From 8889e3763914fdb8e5d7206808ffe68d94eef0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 20:20:53 +0400 Subject: [PATCH 01/18] tests: fix gcc pragma dignostic name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau --- tests/object_size.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/object_size.c b/tests/object_size.c index c0248ab65..f73a81dcb 100644 --- a/tests/object_size.c +++ b/tests/object_size.c @@ -70,7 +70,7 @@ int main(void) }, .seedCompatLevel = 1, }; -#pragma GCC diagnostics pop +#pragma GCC diagnostic pop static const size_t exp_sizes[7] = { 0, 3284, 3284, 3284, 3284, 3284, 3288, }; From da26c94015c645709a33dd0debf7cc1857a1c93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 14:17:02 +0400 Subject: [PATCH 02/18] feat: Add initial Meson build system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces the initial Meson build system for libtpms. This first step allows compiling a minimal shared library and serves as the foundation for the full migration from Autotools. The following files are added: - meson.build: The main build file. - src/meson.build: The build file for the src directory. - config.h.in: The template for the configuration header. - meson_migration_plan.md: The plan for the migration. This corresponds to Step 1 of the migration plan. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- config.h.in | 3 + meson.build | 20 ++ meson_migration_plan.md | 450 ++++++++++++++++++++++++++++++++++++++++ src/meson.build | 26 +++ 4 files changed, 499 insertions(+) create mode 100644 config.h.in create mode 100644 meson.build create mode 100644 meson_migration_plan.md create mode 100644 src/meson.build diff --git a/config.h.in b/config.h.in new file mode 100644 index 000000000..6a27017e8 --- /dev/null +++ b/config.h.in @@ -0,0 +1,3 @@ +/* config.h.in. Generated from meson.build by Meson. */ + +#mesondefine PACKAGE_VERSION diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..bf7e3d20a --- /dev/null +++ b/meson.build @@ -0,0 +1,20 @@ +project('libtpms', 'c', + version: '0.11.0', + license: 'CPL-1.0', + default_options: ['c_std=c99']) + +# Add an include directory that points to the build directory. +# This is necessary so that source files can find the generated config.h +add_project_arguments('-I' + meson.current_build_dir(), language: 'c') + +# Create a configuration header file +conf_data = configuration_data() +conf_data.set('PACKAGE_VERSION', '"' + meson.project_version() + '"') +configure_file( + input: 'config.h.in', + output: 'config.h', + configuration: conf_data +) + +# Add the src subdirectory to the build +subdir('src') diff --git a/meson_migration_plan.md b/meson_migration_plan.md new file mode 100644 index 000000000..87541b9a5 --- /dev/null +++ b/meson_migration_plan.md @@ -0,0 +1,450 @@ +Of course. Here is a detailed, iterative plan to migrate the `libtpms` build system from Autotools to Meson, ensuring feature parity and comparing the two systems at each stage. + +### Migration Philosophy + +The goal is to replace `configure.ac` and all `Makefile.am` files with `meson.build` files. We will start with the simplest possible build and incrementally add features, options, and complexity, mirroring the capabilities of the Autotools setup. + +--- + +### Step 1: Basic Project Setup and a "Dummy" Library + +**Goal:** Create the initial `meson.build` file, define the project, and compile a shared library with a minimal set of source files. This is the "Hello, World" of the build system. + +**Meson Implementation (`/meson.build`):** +```meson +project('libtpms', 'c', + version: '0.11.0', + license: 'BSD-2-Clause', # Check LICENSE file for exact SPDX identifier + default_options: ['c_std=c99']) + +# Add the src subdirectory to the build +subdir('src') +``` + +**Meson Implementation (`/src/meson.build`):** +```meson +# Start with the absolute minimum common files to prove compilation works +libtpms_sources = files( + 'tpm_debug.c', + 'tpm_library.c', + 'tpm_memory.c', + 'tpm_nvfile.c', + 'disabled_interface.c' +) + +# Define the shared library +libtpms = shared_library('tpms', + libtpms_sources, + install: true, +) +``` + +**Autotools Comparison:** +* `project(...)` in Meson replaces `AC_INIT(...)` and `AM_INIT_AUTOMAKE(...)` in `configure.ac`. The version number is set directly. +* `shared_library(...)` replaces the `lib_LTLIBRARIES = libtpms.la` and the associated `libtpms_la_SOURCES` from `src/Makefile.am`. +* At this stage, we are ignoring almost all complexity, just setting up the basic structure. The `subdir('src')` call is analogous to `SUBDIRS = src` in the root `Makefile.am`. + +--- + +### Step 2: Adding Dependencies (OpenSSL) and Headers + +**Goal:** Introduce dependency handling by adding the OpenSSL requirement. We will also define and install the public header files. + +**Meson Implementation (`/src/meson.build`):** +```meson +# Find the OpenSSL dependency (libcrypto) +crypto_dep = dependency('openssl', version: '>=1.1.0') + +# Public headers from include/libtpms +inc_dir = include_directories('../include/libtpms') + +libtpms_sources = files( + # ... same files as Step 1 ... +) + +libtpms = shared_library('tpms', + libtpms_sources, + include_directories: inc_dir, + dependencies: crypto_dep, # Link against the dependency + install: true, +) + +# --- Header Installation --- +# This part goes in a new `include/libtpms/meson.build` +# and is called from the root `meson.build` via `subdir('include/libtpms')` + +# in include/libtpms/meson.build: +install_headers( + 'tpm_error.h', + 'tpm_library.h', + 'tpm_memory.h', + 'tpm_nvfilename.h', + 'tpm_tis.h', + 'tpm_types.h', + subdir: 'libtpms' +) +``` + +**Autotools Comparison:** +* `dependency('openssl')` replaces `AC_CHECK_LIB(crypto, ...)` and the associated header checks in `configure.ac`. Meson handles finding the library, its headers, and providing the necessary flags automatically. It's much more concise. +* `install_headers(...)` replaces the `libtpmsinclude_HEADERS` and `libtpmsincludedir` logic from `include/libtpms/Makefile.am`. + +--- + +### Step 3: Introducing Build Options (TPM1/TPM2 Support) + +**Goal:** Replicate the `--with-tpm1` and `--with-tpm2` configure flags using Meson's feature options. + +**Meson Implementation (`/meson.build`):** +```meson +project('libtpms', 'c', + # ... + ) + +# Define build options, similar to configure flags +option('tpm1', type: 'boolean', value: true, description: 'Build with TPM 1.2 support.') +option('tpm2', type: 'boolean', value: true, description: 'Build with TPM 2.0 support.') + +# ... +subdir('src') +``` + +**Meson Implementation (`/src/meson.build`):** +```meson +# ... (dependencies, etc.) ... + +# Get the value of the options +with_tpm1 = get_option('tpm1') +with_tpm2 = get_option('tpm2') + +# Start building the source list conditionally +libtpms_sources = files(...) # Core files from Step 1 + +if with_tpm1 + # Add TPM1 sources here + message('Building with TPM 1.2 support') +endif + +if with_tpm2 + # Add TPM2 sources here + message('Building with TPM 2.0 support') +endif + +# ... +``` + +**Autotools Comparison:** +* `option('tpm1', ...)` is the direct equivalent of `AC_ARG_WITH([tpm1], ...)`. The `value: true` makes it an enabled-by-default option. +* `get_option('tpm1')` is how the build script retrieves the user's choice, similar to how the shell variable `$with_tpm1` is used in `configure.ac`. +* The `if/endif` blocks directly mirror the `AM_CONDITIONAL([WITH_TPM1], ...)` logic used to control which source files are compiled in `src/Makefile.am`. + +--- + +### Step 4: Populating Conditional Source Files + +**Goal:** Fully replicate the conditional source file logic from `src/Makefile.am` based on the TPM1/TPM2 options. + +**Meson Implementation (`/src/meson.build`):** +```meson +# ... (options, dependencies) ... + +# Create empty arrays for sources +tpm1_sources = [] +tpm2_sources = [] +common_sources = files( + 'disabled_interface.c', + 'tpm_debug.c', + 'tpm_library.c', + 'tpm_memory.c', + 'tpm_nvfile.c' +) + +# TPM 1.2 Sources +if get_option('tpm1') + tpm1_sources += files( + 'tpm12/tpm_admin.c', + 'tpm12/tpm_audit.c', + # ... all other tpm12 sources ... + 'tpm_tpm12_interface.c', + 'tpm_tpm12_tis.c', + 'tpm12/tpm_crypto.c' # Assuming OpenSSL for now + ) +endif + +# TPM 2.0 Sources +if get_option('tpm2') + # Check for librt, needed by TPM2 code + rt_dep = meson.get_compiler('c').find_library('rt', required: false) + + tpm2_sources += files( + 'tpm2/ACT_spt.c', + 'tpm2/ACTCommands.c', + # ... all other tpm2 sources ... + 'tpm_tpm2_interface.c', + 'tpm_tpm2_tis.c' + ) + # Add TPM2 crypto sources for OpenSSL + tpm2_sources += files( + 'tpm2/crypto/openssl/BnToOsslMath.c', + # ... all other tpm2/crypto/openssl sources ... + ) +endif + +# Combine all sources +libtpms = shared_library('tpms', + common_sources + tpm1_sources + tpm2_sources, + dependencies: [crypto_dep, rt_dep], # Add rt_dep here + # ... +) +``` + +**Autotools Comparison:** +* This step directly translates the large `libtpms_tpm12_la_SOURCES` and `libtpms_tpm2_la_SOURCES` blocks from `src/Makefile.am` into Meson lists. +* The `find_library('rt', ...)` call replaces `AC_CHECK_LIB(c, clock_gettime, ..., LIBRT_LIBS="-lrt")`. +* The concatenation of source lists (`common_sources + tpm1_sources + ...`) is Meson's way of achieving what `libtpms_la_LIBADD += libtpms_tpm12.la` does in `Makefile.am`—combining different components into one final target. + +--- + +### Step 5: Compiler Flags and Hardening + +**Goal:** Add warning flags and security hardening flags, checking for compiler support first. + +**Meson Implementation (`/meson.build`):** +```meson +project(...) + +c_compiler = meson.get_compiler('c') + +# Define flags and check for support +c_flags = [ + '-Wall', + '-Werror', + '-Wshadow', + '-Wreturn-type', + '-Wsign-compare', + '-Wno-self-assign', + '-Wmissing-prototypes' +] +supported_c_flags = c_compiler.get_supported_arguments(c_flags) +add_project_arguments(supported_c_flags, language: 'c') + +# Hardening flags +hardening_flags = [] +if get_option('buildtype') != 'plain' + # Stack protector + if c_compiler.has_argument('-fstack-protector-strong') + hardening_flags += '-fstack-protector-strong' + elif c_compiler.has_argument('-fstack-protector') + hardening_flags += '-fstack-protector' + endif + # Fortify source + if c_compiler.has_argument('-D_FORTIFY_SOURCE=2') + hardening_flags += '-D_FORTIFY_SOURCE=2' + endif +endif +add_project_arguments(hardening_flags, language: 'c') + +# Hardening linker flags +ld_flags = [] +if get_option('buildtype') != 'plain' + if c_compiler.has_link_argument('-Wl,-z,relro') + ld_flags += '-Wl,-z,relro' + endif + if c_compiler.has_link_argument('-Wl,-z,now') + ld_flags += '-Wl,-z,now' + endif +endif +add_project_link_arguments(ld_flags, language: 'c') +``` + +**Autotools Comparison:** +* This replaces the manual `AM_CFLAGS` definitions and the complex `AS_IF` blocks that check for hardening support in `configure.ac`. +* `compiler.get_supported_arguments()`, `compiler.has_argument()`, and `compiler.has_link_argument()` are Meson's clean and reliable way to perform the same checks that Autotools does with trial compilations. +* `add_project_arguments` and `add_project_link_arguments` are the global way to add flags, similar to setting `AM_CFLAGS` and `AM_LDFLAGS`. + +--- + +### Step 6: Adding the FreeBL Crypto Backend + +**Goal:** Implement the logic to choose between OpenSSL and FreeBL. + +**Meson Implementation (`/meson.build`):** +```meson +# Add a choice option for the crypto backend +option('crypto_backend', type: 'combo', choices: ['openssl', 'freebl'], value: 'openssl', + description: 'Choose the cryptographic backend.') +``` + +**Meson Implementation (`/src/meson.build`):** +```meson +crypto_backend = get_option('crypto_backend') +crypto_dep = [] +c_args = [] + +if crypto_backend == 'openssl' + crypto_dep = dependency('openssl') + c_args += '-DUSE_OPENSSL_CRYPTO_LIBRARY=1' +else # freebl + # Find nss, nspr, gmp + nss_dep = dependency('nss') + nspr_dep = dependency('nspr') + gmp_dep = dependency('gmp') + # freebl is part of nss, but we might need to find it explicitly + freebl_dep = meson.get_compiler('c').find_library('freebl', required: true) + crypto_dep = [nss_dep, nspr_dep, gmp_dep, freebl_dep] + c_args += '-DUSE_FREEBL_CRYPTO_LIBRARY=1' +endif + +# In the library definition: +libtpms = shared_library('tpms', + ..., + c_args: c_args, + dependencies: crypto_dep, + ... +) +``` + +**Autotools Comparison:** +* The `combo` option type is a much cleaner way to handle mutually exclusive choices than the Autotools `AC_ARG_WITH` logic. +* The `if/else` block for `crypto_backend` replaces the `AS_CASE([$cryptolib], ...)` block in `configure.ac`. +* Dependency management remains much simpler. Instead of manual `AC_CHECK_HEADERS` and `AC_SEARCH_LIBS`, we just declare the dependencies. + +--- + +### Step 7: Adding Finer-Grained Crypto Options + +**Goal:** Implement the `--disable-use-openssl-functions` logic. + +**Meson Implementation (`/meson.build`):** +```meson +option('use_openssl_functions', type: 'boolean', value: true, + description: 'Use OpenSSL functions for crypto instead of internal code.') +``` + +**Meson Implementation (`/src/meson.build`):** +```meson +# ... +if crypto_backend == 'openssl' and get_option('use_openssl_functions') + # Check for specific functions in libcrypto + # Meson doesn't have a direct check_lib for functions, but we can use has_function + # or just assume modern OpenSSL has them. For this plan, we'll add defines. + c_args += [ + '-DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=1', + '-DUSE_OPENSSL_FUNCTIONS_EC=1', + '-DUSE_OPENSSL_FUNCTIONS_ECDSA=1', + '-DUSE_OPENSSL_FUNCTIONS_RSA=1', + '-DUSE_OPENSSL_FUNCTIONS_SSKDF=1' + ] +else + c_args += [ + '-DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=0', + # ... and so on for all flags ... + ] +endif +``` + +**Autotools Comparison:** +* This replaces the `AC_ARG_ENABLE([use-openssl-functions], ...)` and the many `AC_CHECK_LIB` calls for individual functions. While Meson's `has_function` is available, it's often simpler to rely on the dependency version and add the defines, as the check in Autotools is mostly for older OpenSSL versions. + +--- + +### Step 8: Building Tests, Man Pages, and Pkg-Config + +**Goal:** Replicate the `tests` and `man` directory targets, and generate the `libtpms.pc` file. + +**Meson Implementation (`/tests/meson.build`):** +```meson +# Get the libtpms dependency from the main build +libtpms_dep = dependency('tpms', fallback: ['tpms', 'libtpms']) + +# Build an executable +tpm2_selftest = executable('tpm2_selftest', + 'tpm2_selftest.c', + dependencies: libtpms_dep +) + +# Define a test +test('TPM2 Self Test', tpm2_selftest, + args: ['--device', '/dev/null']) +``` + +**Meson Implementation (`/man/man3/meson.build`):** +```meson +pod2man = find_program('pod2man', required: true) + +# Use a custom target to generate man pages +custom_target('man_TPM_IO_Hash_Start', + input: 'TPM_IO_Hash_Start.pod', + output: 'TPM_IO_Hash_Start.3', + command: [pod2man, '-r', 'libtpms', '-c', '""', '-n', '@BASENAME@', '--section=3', '@INPUT@'], + capture: true, + install: true, + install_dir: get_option('mandir') / 'man3' +) +# Repeat for all .pod files +``` + +**Meson Implementation (`/meson.build`):** +```meson +# ... +# Pkg-config generation +pkg = import('pkgconfig') +pkg.generate( + name: 'libtpms', + description: 'A library for TPM emulation.', + version: meson.project_version(), + libraries: libtpms +) +``` + +**Autotools Comparison:** +* `executable()` and `test()` in `tests/meson.build` replace `check_PROGRAMS` and `TESTS` from `tests/Makefile.am`. The dependency is handled cleanly. +* `custom_target()` is Meson's powerful way to replace rule-based recipes, like the `%.3 : %.pod` rule in `man/man3/Makefile.am`. +* The `pkgconfig` module is a massive simplification over maintaining a `libtpms.pc.in` file and using `AC_SUBST` in `configure.ac`. + +--- + +### Step 9: Special Build Modes (Coverage, Sanitizers) + +**Goal:** Implement the remaining special build modes. + +**Meson Implementation:** +This is where Meson shines. There is no need for custom logic in the build files. The user controls this with built-in options: +* **Test Coverage:** `./meson configure -Db_coverage=true` +* **Sanitizers:** `./meson configure -Db_sanitize=address,undefined` +* **Fuzzing:** `./meson configure -Db_fuzzing=true` (requires a recent Meson version) + +**Autotools Comparison:** +* This replaces `AC_ARG_ENABLE([test-coverage], ...)` and `AC_ARG_ENABLE([sanitizers], ...)`. Meson's implementation is standardized, requires zero code in the build scripts, and is less error-prone than managing `COVERAGE_CFLAGS` manually. + +--- + +### Step 10: Final Touches (Versioning, Installation) + +**Goal:** Ensure library versioning and symbol exports are correct. + +**Meson Implementation (`/src/meson.build`):** +```meson +# ... +libtpms_version = meson.project_version() +# LIBTPMS_VERSION_INFO=`expr $LIBTPMS_VER_MAJOR + $LIBTPMS_VER_MINOR`:$LIBTPMS_VER_MICRO:$LIBTPMS_VER_MINOR +# This logic needs to be translated to Meson. +# For 0.11.0, this is 11:0:11 +soversion = '11' # Based on the autotools logic for this specific version + +libtpms = shared_library('tpms', + ..., + version: libtpms_version, + soversion: soversion, + darwin_versions: [soversion, libtpms_version], # For macOS compatibility + vs_module_defs: 'libtpms.syms', # For Windows + link_args: ['-Wl,--version-script,@0@'.format(files('libtpms.syms')[0].full_path())], # For Linux/ELF + install: true +) +``` + +**Autotools Comparison:** +* The `version` and `soversion` parameters in `shared_library` replace the `-version-info $(LIBTPMS_VERSION_INFO)` logic. +* The `link_args` with a version script replaces the `HAVE_VERSION_SCRIPT` conditional logic and the associated `-Wl,--version-script` flag in `src/Makefile.am`. Meson makes accessing the file path for this much easier. + +This iterative plan provides a clear path from a basic build to a full-featured replacement of the Autotools system, highlighting the advantages and simplifications Meson offers at each step. diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 000000000..fe685b705 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,26 @@ +# Define an include directory that points to the library's public headers +project_inc = include_directories('../include/libtpms') + +# Define an include directory for the generated config.h in the build directory +# This is where config.h will be generated. +build_inc = include_directories('.') + +# Start with the absolute minimum common files to prove compilation works +libtpms_sources = files( + 'tpm_debug.c', + 'tpm_library.c', + 'tpm_memory.c', + 'tpm_nvfile.c', + 'disabled_interface.c' +) + +# Define the shared library +libtpms = shared_library('tpms', + libtpms_sources, + c_args: [ + '-DTPM_NV_DISK', + '-include', 'tpm_library_conf.h' + ], + include_directories: [project_inc, build_inc], + install: true, +) \ No newline at end of file From 37b412fd43024c3429697ef159c9d63409f87f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 20:45:28 +0400 Subject: [PATCH 03/18] meson: fix license MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gemini didn't get the license correctly. Signed-off-by: Marc-André Lureau --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index bf7e3d20a..decd02c7f 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('libtpms', 'c', version: '0.11.0', - license: 'CPL-1.0', + license: 'BSD-3-Clause AND LicenseRef-TCGL', default_options: ['c_std=c99']) # Add an include directory that points to the build directory. From 9ef45de8b07fcc4a05be49fc614d2d66ce750018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 14:18:19 +0400 Subject: [PATCH 04/18] feat: Add OpenSSL dependency and header installation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements Step 2 of the Meson migration plan. - The build system now finds and links against the OpenSSL library. - Public header files are now installed to the correct location. - The 'include' directory has been added to the Meson build process. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- include/libtpms/meson.build | 9 +++++++++ include/meson.build | 1 + meson.build | 5 +++-- src/meson.build | 14 +++++++------- 4 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 include/libtpms/meson.build create mode 100644 include/meson.build diff --git a/include/libtpms/meson.build b/include/libtpms/meson.build new file mode 100644 index 000000000..b983d97ad --- /dev/null +++ b/include/libtpms/meson.build @@ -0,0 +1,9 @@ +install_headers( + 'tpm_error.h', + 'tpm_library.h', + 'tpm_memory.h', + 'tpm_nvfilename.h', + 'tpm_tis.h', + 'tpm_types.h', + subdir: 'libtpms' +) diff --git a/include/meson.build b/include/meson.build new file mode 100644 index 000000000..3cdac6389 --- /dev/null +++ b/include/meson.build @@ -0,0 +1 @@ +subdir('libtpms') diff --git a/meson.build b/meson.build index decd02c7f..78e162fae 100644 --- a/meson.build +++ b/meson.build @@ -16,5 +16,6 @@ configure_file( configuration: conf_data ) -# Add the src subdirectory to the build -subdir('src') +# Add subdirectories to the build +subdir('include') +subdir('src') \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index fe685b705..fa3e37cdc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,9 +1,8 @@ -# Define an include directory that points to the library's public headers -project_inc = include_directories('../include/libtpms') +# Find the OpenSSL dependency (libcrypto) +crypto_dep = dependency('openssl', version: '>=1.1.0', required: true) -# Define an include directory for the generated config.h in the build directory -# This is where config.h will be generated. -build_inc = include_directories('.') +# Include directory for the library's own public headers +lib_inc = include_directories('../include/libtpms') # Start with the absolute minimum common files to prove compilation works libtpms_sources = files( @@ -21,6 +20,7 @@ libtpms = shared_library('tpms', '-DTPM_NV_DISK', '-include', 'tpm_library_conf.h' ], - include_directories: [project_inc, build_inc], + dependencies: crypto_dep, + include_directories: [lib_inc], install: true, -) \ No newline at end of file +) From de29c4b8d28c036b8c402cb85c016ea0f6bb7d8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 14:19:58 +0400 Subject: [PATCH 05/18] feat: Add build options for TPM1 and TPM2 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements Step 3 of the Meson migration plan. - Added meson_options.txt to define build options. - Introduced 'tpm1' and 'tpm2' boolean options to control which parts of the library are built. - The build logic in src/meson.build now checks these options. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- meson_options.txt | 2 ++ src/meson.build | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 meson_options.txt diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 000000000..871c59fa8 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,2 @@ +option('tpm1', type: 'boolean', value: true, description: 'Build with TPM 1.2 support.') +option('tpm2', type: 'boolean', value: true, description: 'Build with TPM 2.0 support.') diff --git a/src/meson.build b/src/meson.build index fa3e37cdc..6dc573605 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,7 +4,11 @@ crypto_dep = dependency('openssl', version: '>=1.1.0', required: true) # Include directory for the library's own public headers lib_inc = include_directories('../include/libtpms') -# Start with the absolute minimum common files to prove compilation works +# Get the value of the options +with_tpm1 = get_option('tpm1') +with_tpm2 = get_option('tpm2') + +# Start with the common source files libtpms_sources = files( 'tpm_debug.c', 'tpm_library.c', @@ -13,6 +17,16 @@ libtpms_sources = files( 'disabled_interface.c' ) +if with_tpm1 + # Add TPM1 sources here in the next step + message('Building with TPM 1.2 support') +endif + +if with_tpm2 + # Add TPM2 sources here in the next step + message('Building with TPM 2.0 support') +endif + # Define the shared library libtpms = shared_library('tpms', libtpms_sources, @@ -23,4 +37,4 @@ libtpms = shared_library('tpms', dependencies: crypto_dep, include_directories: [lib_inc], install: true, -) +) \ No newline at end of file From d851618afe197d3aa0a64d332b46df80602b54df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 14:24:07 +0400 Subject: [PATCH 06/18] feat: Add full source lists for TPM1 and TPM2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements Step 4 of the Meson migration plan. - Populates the build with the full list of source files for both TPM 1.2 and TPM 2.0 implementations. - Refactors the build to use intermediate static libraries for TPM1 and TPM2, allowing for implementation-specific compiler flags. - Adds necessary preprocessor definitions to successfully compile the full library. - Adds header checks for arpa/inet.h and time.h. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- config.h.in | 2 + meson.build | 11 ++++- src/meson.build | 128 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 129 insertions(+), 12 deletions(-) diff --git a/config.h.in b/config.h.in index 6a27017e8..238722270 100644 --- a/config.h.in +++ b/config.h.in @@ -1,3 +1,5 @@ /* config.h.in. Generated from meson.build by Meson. */ #mesondefine PACKAGE_VERSION +#mesondefine HAVE_ARPA_INET_H +#mesondefine HAVE_TIME_H diff --git a/meson.build b/meson.build index 78e162fae..a0d791985 100644 --- a/meson.build +++ b/meson.build @@ -4,12 +4,21 @@ project('libtpms', 'c', default_options: ['c_std=c99']) # Add an include directory that points to the build directory. -# This is necessary so that source files can find the generated config.h add_project_arguments('-I' + meson.current_build_dir(), language: 'c') # Create a configuration header file conf_data = configuration_data() conf_data.set('PACKAGE_VERSION', '"' + meson.project_version() + '"') + +# Check for headers +c_compiler = meson.get_compiler('c') +if c_compiler.has_header('arpa/inet.h') + conf_data.set('HAVE_ARPA_INET_H', 1) +endif +if c_compiler.has_header('time.h') + conf_data.set('HAVE_TIME_H', 1) +endif + configure_file( input: 'config.h.in', output: 'config.h', diff --git a/src/meson.build b/src/meson.build index 6dc573605..8506ac83d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -9,7 +9,7 @@ with_tpm1 = get_option('tpm1') with_tpm2 = get_option('tpm2') # Start with the common source files -libtpms_sources = files( +common_sources = files( 'tpm_debug.c', 'tpm_library.c', 'tpm_memory.c', @@ -17,24 +17,130 @@ libtpms_sources = files( 'disabled_interface.c' ) +link_with_libs = [] +extra_deps = [] + +# Common c_args for all libraries +common_c_args = [ + '-DTPM_NV_DISK', + '-DTPM_LIBTPMS_CALLBACKS', + '-include', 'tpm_library_conf.h' +] + if with_tpm1 - # Add TPM1 sources here in the next step message('Building with TPM 1.2 support') + tpm1_sources = files( + 'tpm12/tpm_admin.c', 'tpm12/tpm_audit.c', 'tpm12/tpm_auth.c', + 'tpm12/tpm_cryptoh.c', 'tpm12/tpm_counter.c', 'tpm12/tpm_daa.c', + 'tpm12/tpm_delegate.c', 'tpm12/tpm_digest.c', 'tpm12/tpm_error.c', + 'tpm12/tpm_global.c', 'tpm12/tpm_identity.c', 'tpm12/tpm_init.c', + 'tpm12/tpm_libtpms_io.c', 'tpm12/tpm_key.c', 'tpm12/tpm_load.c', + 'tpm12/tpm_maint.c', 'tpm12/tpm_migration.c', 'tpm12/tpm_nonce.c', + 'tpm12/tpm_nvram.c', 'tpm12/tpm_openssl_helpers.c', 'tpm12/tpm_owner.c', + 'tpm12/tpm_pcr.c', 'tpm12/tpm_permanent.c', 'tpm12/tpm_platform.c', + 'tpm12/tpm_process.c', 'tpm12/tpm_secret.c', 'tpm12/tpm_session.c', + 'tpm12/tpm_sizedbuffer.c', 'tpm12/tpm_startup.c', 'tpm12/tpm_store.c', + 'tpm12/tpm_storage.c', 'tpm12/tpm_ticks.c', 'tpm12/tpm_time.c', + 'tpm12/tpm_transport.c', 'tpm12/tpm_ver.c', 'tpm12/tpm_svnrevision.c', + 'tpm_tpm12_interface.c', 'tpm_tpm12_tis.c', 'tpm12/tpm_crypto.c' + ) + + tpm1_lib = static_library('tpms_tpm12', tpm1_sources, + c_args: common_c_args + [ + '-DTPM_V12', + '-DTPM_PCCLIENT', + '-DTPM_POSIX', + '-DTPM_AES', + '-DTPM_NOMAINTENANCE_COMMANDS', + '-DTPM_ENABLE_ACTIVATE', + '-DTPM_VOLATILE_LOAD', + ], + include_directories: [lib_inc], + ) + link_with_libs += tpm1_lib endif if with_tpm2 - # Add TPM2 sources here in the next step message('Building with TPM 2.0 support') + rt_dep = meson.get_compiler('c').find_library('rt', required: false) + extra_deps += rt_dep + + tpm2_sources = files( + 'tpm2/ACT_spt.c', 'tpm2/ACTCommands.c', 'tpm2/AlgorithmCap.c', + 'tpm2/AlgorithmTests.c', 'tpm2/AsymmetricCommands.c', + 'tpm2/AttestationCommands.c', 'tpm2/Attest_spt.c', 'tpm2/AuditCommands.c', + 'tpm2/Bits.c', 'tpm2/BnEccConstants.c', 'tpm2/BnConvert.c', 'tpm2/BnMath.c', + 'tpm2/BnMemory.c', 'tpm2/Cancel.c', 'tpm2/CapabilityCommands.c', + 'tpm2/Clock.c', 'tpm2/ClockCommands.c', 'tpm2/CommandAudit.c', + 'tpm2/CommandCodeAttributes.c', 'tpm2/CommandDispatcher.c', + 'tpm2/ContextCommands.c', 'tpm2/Context_spt.c', 'tpm2/CryptEccData.c', + 'tpm2/CryptSelfTest.c', 'tpm2/CryptUtil.c', 'tpm2/DA.c', + 'tpm2/DebugHelpers.c', 'tpm2/DictionaryCommands.c', + 'tpm2/DuplicationCommands.c', 'tpm2/EACommands.c', + 'tpm2/EncryptDecrypt_spt.c', 'tpm2/Entity.c', 'tpm2/Entropy.c', + 'tpm2/EphemeralCommands.c', 'tpm2/ExecCommand.c', 'tpm2/ExtraData.c', + 'tpm2/Global.c', 'tpm2/Handle.c', 'tpm2/HashCommands.c', + 'tpm2/Hierarchy.c', 'tpm2/HierarchyCommands.c', 'tpm2/IntegrityCommands.c', + 'tpm2/IoBuffers.c', 'tpm2/Locality.c', 'tpm2/LocalityPlat.c', + 'tpm2/ManagementCommands.c', 'tpm2/Manufacture.c', 'tpm2/Marshal.c', + 'tpm2/MathOnByteBuffers.c', 'tpm2/Memory.c', 'tpm2/NVCommands.c', + 'tpm2/NvDynamic.c', 'tpm2/NVMem.c', 'tpm2/NvReserved.c', 'tpm2/NV_spt.c', + 'tpm2/Object.c', 'tpm2/ObjectCommands.c', 'tpm2/Object_spt.c', 'tpm2/PCR.c', + 'tpm2/PlatformACT.c', 'tpm2/PlatformData.c', 'tpm2/PlatformPCR.c', + 'tpm2/Policy_spt.c', 'tpm2/Power.c', 'tpm2/PowerPlat.c', 'tpm2/PP.c', + 'tpm2/PPPlat.c', 'tpm2/PrimeData.c', 'tpm2/PropertyCap.c', + 'tpm2/RandomCommands.c', 'tpm2/Response.c', + 'tpm2/ResponseCodeProcessing.c', 'tpm2/RunCommand.c', 'tpm2/Session.c', + 'tpm2/SessionCommands.c', 'tpm2/SessionProcess.c', + 'tpm2/SigningCommands.c', 'tpm2/StartupCommands.c', + 'tpm2/SymmetricCommands.c', 'tpm2/TestingCommands.c', 'tpm2/Ticket.c', + 'tpm2/Time.c', 'tpm2/TpmASN1.c', 'tpm2/TpmBigNumThunks.c', + 'tpm2/TpmEcc_Signature_ECDAA.c', 'tpm2/TpmEcc_Signature_ECDSA.c', + 'tpm2/TpmEcc_Signature_Schnorr.c', 'tpm2/TpmEcc_Signature_SM2.c', + 'tpm2/TpmEcc_Signature_Util.c', 'tpm2/TpmEcc_Util.c', + 'tpm2/TpmMath_Debug.c', 'tpm2/TpmMath_Util.c', 'tpm2/TpmSizeChecks.c', + 'tpm2/TPMCmdp.c', 'tpm2/TpmFail.c', 'tpm2/Unique.c', 'tpm2/Unmarshal.c', + 'tpm2/VendorInfo.c', 'tpm2/Vendor_TCG_Test.c', 'tpm2/X509_ECC.c', + 'tpm2/X509_RSA.c', 'tpm2/X509_spt.c', 'tpm_tpm2_interface.c', + 'tpm_tpm2_tis.c', 'tpm2/BackwardsCompatibilityBitArray.c', + 'tpm2/BackwardsCompatibilityObject.c', 'tpm2/LibtpmsCallbacks.c', + 'tpm2/NVMarshal.c', 'tpm2/RuntimeAlgorithm.c', 'tpm2/RuntimeAttributes.c', + 'tpm2/RuntimeCommands.c', 'tpm2/RuntimeProfile.c', 'tpm2/StateMarshal.c', + 'tpm2/Volatile.c', + 'tpm2/crypto/openssl/BnToOsslMath.c', 'tpm2/crypto/openssl/CryptCmac.c', + 'tpm2/crypto/openssl/CryptDes.c', 'tpm2/crypto/openssl/CryptEccCrypt.c', + 'tpm2/crypto/openssl/CryptEccKeyExchange.c', 'tpm2/crypto/openssl/CryptEccMain.c', + 'tpm2/crypto/openssl/CryptEccSignature.c', 'tpm2/crypto/openssl/CryptHash.c', + 'tpm2/crypto/openssl/CryptPrime.c', 'tpm2/crypto/openssl/CryptPrimeSieve.c', + 'tpm2/crypto/openssl/CryptRand.c', 'tpm2/crypto/openssl/CryptRsa.c', + 'tpm2/crypto/openssl/CryptSmac.c', 'tpm2/crypto/openssl/CryptSym.c', + 'tpm2/crypto/openssl/ExpDCache.c', 'tpm2/crypto/openssl/Helpers.c', + 'tpm2/crypto/openssl/TpmToOsslDesSupport.c', 'tpm2/crypto/openssl/TpmToOsslSupport.c' + ) + + tpm2_lib = static_library('tpms_tpm2', tpm2_sources, + c_args: common_c_args + [ + '-D_POSIX_C_SOURCE=200809L', + '-DTPM_POSIX', + '-include', 'config.h' + ], + include_directories: [ + lib_inc, + '.', + 'tpm2', + 'tpm2/crypto', + 'tpm2/crypto/openssl' + ], + ) + link_with_libs += tpm2_lib endif -# Define the shared library +# Define the final shared library libtpms = shared_library('tpms', - libtpms_sources, - c_args: [ - '-DTPM_NV_DISK', - '-include', 'tpm_library_conf.h' - ], - dependencies: crypto_dep, + common_sources, + c_args: common_c_args + ['-include', 'config.h'], + link_with: link_with_libs, + dependencies: [crypto_dep] + extra_deps, include_directories: [lib_inc], install: true, -) \ No newline at end of file +) From 60bd0377d0e606da900f69cb24123fb595108c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 14:31:13 +0400 Subject: [PATCH 07/18] feat: Add compiler warning and hardening flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements Step 5 of the Meson migration plan. - Adds a comprehensive set of compiler warning flags, such as -Wall and -Werror, checking for compiler support first. - Adds security hardening flags (-fstack-protector-strong, -D_FORTIFY_SOURCE=2, -Wl,-z,relro, -Wl,-z,now), also checking for compiler and linker support. - Conditionally applies _FORTIFY_SOURCE only when optimizations are enabled to prevent build failures in debug mode. - Adds -DOPENSSL_SUPPRESS_DEPRECATED to handle deprecation warnings in OpenSSL and allow the build to succeed with -Werror. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- meson.build | 44 +++++++++++++++++++++++++++++++++++++++++++- src/meson.build | 3 ++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index a0d791985..dfaa24785 100644 --- a/meson.build +++ b/meson.build @@ -3,15 +3,57 @@ project('libtpms', 'c', license: 'BSD-3-Clause AND LicenseRef-TCGL', default_options: ['c_std=c99']) +c_compiler = meson.get_compiler('c') + # Add an include directory that points to the build directory. add_project_arguments('-I' + meson.current_build_dir(), language: 'c') +# Add common warning flags +warning_flags = [ + '-Wall', + '-Werror', + '-Wshadow', + '-Wreturn-type', + '-Wsign-compare', + '-Wno-self-assign', + '-Wmissing-prototypes' +] +supported_warning_flags = c_compiler.get_supported_arguments(warning_flags) +add_project_arguments(supported_warning_flags, language: 'c') + +# Add hardening flags for non-plain build types +if get_option('buildtype') != 'plain' + hardening_c_flags = [] + # Stack protector + if c_compiler.has_argument('-fstack-protector-strong') + hardening_c_flags += '-fstack-protector-strong' + elif c_compiler.has_argument('-fstack-protector') + hardening_c_flags += '-fstack-protector' + endif + # Fortify source only works with optimization + if get_option('optimization') != '0' + if c_compiler.has_argument('-D_FORTIFY_SOURCE=2') + hardening_c_flags += '-D_FORTIFY_SOURCE=2' + endif + endif + add_project_arguments(hardening_c_flags, language: 'c') + + hardening_ld_flags = [] + # Linker hardening + if c_compiler.has_link_argument('-Wl,-z,relro') + hardening_ld_flags += '-Wl,-z,relro' + endif + if c_compiler.has_link_argument('-Wl,-z,now') + hardening_ld_flags += '-Wl,-z,now' + endif + add_project_link_arguments(hardening_ld_flags, language: 'c') +endif + # Create a configuration header file conf_data = configuration_data() conf_data.set('PACKAGE_VERSION', '"' + meson.project_version() + '"') # Check for headers -c_compiler = meson.get_compiler('c') if c_compiler.has_header('arpa/inet.h') conf_data.set('HAVE_ARPA_INET_H', 1) endif diff --git a/src/meson.build b/src/meson.build index 8506ac83d..e402155b3 100644 --- a/src/meson.build +++ b/src/meson.build @@ -24,6 +24,7 @@ extra_deps = [] common_c_args = [ '-DTPM_NV_DISK', '-DTPM_LIBTPMS_CALLBACKS', + '-DOPENSSL_SUPPRESS_DEPRECATED', '-include', 'tpm_library_conf.h' ] @@ -143,4 +144,4 @@ libtpms = shared_library('tpms', dependencies: [crypto_dep] + extra_deps, include_directories: [lib_inc], install: true, -) +) \ No newline at end of file From 74b91bec7e708d5beb88f4a1a175c6af66580bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 14:37:21 +0400 Subject: [PATCH 08/18] feat: Add support for FreeBL crypto backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements Step 6 of the Meson migration plan. - Adds a 'crypto_backend' option to 'meson_options.txt' to allow selecting between 'openssl' and 'freebl'. - The build logic in 'src/meson.build' now conditionally selects the appropriate crypto source files and dependencies. - Adds a forward declaration to 'tpm_crypto_freebl.c' to fix a compilation error when building with '-Werror'. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- meson_options.txt | 1 + src/meson.build | 50 +++++++++++++++++++++++++++-------- src/tpm12/tpm_crypto_freebl.c | 8 ++++++ 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index 871c59fa8..1db358a9e 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,2 +1,3 @@ option('tpm1', type: 'boolean', value: true, description: 'Build with TPM 1.2 support.') option('tpm2', type: 'boolean', value: true, description: 'Build with TPM 2.0 support.') +option('crypto_backend', type: 'combo', choices: ['openssl', 'freebl'], value: 'openssl', description: 'Choose the cryptographic backend.') \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index e402155b3..bc9540580 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,14 +1,41 @@ -# Find the OpenSSL dependency (libcrypto) -crypto_dep = dependency('openssl', version: '>=1.1.0', required: true) +# Get build options +with_tpm1 = get_option('tpm1') +with_tpm2 = get_option('tpm2') +crypto_backend = get_option('crypto_backend') + +# TPM2 requires OpenSSL in this build configuration +if with_tpm2 and crypto_backend != 'openssl' + error('TPM2 support currently requires the openssl crypto backend.') +endif + +# --- Crypto Dependencies and Flags --- +crypto_deps = [] +tpm1_crypto_sources = [] +freebl_inc = [] +if crypto_backend == 'openssl' + crypto_deps += dependency('openssl', version: '>=1.1.0', required: true) + if with_tpm1 + tpm1_crypto_sources += 'tpm12/tpm_crypto.c' + endif +else # freebl + nss_dep = dependency('nss') + nspr_dep = dependency('nspr') + gmp_dep = dependency('gmp') + crypto_deps += [nss_dep, nspr_dep, gmp_dep] + crypto_deps += meson.get_compiler('c').find_library('freebl', required: true) + freebl_inc += include_directories(nss_dep.get_variable(pkgconfig: 'includedir')) + freebl_inc += include_directories(nspr_dep.get_variable(pkgconfig: 'includedir')) + if with_tpm1 + tpm1_crypto_sources += 'tpm12/tpm_crypto_freebl.c' + endif +endif + +# --- Library Definitions --- # Include directory for the library's own public headers lib_inc = include_directories('../include/libtpms') -# Get the value of the options -with_tpm1 = get_option('tpm1') -with_tpm2 = get_option('tpm2') - -# Start with the common source files +# Common source files common_sources = files( 'tpm_debug.c', 'tpm_library.c', @@ -43,7 +70,8 @@ if with_tpm1 'tpm12/tpm_sizedbuffer.c', 'tpm12/tpm_startup.c', 'tpm12/tpm_store.c', 'tpm12/tpm_storage.c', 'tpm12/tpm_ticks.c', 'tpm12/tpm_time.c', 'tpm12/tpm_transport.c', 'tpm12/tpm_ver.c', 'tpm12/tpm_svnrevision.c', - 'tpm_tpm12_interface.c', 'tpm_tpm12_tis.c', 'tpm12/tpm_crypto.c' + 'tpm_tpm12_interface.c', 'tpm_tpm12_tis.c', + tpm1_crypto_sources ) tpm1_lib = static_library('tpms_tpm12', tpm1_sources, @@ -56,7 +84,7 @@ if with_tpm1 '-DTPM_ENABLE_ACTIVATE', '-DTPM_VOLATILE_LOAD', ], - include_directories: [lib_inc], + include_directories: [lib_inc] + freebl_inc, ) link_with_libs += tpm1_lib endif @@ -141,7 +169,7 @@ libtpms = shared_library('tpms', common_sources, c_args: common_c_args + ['-include', 'config.h'], link_with: link_with_libs, - dependencies: [crypto_dep] + extra_deps, + dependencies: crypto_deps + extra_deps, include_directories: [lib_inc], install: true, -) \ No newline at end of file +) diff --git a/src/tpm12/tpm_crypto_freebl.c b/src/tpm12/tpm_crypto_freebl.c index 272c26472..36afae52f 100644 --- a/src/tpm12/tpm_crypto_freebl.c +++ b/src/tpm12/tpm_crypto_freebl.c @@ -82,6 +82,14 @@ static unsigned char sha1Oid[] = { local prototypes */ +static TPM_RESULT TPM_RSAPublicEncryptRaw(unsigned char *encrypt_data, /* output */ + uint32_t encrypt_data_size, /* input, size of enc buffer */ + unsigned char *decrypt_data, /* input */ + uint32_t decrypt_data_size, /* input, size of dec buffer */ + unsigned char *narr, /* public modulus */ + uint32_t nbytes, + unsigned char *earr, /* public exponent */ + uint32_t ebytes); static void TPM_RSAPrivateKeyInit(RSAPrivateKey *rsa_pri_key); static TPM_RESULT TPM_RSAGeneratePublicToken(RSAPublicKey *rsa_pub_key, unsigned char *narr, From 4bfb164c8aea1bdd564a9f0dfc2aea98f4aed584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 14:51:25 +0400 Subject: [PATCH 09/18] feat: Add option to enable/disable use of OpenSSL functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements step 7 of the Meson migration plan. It introduces a new boolean option, 'use_openssl_functions', to control whether to use OpenSSL's own crypto functions or the library's internal ones. This mirrors the behavior of the '--disable-use-openssl-functions' flag in the Autotools build system. The option is added to 'meson_options.txt' and the corresponding C defines are conditionally applied in 'src/meson.build' for both TPM 1.2 and TPM 2.0 builds when using the OpenSSL backend. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- meson_options.txt | 3 ++- src/meson.build | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index 1db358a9e..9ba573bdd 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,4 @@ option('tpm1', type: 'boolean', value: true, description: 'Build with TPM 1.2 support.') option('tpm2', type: 'boolean', value: true, description: 'Build with TPM 2.0 support.') -option('crypto_backend', type: 'combo', choices: ['openssl', 'freebl'], value: 'openssl', description: 'Choose the cryptographic backend.') \ No newline at end of file +option('crypto_backend', type: 'combo', choices: ['openssl', 'freebl'], value: 'openssl', description: 'Choose the cryptographic backend.') +option('use_openssl_functions', type: 'boolean', value: true, description: 'Use OpenSSL functions for crypto instead of internal code.') diff --git a/src/meson.build b/src/meson.build index bc9540580..4ebfe020c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -12,11 +12,29 @@ endif crypto_deps = [] tpm1_crypto_sources = [] freebl_inc = [] +openssl_flags = [] if crypto_backend == 'openssl' crypto_deps += dependency('openssl', version: '>=1.1.0', required: true) if with_tpm1 tpm1_crypto_sources += 'tpm12/tpm_crypto.c' endif + if get_option('use_openssl_functions') + openssl_flags += [ + '-DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=1', + '-DUSE_OPENSSL_FUNCTIONS_EC=1', + '-DUSE_OPENSSL_FUNCTIONS_ECDSA=1', + '-DUSE_OPENSSL_FUNCTIONS_RSA=1', + '-DUSE_OPENSSL_FUNCTIONS_SSKDF=1' + ] + else + openssl_flags += [ + '-DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=0', + '-DUSE_OPENSSL_FUNCTIONS_EC=0', + '-DUSE_OPENSSL_FUNCTIONS_ECDSA=0', + '-DUSE_OPENSSL_FUNCTIONS_RSA=0', + '-DUSE_OPENSSL_FUNCTIONS_SSKDF=0' + ] + endif else # freebl nss_dep = dependency('nss') nspr_dep = dependency('nspr') @@ -75,7 +93,7 @@ if with_tpm1 ) tpm1_lib = static_library('tpms_tpm12', tpm1_sources, - c_args: common_c_args + [ + c_args: common_c_args + openssl_flags + [ '-DTPM_V12', '-DTPM_PCCLIENT', '-DTPM_POSIX', @@ -148,7 +166,7 @@ if with_tpm2 ) tpm2_lib = static_library('tpms_tpm2', tpm2_sources, - c_args: common_c_args + [ + c_args: common_c_args + openssl_flags + [ '-D_POSIX_C_SOURCE=200809L', '-DTPM_POSIX', '-include', 'config.h' From 6162498a0e933bb0cebac7feff766d6b09b84d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 15:00:15 +0400 Subject: [PATCH 10/18] feat: Add man page generation to Meson build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit implements the man page portion of step 8 of the Meson migration plan. It adds the necessary 'meson.build' files to the 'man' and 'man/man3' directories to find 'pod2man' and generate the man pages from the '.pod' source files. The generated man pages are also installed. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- man/man3/meson.build | 37 +++++++++++++++++++++++++++++++++++++ man/meson.build | 1 + meson.build | 4 +++- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 man/man3/meson.build create mode 100644 man/meson.build diff --git a/man/man3/meson.build b/man/man3/meson.build new file mode 100644 index 000000000..8f221028d --- /dev/null +++ b/man/man3/meson.build @@ -0,0 +1,37 @@ +pod_files = [ + 'TPM_IO_Hash_Start.pod', + 'TPM_IO_TpmEstablished_Get.pod', + 'TPM_Malloc.pod', + 'TPMLIB_CancelCommand.pod', + 'TPMLIB_ChooseTPMVersion.pod', + 'TPMLIB_DecodeBlob.pod', + 'TPMLIB_GetInfo.pod', + 'TPMLIB_GetTPMProperty.pod', + 'TPMLIB_GetVersion.pod', + 'TPMLIB_MainInit.pod', + 'TPMLIB_Process.pod', + 'TPMLIB_RegisterCallbacks.pod', + 'TPMLIB_SetBufferSize.pod', + 'TPMLIB_SetDebugFD.pod', + 'TPMLIB_SetProfile.pod', + 'TPMLIB_SetState.pod', + 'TPMLIB_ValidateState.pod', + 'TPMLIB_VolatileAll_Store.pod', + 'TPMLIB_WasManufactured.pod', +] + +pod2man = find_program('pod2man', required: true) + +foreach pod : pod_files + base_name = pod.split('.')[0] + target_name = base_name + '.3' + + custom_target(target_name, + input: pod, + output: target_name, + command: [pod2man, '-r', 'libtpms', '-c', '""', '-n', base_name, '--section=3', '@INPUT@', '@OUTPUT@'], + capture: false, + install: true, + install_dir: get_option('mandir') / 'man3' + ) +endforeach diff --git a/man/meson.build b/man/meson.build new file mode 100644 index 000000000..dc4cd0418 --- /dev/null +++ b/man/meson.build @@ -0,0 +1 @@ +subdir('man3') diff --git a/meson.build b/meson.build index dfaa24785..4f4fda3a0 100644 --- a/meson.build +++ b/meson.build @@ -67,6 +67,8 @@ configure_file( configuration: conf_data ) +# Add subdirectories to the build # Add subdirectories to the build subdir('include') -subdir('src') \ No newline at end of file +subdir('src') +subdir('man') From 869b7c981cf1b99089078a9556afc082f042f77e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 20:29:37 +0400 Subject: [PATCH 11/18] meson: fix build with tpm1/tpm2 flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau --- meson.build | 14 ++++++++++++++ src/meson.build | 9 ++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index 4f4fda3a0..4c05a4ee8 100644 --- a/meson.build +++ b/meson.build @@ -21,6 +21,11 @@ warning_flags = [ supported_warning_flags = c_compiler.get_supported_arguments(warning_flags) add_project_arguments(supported_warning_flags, language: 'c') +# Get build options +with_tpm1 = get_option('tpm1') +with_tpm2 = get_option('tpm2') +crypto_backend = get_option('crypto_backend') + # Add hardening flags for non-plain build types if get_option('buildtype') != 'plain' hardening_c_flags = [] @@ -72,3 +77,12 @@ configure_file( subdir('include') subdir('src') subdir('man') + +summary_info = {} +summary_info += {'Build directory': meson.current_build_dir()} +summary_info += {'Source path': meson.current_source_dir()} +summary_info += {'TPM1': with_tpm1} +summary_info += {'TPM2': with_tpm2} +summary_info += {'Crypto backend': crypto_backend} + +summary(summary_info, bool_yn: true, section: 'Build environment') diff --git a/src/meson.build b/src/meson.build index 4ebfe020c..5c1d3414e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,8 +1,3 @@ -# Get build options -with_tpm1 = get_option('tpm1') -with_tpm2 = get_option('tpm2') -crypto_backend = get_option('crypto_backend') - # TPM2 requires OpenSSL in this build configuration if with_tpm2 and crypto_backend != 'openssl' error('TPM2 support currently requires the openssl crypto backend.') @@ -74,7 +69,7 @@ common_c_args = [ ] if with_tpm1 - message('Building with TPM 1.2 support') + common_c_args += ['-DWITH_TPM1'] tpm1_sources = files( 'tpm12/tpm_admin.c', 'tpm12/tpm_audit.c', 'tpm12/tpm_auth.c', 'tpm12/tpm_cryptoh.c', 'tpm12/tpm_counter.c', 'tpm12/tpm_daa.c', @@ -108,7 +103,7 @@ if with_tpm1 endif if with_tpm2 - message('Building with TPM 2.0 support') + common_c_args += ['-DWITH_TPM2'] rt_dep = meson.get_compiler('c').find_library('rt', required: false) extra_deps += rt_dep From 1aa944983858d31cde4ad716b1002f763ee9edd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 17:31:34 +0400 Subject: [PATCH 12/18] meson: fix build with missing crypto flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau --- meson.build | 6 ++++++ src/meson.build | 10 +++++----- src/tpm12/tpm_crypto_freebl.c | 8 -------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/meson.build b/meson.build index 4c05a4ee8..773df5226 100644 --- a/meson.build +++ b/meson.build @@ -26,6 +26,12 @@ with_tpm1 = get_option('tpm1') with_tpm2 = get_option('tpm2') crypto_backend = get_option('crypto_backend') +if crypto_backend == 'openssl' + add_project_arguments(['-DUSE_OPENSSL_CRYPTO_LIBRARY=1'], language: 'c') +else + add_project_arguments(['-DUSE_FREEBL_CRYPTO_LIBRARY=1'], language: 'c') +endif + # Add hardening flags for non-plain build types if get_option('buildtype') != 'plain' hardening_c_flags = [] diff --git a/src/meson.build b/src/meson.build index 5c1d3414e..5da2089ce 100644 --- a/src/meson.build +++ b/src/meson.build @@ -7,14 +7,14 @@ endif crypto_deps = [] tpm1_crypto_sources = [] freebl_inc = [] -openssl_flags = [] +crypto_flags = [] if crypto_backend == 'openssl' crypto_deps += dependency('openssl', version: '>=1.1.0', required: true) if with_tpm1 tpm1_crypto_sources += 'tpm12/tpm_crypto.c' endif if get_option('use_openssl_functions') - openssl_flags += [ + crypto_flags += [ '-DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=1', '-DUSE_OPENSSL_FUNCTIONS_EC=1', '-DUSE_OPENSSL_FUNCTIONS_ECDSA=1', @@ -22,7 +22,7 @@ if crypto_backend == 'openssl' '-DUSE_OPENSSL_FUNCTIONS_SSKDF=1' ] else - openssl_flags += [ + crypto_flags += [ '-DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=0', '-DUSE_OPENSSL_FUNCTIONS_EC=0', '-DUSE_OPENSSL_FUNCTIONS_ECDSA=0', @@ -88,7 +88,7 @@ if with_tpm1 ) tpm1_lib = static_library('tpms_tpm12', tpm1_sources, - c_args: common_c_args + openssl_flags + [ + c_args: common_c_args + crypto_flags + [ '-DTPM_V12', '-DTPM_PCCLIENT', '-DTPM_POSIX', @@ -161,7 +161,7 @@ if with_tpm2 ) tpm2_lib = static_library('tpms_tpm2', tpm2_sources, - c_args: common_c_args + openssl_flags + [ + c_args: common_c_args + crypto_flags + [ '-D_POSIX_C_SOURCE=200809L', '-DTPM_POSIX', '-include', 'config.h' diff --git a/src/tpm12/tpm_crypto_freebl.c b/src/tpm12/tpm_crypto_freebl.c index 36afae52f..272c26472 100644 --- a/src/tpm12/tpm_crypto_freebl.c +++ b/src/tpm12/tpm_crypto_freebl.c @@ -82,14 +82,6 @@ static unsigned char sha1Oid[] = { local prototypes */ -static TPM_RESULT TPM_RSAPublicEncryptRaw(unsigned char *encrypt_data, /* output */ - uint32_t encrypt_data_size, /* input, size of enc buffer */ - unsigned char *decrypt_data, /* input */ - uint32_t decrypt_data_size, /* input, size of dec buffer */ - unsigned char *narr, /* public modulus */ - uint32_t nbytes, - unsigned char *earr, /* public exponent */ - uint32_t ebytes); static void TPM_RSAPrivateKeyInit(RSAPrivateKey *rsa_pri_key); static TPM_RESULT TPM_RSAGeneratePublicToken(RSAPublicKey *rsa_pub_key, unsigned char *narr, From 9ab7ac1b19eb6246d07fdc86608808dd8d2f33ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 15:03:41 +0400 Subject: [PATCH 13/18] feat: implement tests with meson MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For various reasons Gemini wasn't capable of adding the tests. It kept following rabbit-holes in a loop. Do it by hand instead. Signed-off-by: Marc-André Lureau --- meson.build | 3 +- meson_options.txt | 3 ++ src/meson.build | 15 ++++++++++ tests/meson.build | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 tests/meson.build diff --git a/meson.build b/meson.build index 773df5226..e700eb51f 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('libtpms', 'c', +project('libtpms', ['c', 'cpp'], version: '0.11.0', license: 'BSD-3-Clause AND LicenseRef-TCGL', default_options: ['c_std=c99']) @@ -83,6 +83,7 @@ configure_file( subdir('include') subdir('src') subdir('man') +subdir('tests') summary_info = {} summary_info += {'Build directory': meson.current_build_dir()} diff --git a/meson_options.txt b/meson_options.txt index 9ba573bdd..b4724021b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,7 @@ + option('tpm1', type: 'boolean', value: true, description: 'Build with TPM 1.2 support.') option('tpm2', type: 'boolean', value: true, description: 'Build with TPM 2.0 support.') option('crypto_backend', type: 'combo', choices: ['openssl', 'freebl'], value: 'openssl', description: 'Choose the cryptographic backend.') option('use_openssl_functions', type: 'boolean', value: true, description: 'Use OpenSSL functions for crypto instead of internal code.') +option('static_tests', type: 'boolean', value: false, description: 'Enable static tests') +option('fuzzing_engine', type: 'boolean', value: false, description: 'Build with fuzzing engine') diff --git a/src/meson.build b/src/meson.build index 5da2089ce..a7ebaa987 100644 --- a/src/meson.build +++ b/src/meson.build @@ -186,3 +186,18 @@ libtpms = shared_library('tpms', include_directories: [lib_inc], install: true, ) + +libtpms_dep = declare_dependency( + link_with: libtpms, + include_directories: [lib_inc], + dependencies: crypto_deps + extra_deps, +) + +# Pkg-config generation +pkg = import('pkgconfig') +pkg.generate( + name: 'libtpms', + description: 'A library for TPM emulation.', + version: meson.project_version(), + libraries: libtpms +) diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 000000000..e5d90ccbc --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,70 @@ +test_env = { + 'abs_top_srcdir': meson.project_source_root(), + 'abs_top_builddir': meson.project_build_root(), + 'abs_top_testdir': meson.project_source_root() / 'tests', +} + +sh = find_program('sh') + +exe = executable('base64decode', files('base64decode.c'), dependencies: [libtpms_dep]) +test('base64decode.sh', sh, args: files('base64decode.sh'), depends: exe, workdir: meson.current_build_dir()) + +src_inc = [ + '../include/libtpms', + '../src', + '../src/tpm2', + '../src/tpm2/crypto', + '../src/tpm2/crypto/openssl', +] + +if get_option('tpm2') + exe = executable('nvram_offsets', 'nvram_offsets.c', + dependencies: [libtpms_dep], + include_directories: src_inc, + c_args: ['-DTPM_POSIX', '-D_POSIX_C_SOURCE=200809L'], + ) + test('nvram_offsets', exe, env: test_env) + + exe = executable('tpm2_createprimary', files('tpm2_createprimary.c'), dependencies: [libtpms_dep]) + test('tpm2_createprimary.sh', sh, args: files('tpm2_createprimary.sh'), depends: exe, workdir: meson.current_build_dir()) + + exe = executable('tpm2_cve-2023-1017', files('tpm2_cve-2023-1017.c'), dependencies: [libtpms_dep]) + test('tpm2_cve-2023-1017.sh', sh, args: files('tpm2_cve-2023-1017.sh'), depends: exe, workdir: meson.current_build_dir()) + + exe = executable('tpm2_cve-2023-1018', files('tpm2_cve-2023-1018.c'), dependencies: [libtpms_dep]) + test('tpm2_cve-2023-1018.sh', sh, args: files('tpm2_cve-2023-1018.sh'), depends: exe, workdir: meson.current_build_dir()) + + exe = executable('tpm2_selftest', files('tpm2_selftest.c'), dependencies: [libtpms_dep]) + test('tpm2_selftest.sh', sh, args: files('tpm2_selftest.sh'), depends: exe, workdir: meson.current_build_dir()) + + exe = executable('tpm2_pcr_read', files('tpm2_pcr_read.c'), dependencies: [libtpms_dep]) + test('tpm2_pcr_read.sh', sh, args: files('tpm2_pcr_read.sh'), depends: exe, workdir: meson.current_build_dir()) + + exe = executable('tpm2_setprofile', files('tpm2_setprofile.c'), dependencies: [libtpms_dep]) + test('tpm2_setprofile.sh', sh, args: files('tpm2_setprofile.sh'), depends: exe, workdir: meson.current_build_dir()) + + fuzz_sources = ['fuzz.cc'] + if not get_option('fuzzing_engine') + fuzz_sources += 'fuzz-main.c' + endif + exe = executable('fuzz', fuzz_sources, dependencies: [libtpms_dep], c_args: ['-DTPM_POSIX', '-D_POSIX_C_SOURCE=200809L']) + test('fuzz.sh', sh, args: files('fuzz.sh'), depends: exe, workdir: meson.current_build_dir()) + + if get_option('static_tests') + exe = executable('object_size', files('object_size.c'), + dependencies: [libtpms_dep], + include_directories: src_inc, + c_args: ['-static', '-DTPM_POSIX', '-D_POSIX_C_SOURCE=200809L'], + ) + test('object_size', exe, env: test_env) + endif +endif + +if crypto_backend == 'freebl' + exe = executable('freebl_sha1flattensize', 'freebl_sha1flattensize.c', + dependencies: [libtpms_dep, nss_dep, nspr_dep], + link_args: ['-lfreebl'] + ) + # FIXME: test fails + # test('freebl_sha1flattensize', exe, env: test_env) +endif From 86b5684cfd842f14f30192ea1633194edb637725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 20:52:50 +0400 Subject: [PATCH 14/18] meson: add versioning and symbol exports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement step 10 of the meson migration plan. This adds the library versioning information to the shared library target, including soversion, and handles symbol exports using a version script, mirroring the behavior of the Autotools build system. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- src/meson.build | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/meson.build b/src/meson.build index a7ebaa987..0e3063ad8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,3 +1,13 @@ +# Versioning +libtpms_version = meson.project_version() +libtpms_version_arr = libtpms_version.split('.') +libtpms_ver_major = libtpms_version_arr[0].to_int() +libtpms_ver_minor = libtpms_version_arr[1].to_int() + +current = libtpms_ver_major + libtpms_ver_minor +age = libtpms_ver_minor +soversion = '@0@'.format(current - age) + # TPM2 requires OpenSSL in this build configuration if with_tpm2 and crypto_backend != 'openssl' error('TPM2 support currently requires the openssl crypto backend.') @@ -185,6 +195,11 @@ libtpms = shared_library('tpms', dependencies: crypto_deps + extra_deps, include_directories: [lib_inc], install: true, + version: libtpms_version, + soversion: soversion, + darwin_versions: [soversion, libtpms_version], + vs_module_defs: 'libtpms.syms', + link_args: ['-Wl,--version-script,@0@'.format(meson.current_source_dir() / 'libtpms.syms')], ) libtpms_dep = declare_dependency( @@ -200,4 +215,4 @@ pkg.generate( description: 'A library for TPM emulation.', version: meson.project_version(), libraries: libtpms -) +) \ No newline at end of file From 814c8171817dc3b24552fd6e78025d7863d8f16e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 21:07:03 +0400 Subject: [PATCH 15/18] meson: fix linking object_size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build both libraries, drop need for "static_tests" option. Signed-off-by: Marc-André Lureau --- meson_options.txt | 1 - src/meson.build | 4 ++-- tests/meson.build | 14 ++++++-------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index b4724021b..7c3997f9e 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,5 +3,4 @@ option('tpm1', type: 'boolean', value: true, description: 'Build with TPM 1.2 su option('tpm2', type: 'boolean', value: true, description: 'Build with TPM 2.0 support.') option('crypto_backend', type: 'combo', choices: ['openssl', 'freebl'], value: 'openssl', description: 'Choose the cryptographic backend.') option('use_openssl_functions', type: 'boolean', value: true, description: 'Use OpenSSL functions for crypto instead of internal code.') -option('static_tests', type: 'boolean', value: false, description: 'Enable static tests') option('fuzzing_engine', type: 'boolean', value: false, description: 'Build with fuzzing engine') diff --git a/src/meson.build b/src/meson.build index 0e3063ad8..f0aa9761e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -188,7 +188,7 @@ if with_tpm2 endif # Define the final shared library -libtpms = shared_library('tpms', +libtpms = both_libraries('tpms', common_sources, c_args: common_c_args + ['-include', 'config.h'], link_with: link_with_libs, @@ -215,4 +215,4 @@ pkg.generate( description: 'A library for TPM emulation.', version: meson.project_version(), libraries: libtpms -) \ No newline at end of file +) diff --git a/tests/meson.build b/tests/meson.build index e5d90ccbc..47950d25c 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -50,14 +50,12 @@ if get_option('tpm2') exe = executable('fuzz', fuzz_sources, dependencies: [libtpms_dep], c_args: ['-DTPM_POSIX', '-D_POSIX_C_SOURCE=200809L']) test('fuzz.sh', sh, args: files('fuzz.sh'), depends: exe, workdir: meson.current_build_dir()) - if get_option('static_tests') - exe = executable('object_size', files('object_size.c'), - dependencies: [libtpms_dep], - include_directories: src_inc, - c_args: ['-static', '-DTPM_POSIX', '-D_POSIX_C_SOURCE=200809L'], - ) - test('object_size', exe, env: test_env) - endif + exe = executable('object_size', files('object_size.c'), + link_with: libtpms.get_static_lib(), + include_directories: src_inc, + c_args: ['-static', '-DTPM_POSIX', '-D_POSIX_C_SOURCE=200809L'], + ) + test('object_size', exe, env: test_env) endif if crypto_backend == 'freebl' From 18d40372519be46588365356154199c4c74ee4bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 21:32:19 +0400 Subject: [PATCH 16/18] meson: cleanups & misc improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc-André Lureau --- config.h.in | 5 - include/libtpms/meson.build | 8 +- meson.build | 36 +-- meson_options.txt => meson.options | 0 meson_migration_plan.md | 450 ----------------------------- src/meson.build | 14 +- 6 files changed, 32 insertions(+), 481 deletions(-) delete mode 100644 config.h.in rename meson_options.txt => meson.options (100%) delete mode 100644 meson_migration_plan.md diff --git a/config.h.in b/config.h.in deleted file mode 100644 index 238722270..000000000 --- a/config.h.in +++ /dev/null @@ -1,5 +0,0 @@ -/* config.h.in. Generated from meson.build by Meson. */ - -#mesondefine PACKAGE_VERSION -#mesondefine HAVE_ARPA_INET_H -#mesondefine HAVE_TIME_H diff --git a/include/libtpms/meson.build b/include/libtpms/meson.build index b983d97ad..c0d8ce9da 100644 --- a/include/libtpms/meson.build +++ b/include/libtpms/meson.build @@ -1,9 +1,15 @@ +tpm_library_h = configure_file( + input: 'tpm_library.h.in', + output: 'tpm_library.h', + configuration: conf_data, +) + install_headers( 'tpm_error.h', - 'tpm_library.h', 'tpm_memory.h', 'tpm_nvfilename.h', 'tpm_tis.h', 'tpm_types.h', + tpm_library_h, subdir: 'libtpms' ) diff --git a/meson.build b/meson.build index e700eb51f..4204a3238 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,10 @@ -project('libtpms', ['c', 'cpp'], - version: '0.11.0', - license: 'BSD-3-Clause AND LicenseRef-TCGL', - default_options: ['c_std=c99']) +project( + 'libtpms', ['c', 'cpp'], + version: '0.11.0', + license: 'BSD-3-Clause AND LicenseRef-TCGL', + default_options: ['c_std=c99', 'warning_level=1', 'werror=true'], + meson_version: '>=1.1', +) c_compiler = meson.get_compiler('c') @@ -10,8 +13,6 @@ add_project_arguments('-I' + meson.current_build_dir(), language: 'c') # Add common warning flags warning_flags = [ - '-Wall', - '-Werror', '-Wshadow', '-Wreturn-type', '-Wsign-compare', @@ -60,25 +61,26 @@ if get_option('buildtype') != 'plain' add_project_link_arguments(hardening_ld_flags, language: 'c') endif +# Versioning +libtpms_version = meson.project_version() +libtpms_version_arr = libtpms_version.split('.') +libtpms_ver_major = libtpms_version_arr[0].to_int() +libtpms_ver_minor = libtpms_version_arr[1].to_int() +libtpms_ver_micro = libtpms_version_arr[2].to_int() + # Create a configuration header file conf_data = configuration_data() conf_data.set('PACKAGE_VERSION', '"' + meson.project_version() + '"') +conf_data.set('LIBTPMS_VER_MAJOR', libtpms_ver_major) +conf_data.set('LIBTPMS_VER_MINOR', libtpms_ver_minor) +conf_data.set('LIBTPMS_VER_MICRO', libtpms_ver_micro) -# Check for headers -if c_compiler.has_header('arpa/inet.h') - conf_data.set('HAVE_ARPA_INET_H', 1) -endif -if c_compiler.has_header('time.h') - conf_data.set('HAVE_TIME_H', 1) -endif - +# config.h could be dropped if when autotools is removed configure_file( - input: 'config.h.in', output: 'config.h', configuration: conf_data ) -# Add subdirectories to the build # Add subdirectories to the build subdir('include') subdir('src') @@ -92,4 +94,4 @@ summary_info += {'TPM1': with_tpm1} summary_info += {'TPM2': with_tpm2} summary_info += {'Crypto backend': crypto_backend} -summary(summary_info, bool_yn: true, section: 'Build environment') +summary(summary_info, bool_yn: true, section: 'Build configuration') diff --git a/meson_options.txt b/meson.options similarity index 100% rename from meson_options.txt rename to meson.options diff --git a/meson_migration_plan.md b/meson_migration_plan.md deleted file mode 100644 index 87541b9a5..000000000 --- a/meson_migration_plan.md +++ /dev/null @@ -1,450 +0,0 @@ -Of course. Here is a detailed, iterative plan to migrate the `libtpms` build system from Autotools to Meson, ensuring feature parity and comparing the two systems at each stage. - -### Migration Philosophy - -The goal is to replace `configure.ac` and all `Makefile.am` files with `meson.build` files. We will start with the simplest possible build and incrementally add features, options, and complexity, mirroring the capabilities of the Autotools setup. - ---- - -### Step 1: Basic Project Setup and a "Dummy" Library - -**Goal:** Create the initial `meson.build` file, define the project, and compile a shared library with a minimal set of source files. This is the "Hello, World" of the build system. - -**Meson Implementation (`/meson.build`):** -```meson -project('libtpms', 'c', - version: '0.11.0', - license: 'BSD-2-Clause', # Check LICENSE file for exact SPDX identifier - default_options: ['c_std=c99']) - -# Add the src subdirectory to the build -subdir('src') -``` - -**Meson Implementation (`/src/meson.build`):** -```meson -# Start with the absolute minimum common files to prove compilation works -libtpms_sources = files( - 'tpm_debug.c', - 'tpm_library.c', - 'tpm_memory.c', - 'tpm_nvfile.c', - 'disabled_interface.c' -) - -# Define the shared library -libtpms = shared_library('tpms', - libtpms_sources, - install: true, -) -``` - -**Autotools Comparison:** -* `project(...)` in Meson replaces `AC_INIT(...)` and `AM_INIT_AUTOMAKE(...)` in `configure.ac`. The version number is set directly. -* `shared_library(...)` replaces the `lib_LTLIBRARIES = libtpms.la` and the associated `libtpms_la_SOURCES` from `src/Makefile.am`. -* At this stage, we are ignoring almost all complexity, just setting up the basic structure. The `subdir('src')` call is analogous to `SUBDIRS = src` in the root `Makefile.am`. - ---- - -### Step 2: Adding Dependencies (OpenSSL) and Headers - -**Goal:** Introduce dependency handling by adding the OpenSSL requirement. We will also define and install the public header files. - -**Meson Implementation (`/src/meson.build`):** -```meson -# Find the OpenSSL dependency (libcrypto) -crypto_dep = dependency('openssl', version: '>=1.1.0') - -# Public headers from include/libtpms -inc_dir = include_directories('../include/libtpms') - -libtpms_sources = files( - # ... same files as Step 1 ... -) - -libtpms = shared_library('tpms', - libtpms_sources, - include_directories: inc_dir, - dependencies: crypto_dep, # Link against the dependency - install: true, -) - -# --- Header Installation --- -# This part goes in a new `include/libtpms/meson.build` -# and is called from the root `meson.build` via `subdir('include/libtpms')` - -# in include/libtpms/meson.build: -install_headers( - 'tpm_error.h', - 'tpm_library.h', - 'tpm_memory.h', - 'tpm_nvfilename.h', - 'tpm_tis.h', - 'tpm_types.h', - subdir: 'libtpms' -) -``` - -**Autotools Comparison:** -* `dependency('openssl')` replaces `AC_CHECK_LIB(crypto, ...)` and the associated header checks in `configure.ac`. Meson handles finding the library, its headers, and providing the necessary flags automatically. It's much more concise. -* `install_headers(...)` replaces the `libtpmsinclude_HEADERS` and `libtpmsincludedir` logic from `include/libtpms/Makefile.am`. - ---- - -### Step 3: Introducing Build Options (TPM1/TPM2 Support) - -**Goal:** Replicate the `--with-tpm1` and `--with-tpm2` configure flags using Meson's feature options. - -**Meson Implementation (`/meson.build`):** -```meson -project('libtpms', 'c', - # ... - ) - -# Define build options, similar to configure flags -option('tpm1', type: 'boolean', value: true, description: 'Build with TPM 1.2 support.') -option('tpm2', type: 'boolean', value: true, description: 'Build with TPM 2.0 support.') - -# ... -subdir('src') -``` - -**Meson Implementation (`/src/meson.build`):** -```meson -# ... (dependencies, etc.) ... - -# Get the value of the options -with_tpm1 = get_option('tpm1') -with_tpm2 = get_option('tpm2') - -# Start building the source list conditionally -libtpms_sources = files(...) # Core files from Step 1 - -if with_tpm1 - # Add TPM1 sources here - message('Building with TPM 1.2 support') -endif - -if with_tpm2 - # Add TPM2 sources here - message('Building with TPM 2.0 support') -endif - -# ... -``` - -**Autotools Comparison:** -* `option('tpm1', ...)` is the direct equivalent of `AC_ARG_WITH([tpm1], ...)`. The `value: true` makes it an enabled-by-default option. -* `get_option('tpm1')` is how the build script retrieves the user's choice, similar to how the shell variable `$with_tpm1` is used in `configure.ac`. -* The `if/endif` blocks directly mirror the `AM_CONDITIONAL([WITH_TPM1], ...)` logic used to control which source files are compiled in `src/Makefile.am`. - ---- - -### Step 4: Populating Conditional Source Files - -**Goal:** Fully replicate the conditional source file logic from `src/Makefile.am` based on the TPM1/TPM2 options. - -**Meson Implementation (`/src/meson.build`):** -```meson -# ... (options, dependencies) ... - -# Create empty arrays for sources -tpm1_sources = [] -tpm2_sources = [] -common_sources = files( - 'disabled_interface.c', - 'tpm_debug.c', - 'tpm_library.c', - 'tpm_memory.c', - 'tpm_nvfile.c' -) - -# TPM 1.2 Sources -if get_option('tpm1') - tpm1_sources += files( - 'tpm12/tpm_admin.c', - 'tpm12/tpm_audit.c', - # ... all other tpm12 sources ... - 'tpm_tpm12_interface.c', - 'tpm_tpm12_tis.c', - 'tpm12/tpm_crypto.c' # Assuming OpenSSL for now - ) -endif - -# TPM 2.0 Sources -if get_option('tpm2') - # Check for librt, needed by TPM2 code - rt_dep = meson.get_compiler('c').find_library('rt', required: false) - - tpm2_sources += files( - 'tpm2/ACT_spt.c', - 'tpm2/ACTCommands.c', - # ... all other tpm2 sources ... - 'tpm_tpm2_interface.c', - 'tpm_tpm2_tis.c' - ) - # Add TPM2 crypto sources for OpenSSL - tpm2_sources += files( - 'tpm2/crypto/openssl/BnToOsslMath.c', - # ... all other tpm2/crypto/openssl sources ... - ) -endif - -# Combine all sources -libtpms = shared_library('tpms', - common_sources + tpm1_sources + tpm2_sources, - dependencies: [crypto_dep, rt_dep], # Add rt_dep here - # ... -) -``` - -**Autotools Comparison:** -* This step directly translates the large `libtpms_tpm12_la_SOURCES` and `libtpms_tpm2_la_SOURCES` blocks from `src/Makefile.am` into Meson lists. -* The `find_library('rt', ...)` call replaces `AC_CHECK_LIB(c, clock_gettime, ..., LIBRT_LIBS="-lrt")`. -* The concatenation of source lists (`common_sources + tpm1_sources + ...`) is Meson's way of achieving what `libtpms_la_LIBADD += libtpms_tpm12.la` does in `Makefile.am`—combining different components into one final target. - ---- - -### Step 5: Compiler Flags and Hardening - -**Goal:** Add warning flags and security hardening flags, checking for compiler support first. - -**Meson Implementation (`/meson.build`):** -```meson -project(...) - -c_compiler = meson.get_compiler('c') - -# Define flags and check for support -c_flags = [ - '-Wall', - '-Werror', - '-Wshadow', - '-Wreturn-type', - '-Wsign-compare', - '-Wno-self-assign', - '-Wmissing-prototypes' -] -supported_c_flags = c_compiler.get_supported_arguments(c_flags) -add_project_arguments(supported_c_flags, language: 'c') - -# Hardening flags -hardening_flags = [] -if get_option('buildtype') != 'plain' - # Stack protector - if c_compiler.has_argument('-fstack-protector-strong') - hardening_flags += '-fstack-protector-strong' - elif c_compiler.has_argument('-fstack-protector') - hardening_flags += '-fstack-protector' - endif - # Fortify source - if c_compiler.has_argument('-D_FORTIFY_SOURCE=2') - hardening_flags += '-D_FORTIFY_SOURCE=2' - endif -endif -add_project_arguments(hardening_flags, language: 'c') - -# Hardening linker flags -ld_flags = [] -if get_option('buildtype') != 'plain' - if c_compiler.has_link_argument('-Wl,-z,relro') - ld_flags += '-Wl,-z,relro' - endif - if c_compiler.has_link_argument('-Wl,-z,now') - ld_flags += '-Wl,-z,now' - endif -endif -add_project_link_arguments(ld_flags, language: 'c') -``` - -**Autotools Comparison:** -* This replaces the manual `AM_CFLAGS` definitions and the complex `AS_IF` blocks that check for hardening support in `configure.ac`. -* `compiler.get_supported_arguments()`, `compiler.has_argument()`, and `compiler.has_link_argument()` are Meson's clean and reliable way to perform the same checks that Autotools does with trial compilations. -* `add_project_arguments` and `add_project_link_arguments` are the global way to add flags, similar to setting `AM_CFLAGS` and `AM_LDFLAGS`. - ---- - -### Step 6: Adding the FreeBL Crypto Backend - -**Goal:** Implement the logic to choose between OpenSSL and FreeBL. - -**Meson Implementation (`/meson.build`):** -```meson -# Add a choice option for the crypto backend -option('crypto_backend', type: 'combo', choices: ['openssl', 'freebl'], value: 'openssl', - description: 'Choose the cryptographic backend.') -``` - -**Meson Implementation (`/src/meson.build`):** -```meson -crypto_backend = get_option('crypto_backend') -crypto_dep = [] -c_args = [] - -if crypto_backend == 'openssl' - crypto_dep = dependency('openssl') - c_args += '-DUSE_OPENSSL_CRYPTO_LIBRARY=1' -else # freebl - # Find nss, nspr, gmp - nss_dep = dependency('nss') - nspr_dep = dependency('nspr') - gmp_dep = dependency('gmp') - # freebl is part of nss, but we might need to find it explicitly - freebl_dep = meson.get_compiler('c').find_library('freebl', required: true) - crypto_dep = [nss_dep, nspr_dep, gmp_dep, freebl_dep] - c_args += '-DUSE_FREEBL_CRYPTO_LIBRARY=1' -endif - -# In the library definition: -libtpms = shared_library('tpms', - ..., - c_args: c_args, - dependencies: crypto_dep, - ... -) -``` - -**Autotools Comparison:** -* The `combo` option type is a much cleaner way to handle mutually exclusive choices than the Autotools `AC_ARG_WITH` logic. -* The `if/else` block for `crypto_backend` replaces the `AS_CASE([$cryptolib], ...)` block in `configure.ac`. -* Dependency management remains much simpler. Instead of manual `AC_CHECK_HEADERS` and `AC_SEARCH_LIBS`, we just declare the dependencies. - ---- - -### Step 7: Adding Finer-Grained Crypto Options - -**Goal:** Implement the `--disable-use-openssl-functions` logic. - -**Meson Implementation (`/meson.build`):** -```meson -option('use_openssl_functions', type: 'boolean', value: true, - description: 'Use OpenSSL functions for crypto instead of internal code.') -``` - -**Meson Implementation (`/src/meson.build`):** -```meson -# ... -if crypto_backend == 'openssl' and get_option('use_openssl_functions') - # Check for specific functions in libcrypto - # Meson doesn't have a direct check_lib for functions, but we can use has_function - # or just assume modern OpenSSL has them. For this plan, we'll add defines. - c_args += [ - '-DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=1', - '-DUSE_OPENSSL_FUNCTIONS_EC=1', - '-DUSE_OPENSSL_FUNCTIONS_ECDSA=1', - '-DUSE_OPENSSL_FUNCTIONS_RSA=1', - '-DUSE_OPENSSL_FUNCTIONS_SSKDF=1' - ] -else - c_args += [ - '-DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=0', - # ... and so on for all flags ... - ] -endif -``` - -**Autotools Comparison:** -* This replaces the `AC_ARG_ENABLE([use-openssl-functions], ...)` and the many `AC_CHECK_LIB` calls for individual functions. While Meson's `has_function` is available, it's often simpler to rely on the dependency version and add the defines, as the check in Autotools is mostly for older OpenSSL versions. - ---- - -### Step 8: Building Tests, Man Pages, and Pkg-Config - -**Goal:** Replicate the `tests` and `man` directory targets, and generate the `libtpms.pc` file. - -**Meson Implementation (`/tests/meson.build`):** -```meson -# Get the libtpms dependency from the main build -libtpms_dep = dependency('tpms', fallback: ['tpms', 'libtpms']) - -# Build an executable -tpm2_selftest = executable('tpm2_selftest', - 'tpm2_selftest.c', - dependencies: libtpms_dep -) - -# Define a test -test('TPM2 Self Test', tpm2_selftest, - args: ['--device', '/dev/null']) -``` - -**Meson Implementation (`/man/man3/meson.build`):** -```meson -pod2man = find_program('pod2man', required: true) - -# Use a custom target to generate man pages -custom_target('man_TPM_IO_Hash_Start', - input: 'TPM_IO_Hash_Start.pod', - output: 'TPM_IO_Hash_Start.3', - command: [pod2man, '-r', 'libtpms', '-c', '""', '-n', '@BASENAME@', '--section=3', '@INPUT@'], - capture: true, - install: true, - install_dir: get_option('mandir') / 'man3' -) -# Repeat for all .pod files -``` - -**Meson Implementation (`/meson.build`):** -```meson -# ... -# Pkg-config generation -pkg = import('pkgconfig') -pkg.generate( - name: 'libtpms', - description: 'A library for TPM emulation.', - version: meson.project_version(), - libraries: libtpms -) -``` - -**Autotools Comparison:** -* `executable()` and `test()` in `tests/meson.build` replace `check_PROGRAMS` and `TESTS` from `tests/Makefile.am`. The dependency is handled cleanly. -* `custom_target()` is Meson's powerful way to replace rule-based recipes, like the `%.3 : %.pod` rule in `man/man3/Makefile.am`. -* The `pkgconfig` module is a massive simplification over maintaining a `libtpms.pc.in` file and using `AC_SUBST` in `configure.ac`. - ---- - -### Step 9: Special Build Modes (Coverage, Sanitizers) - -**Goal:** Implement the remaining special build modes. - -**Meson Implementation:** -This is where Meson shines. There is no need for custom logic in the build files. The user controls this with built-in options: -* **Test Coverage:** `./meson configure -Db_coverage=true` -* **Sanitizers:** `./meson configure -Db_sanitize=address,undefined` -* **Fuzzing:** `./meson configure -Db_fuzzing=true` (requires a recent Meson version) - -**Autotools Comparison:** -* This replaces `AC_ARG_ENABLE([test-coverage], ...)` and `AC_ARG_ENABLE([sanitizers], ...)`. Meson's implementation is standardized, requires zero code in the build scripts, and is less error-prone than managing `COVERAGE_CFLAGS` manually. - ---- - -### Step 10: Final Touches (Versioning, Installation) - -**Goal:** Ensure library versioning and symbol exports are correct. - -**Meson Implementation (`/src/meson.build`):** -```meson -# ... -libtpms_version = meson.project_version() -# LIBTPMS_VERSION_INFO=`expr $LIBTPMS_VER_MAJOR + $LIBTPMS_VER_MINOR`:$LIBTPMS_VER_MICRO:$LIBTPMS_VER_MINOR -# This logic needs to be translated to Meson. -# For 0.11.0, this is 11:0:11 -soversion = '11' # Based on the autotools logic for this specific version - -libtpms = shared_library('tpms', - ..., - version: libtpms_version, - soversion: soversion, - darwin_versions: [soversion, libtpms_version], # For macOS compatibility - vs_module_defs: 'libtpms.syms', # For Windows - link_args: ['-Wl,--version-script,@0@'.format(files('libtpms.syms')[0].full_path())], # For Linux/ELF - install: true -) -``` - -**Autotools Comparison:** -* The `version` and `soversion` parameters in `shared_library` replace the `-version-info $(LIBTPMS_VERSION_INFO)` logic. -* The `link_args` with a version script replaces the `HAVE_VERSION_SCRIPT` conditional logic and the associated `-Wl,--version-script` flag in `src/Makefile.am`. Meson makes accessing the file path for this much easier. - -This iterative plan provides a clear path from a basic build to a full-featured replacement of the Autotools system, highlighting the advantages and simplifications Meson offers at each step. diff --git a/src/meson.build b/src/meson.build index f0aa9761e..3d3071eff 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,9 +1,3 @@ -# Versioning -libtpms_version = meson.project_version() -libtpms_version_arr = libtpms_version.split('.') -libtpms_ver_major = libtpms_version_arr[0].to_int() -libtpms_ver_minor = libtpms_version_arr[1].to_int() - current = libtpms_ver_major + libtpms_ver_minor age = libtpms_ver_minor soversion = '@0@'.format(current - age) @@ -174,7 +168,6 @@ if with_tpm2 c_args: common_c_args + crypto_flags + [ '-D_POSIX_C_SOURCE=200809L', '-DTPM_POSIX', - '-include', 'config.h' ], include_directories: [ lib_inc, @@ -190,7 +183,7 @@ endif # Define the final shared library libtpms = both_libraries('tpms', common_sources, - c_args: common_c_args + ['-include', 'config.h'], + c_args: common_c_args, link_with: link_with_libs, dependencies: crypto_deps + extra_deps, include_directories: [lib_inc], @@ -214,5 +207,10 @@ pkg.generate( name: 'libtpms', description: 'A library for TPM emulation.', version: meson.project_version(), + variables: [ + 'with_tpm1=@0@'.format(with_tpm1 ? '1' : '0'), + 'with_tpm2=@0@'.format(with_tpm2 ? '1' : '0'), + 'cryptolib=@0@'.format(crypto_backend), + ], libraries: libtpms ) From b479163801bd8ee61ddcd21e090caeb62170894b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 22:03:53 +0400 Subject: [PATCH 17/18] feat: Add meson build to GitHub CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a meson build to the GitHub CI workflow. It also updates the README with build instructions for both autotools and meson. Signed-off-by: Gemini Signed-off-by: Marc-André Lureau --- .github/workflows/ci.yml | 18 ++++++++++++++++++ README | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 906654873..f3eb114a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,3 +72,21 @@ jobs: exit 0 env: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + + meson-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y meson ninja-build pkg-config openssl libssl-dev + + - name: meson build + run: | + meson setup build --prefix=/usr + meson compile -C build + meson test -C build + meson dist -C build + tar -tf build/meson-dist/*.tar.xz diff --git a/README b/README index 65f654bbd..56aaaf0bd 100644 --- a/README +++ b/README @@ -74,6 +74,31 @@ For patch submissions, please use a Signed-off-by: to indicate agreement to the DCO1.1.txt. +Building +-------- + +There are two build systems available for libtpms: autotools and meson. +The GitHub CI runs builds using both build systems. + +### Autotools + +To build with autotools, run the following commands: + + $ ./autogen.sh --with-openssl --prefix=/usr --with-tpm2 + $ make + $ make check + $ sudo make install + +### Meson + +To build with meson, run the following commands: + + $ meson setup build --prefix=/usr + $ meson compile -C build + $ meson test -C build + $ sudo meson install -C build + + Fuzzing ------- Initial fuzzing is possible with clang & libfuzzer. From 80ef24a8c8f8a5a68a179399e135f0f72062c33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 4 Aug 2025 22:57:41 +0400 Subject: [PATCH 18/18] meson: change format of source files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason, gemini choose a compact form instead. Also split the libtpms-sepecific files out as did the original Makefile.am. Signed-off-by: Marc-André Lureau --- src/meson.build | 235 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 173 insertions(+), 62 deletions(-) diff --git a/src/meson.build b/src/meson.build index 3d3071eff..59da2fa11 100644 --- a/src/meson.build +++ b/src/meson.build @@ -75,19 +75,44 @@ common_c_args = [ if with_tpm1 common_c_args += ['-DWITH_TPM1'] tpm1_sources = files( - 'tpm12/tpm_admin.c', 'tpm12/tpm_audit.c', 'tpm12/tpm_auth.c', - 'tpm12/tpm_cryptoh.c', 'tpm12/tpm_counter.c', 'tpm12/tpm_daa.c', - 'tpm12/tpm_delegate.c', 'tpm12/tpm_digest.c', 'tpm12/tpm_error.c', - 'tpm12/tpm_global.c', 'tpm12/tpm_identity.c', 'tpm12/tpm_init.c', - 'tpm12/tpm_libtpms_io.c', 'tpm12/tpm_key.c', 'tpm12/tpm_load.c', - 'tpm12/tpm_maint.c', 'tpm12/tpm_migration.c', 'tpm12/tpm_nonce.c', - 'tpm12/tpm_nvram.c', 'tpm12/tpm_openssl_helpers.c', 'tpm12/tpm_owner.c', - 'tpm12/tpm_pcr.c', 'tpm12/tpm_permanent.c', 'tpm12/tpm_platform.c', - 'tpm12/tpm_process.c', 'tpm12/tpm_secret.c', 'tpm12/tpm_session.c', - 'tpm12/tpm_sizedbuffer.c', 'tpm12/tpm_startup.c', 'tpm12/tpm_store.c', - 'tpm12/tpm_storage.c', 'tpm12/tpm_ticks.c', 'tpm12/tpm_time.c', - 'tpm12/tpm_transport.c', 'tpm12/tpm_ver.c', 'tpm12/tpm_svnrevision.c', - 'tpm_tpm12_interface.c', 'tpm_tpm12_tis.c', + 'tpm12/tpm_admin.c', + 'tpm12/tpm_audit.c', + 'tpm12/tpm_auth.c', + 'tpm12/tpm_counter.c', + 'tpm12/tpm_cryptoh.c', + 'tpm12/tpm_daa.c', + 'tpm12/tpm_delegate.c', + 'tpm12/tpm_digest.c', + 'tpm12/tpm_error.c', + 'tpm12/tpm_global.c', + 'tpm12/tpm_identity.c', + 'tpm12/tpm_init.c', + 'tpm12/tpm_key.c', + 'tpm12/tpm_libtpms_io.c', + 'tpm12/tpm_load.c', + 'tpm12/tpm_maint.c', + 'tpm12/tpm_migration.c', + 'tpm12/tpm_nonce.c', + 'tpm12/tpm_nvram.c', + 'tpm12/tpm_openssl_helpers.c', + 'tpm12/tpm_owner.c', + 'tpm12/tpm_pcr.c', + 'tpm12/tpm_permanent.c', + 'tpm12/tpm_platform.c', + 'tpm12/tpm_process.c', + 'tpm12/tpm_secret.c', + 'tpm12/tpm_session.c', + 'tpm12/tpm_sizedbuffer.c', + 'tpm12/tpm_startup.c', + 'tpm12/tpm_storage.c', + 'tpm12/tpm_store.c', + 'tpm12/tpm_svnrevision.c', + 'tpm12/tpm_ticks.c', + 'tpm12/tpm_time.c', + 'tpm12/tpm_transport.c', + 'tpm12/tpm_ver.c', + 'tpm_tpm12_interface.c', + 'tpm_tpm12_tis.c', tpm1_crypto_sources ) @@ -112,56 +137,142 @@ if with_tpm2 extra_deps += rt_dep tpm2_sources = files( - 'tpm2/ACT_spt.c', 'tpm2/ACTCommands.c', 'tpm2/AlgorithmCap.c', - 'tpm2/AlgorithmTests.c', 'tpm2/AsymmetricCommands.c', - 'tpm2/AttestationCommands.c', 'tpm2/Attest_spt.c', 'tpm2/AuditCommands.c', - 'tpm2/Bits.c', 'tpm2/BnEccConstants.c', 'tpm2/BnConvert.c', 'tpm2/BnMath.c', - 'tpm2/BnMemory.c', 'tpm2/Cancel.c', 'tpm2/CapabilityCommands.c', - 'tpm2/Clock.c', 'tpm2/ClockCommands.c', 'tpm2/CommandAudit.c', - 'tpm2/CommandCodeAttributes.c', 'tpm2/CommandDispatcher.c', - 'tpm2/ContextCommands.c', 'tpm2/Context_spt.c', 'tpm2/CryptEccData.c', - 'tpm2/CryptSelfTest.c', 'tpm2/CryptUtil.c', 'tpm2/DA.c', - 'tpm2/DebugHelpers.c', 'tpm2/DictionaryCommands.c', - 'tpm2/DuplicationCommands.c', 'tpm2/EACommands.c', - 'tpm2/EncryptDecrypt_spt.c', 'tpm2/Entity.c', 'tpm2/Entropy.c', - 'tpm2/EphemeralCommands.c', 'tpm2/ExecCommand.c', 'tpm2/ExtraData.c', - 'tpm2/Global.c', 'tpm2/Handle.c', 'tpm2/HashCommands.c', - 'tpm2/Hierarchy.c', 'tpm2/HierarchyCommands.c', 'tpm2/IntegrityCommands.c', - 'tpm2/IoBuffers.c', 'tpm2/Locality.c', 'tpm2/LocalityPlat.c', - 'tpm2/ManagementCommands.c', 'tpm2/Manufacture.c', 'tpm2/Marshal.c', - 'tpm2/MathOnByteBuffers.c', 'tpm2/Memory.c', 'tpm2/NVCommands.c', - 'tpm2/NvDynamic.c', 'tpm2/NVMem.c', 'tpm2/NvReserved.c', 'tpm2/NV_spt.c', - 'tpm2/Object.c', 'tpm2/ObjectCommands.c', 'tpm2/Object_spt.c', 'tpm2/PCR.c', - 'tpm2/PlatformACT.c', 'tpm2/PlatformData.c', 'tpm2/PlatformPCR.c', - 'tpm2/Policy_spt.c', 'tpm2/Power.c', 'tpm2/PowerPlat.c', 'tpm2/PP.c', - 'tpm2/PPPlat.c', 'tpm2/PrimeData.c', 'tpm2/PropertyCap.c', - 'tpm2/RandomCommands.c', 'tpm2/Response.c', - 'tpm2/ResponseCodeProcessing.c', 'tpm2/RunCommand.c', 'tpm2/Session.c', - 'tpm2/SessionCommands.c', 'tpm2/SessionProcess.c', - 'tpm2/SigningCommands.c', 'tpm2/StartupCommands.c', - 'tpm2/SymmetricCommands.c', 'tpm2/TestingCommands.c', 'tpm2/Ticket.c', - 'tpm2/Time.c', 'tpm2/TpmASN1.c', 'tpm2/TpmBigNumThunks.c', - 'tpm2/TpmEcc_Signature_ECDAA.c', 'tpm2/TpmEcc_Signature_ECDSA.c', - 'tpm2/TpmEcc_Signature_Schnorr.c', 'tpm2/TpmEcc_Signature_SM2.c', - 'tpm2/TpmEcc_Signature_Util.c', 'tpm2/TpmEcc_Util.c', - 'tpm2/TpmMath_Debug.c', 'tpm2/TpmMath_Util.c', 'tpm2/TpmSizeChecks.c', - 'tpm2/TPMCmdp.c', 'tpm2/TpmFail.c', 'tpm2/Unique.c', 'tpm2/Unmarshal.c', - 'tpm2/VendorInfo.c', 'tpm2/Vendor_TCG_Test.c', 'tpm2/X509_ECC.c', - 'tpm2/X509_RSA.c', 'tpm2/X509_spt.c', 'tpm_tpm2_interface.c', - 'tpm_tpm2_tis.c', 'tpm2/BackwardsCompatibilityBitArray.c', - 'tpm2/BackwardsCompatibilityObject.c', 'tpm2/LibtpmsCallbacks.c', - 'tpm2/NVMarshal.c', 'tpm2/RuntimeAlgorithm.c', 'tpm2/RuntimeAttributes.c', - 'tpm2/RuntimeCommands.c', 'tpm2/RuntimeProfile.c', 'tpm2/StateMarshal.c', + 'tpm2/ACTCommands.c', + 'tpm2/ACT_spt.c', + 'tpm2/AlgorithmCap.c', + 'tpm2/AlgorithmTests.c', + 'tpm2/AsymmetricCommands.c', + 'tpm2/Attest_spt.c', + 'tpm2/AttestationCommands.c', + 'tpm2/AuditCommands.c', + 'tpm2/Bits.c', + 'tpm2/BnConvert.c', + 'tpm2/BnEccConstants.c', + 'tpm2/BnMath.c', + 'tpm2/BnMemory.c', + 'tpm2/Cancel.c', + 'tpm2/CapabilityCommands.c', + 'tpm2/Clock.c', + 'tpm2/ClockCommands.c', + 'tpm2/CommandAudit.c', + 'tpm2/CommandCodeAttributes.c', + 'tpm2/CommandDispatcher.c', + 'tpm2/ContextCommands.c', + 'tpm2/Context_spt.c', + 'tpm2/CryptEccData.c', + 'tpm2/CryptSelfTest.c', + 'tpm2/CryptUtil.c', + 'tpm2/DA.c', + 'tpm2/DebugHelpers.c', + 'tpm2/DictionaryCommands.c', + 'tpm2/DuplicationCommands.c', + 'tpm2/EACommands.c', + 'tpm2/EncryptDecrypt_spt.c', + 'tpm2/Entity.c', + 'tpm2/Entropy.c', + 'tpm2/EphemeralCommands.c', + 'tpm2/ExecCommand.c', + 'tpm2/ExtraData.c', + 'tpm2/Global.c', + 'tpm2/Handle.c', + 'tpm2/HashCommands.c', + 'tpm2/Hierarchy.c', + 'tpm2/HierarchyCommands.c', + 'tpm2/IntegrityCommands.c', + 'tpm2/IoBuffers.c', + 'tpm2/Locality.c', + 'tpm2/LocalityPlat.c', + 'tpm2/ManagementCommands.c', + 'tpm2/Manufacture.c', + 'tpm2/Marshal.c', + 'tpm2/MathOnByteBuffers.c', + 'tpm2/Memory.c', + 'tpm2/NVCommands.c', + 'tpm2/NVMem.c', + 'tpm2/NV_spt.c', + 'tpm2/NvDynamic.c', + 'tpm2/NvReserved.c', + 'tpm2/Object.c', + 'tpm2/ObjectCommands.c', + 'tpm2/Object_spt.c', + 'tpm2/PCR.c', + 'tpm2/PP.c', + 'tpm2/PPPlat.c', + 'tpm2/PlatformACT.c', + 'tpm2/PlatformData.c', + 'tpm2/PlatformPCR.c', + 'tpm2/Policy_spt.c', + 'tpm2/Power.c', + 'tpm2/PowerPlat.c', + 'tpm2/PrimeData.c', + 'tpm2/PropertyCap.c', + 'tpm2/RandomCommands.c', + 'tpm2/Response.c', + 'tpm2/ResponseCodeProcessing.c', + 'tpm2/RunCommand.c', + 'tpm2/Session.c', + 'tpm2/SessionCommands.c', + 'tpm2/SessionProcess.c', + 'tpm2/SigningCommands.c', + 'tpm2/StartupCommands.c', + 'tpm2/SymmetricCommands.c', + 'tpm2/TPMCmdp.c', + 'tpm2/TestingCommands.c', + 'tpm2/Ticket.c', + 'tpm2/Time.c', + 'tpm2/TpmASN1.c', + 'tpm2/TpmBigNumThunks.c', + 'tpm2/TpmEcc_Signature_ECDAA.c', + 'tpm2/TpmEcc_Signature_ECDSA.c', + 'tpm2/TpmEcc_Signature_SM2.c', + 'tpm2/TpmEcc_Signature_Schnorr.c', + 'tpm2/TpmEcc_Signature_Util.c', + 'tpm2/TpmEcc_Util.c', + 'tpm2/TpmFail.c', + 'tpm2/TpmMath_Debug.c', + 'tpm2/TpmMath_Util.c', + 'tpm2/TpmSizeChecks.c', + 'tpm2/Unique.c', + 'tpm2/Unmarshal.c', + 'tpm2/VendorInfo.c', + 'tpm2/Vendor_TCG_Test.c', + 'tpm2/X509_ECC.c', + 'tpm2/X509_RSA.c', + 'tpm2/X509_spt.c', + 'tpm2/crypto/openssl/BnToOsslMath.c', + 'tpm2/crypto/openssl/CryptCmac.c', + 'tpm2/crypto/openssl/CryptDes.c', + 'tpm2/crypto/openssl/CryptEccCrypt.c', + 'tpm2/crypto/openssl/CryptEccKeyExchange.c', + 'tpm2/crypto/openssl/CryptEccMain.c', + 'tpm2/crypto/openssl/CryptEccSignature.c', + 'tpm2/crypto/openssl/CryptHash.c', + 'tpm2/crypto/openssl/CryptPrime.c', + 'tpm2/crypto/openssl/CryptPrimeSieve.c', + 'tpm2/crypto/openssl/CryptRand.c', + 'tpm2/crypto/openssl/CryptRsa.c', + 'tpm2/crypto/openssl/CryptSmac.c', + 'tpm2/crypto/openssl/CryptSym.c', + 'tpm2/crypto/openssl/ExpDCache.c', + 'tpm2/crypto/openssl/Helpers.c', + 'tpm2/crypto/openssl/TpmToOsslDesSupport.c', + 'tpm2/crypto/openssl/TpmToOsslSupport.c', + 'tpm_tpm2_interface.c', + 'tpm_tpm2_tis.c', + ) + + # files specific to libtpms + tpm2_sources += files( + 'tpm2/BackwardsCompatibilityBitArray.c', + 'tpm2/BackwardsCompatibilityObject.c', + 'tpm2/LibtpmsCallbacks.c', + 'tpm2/NVMarshal.c', + 'tpm2/RuntimeAlgorithm.c', + 'tpm2/RuntimeAttributes.c', + 'tpm2/RuntimeCommands.c', + 'tpm2/RuntimeProfile.c', + 'tpm2/StateMarshal.c', 'tpm2/Volatile.c', - 'tpm2/crypto/openssl/BnToOsslMath.c', 'tpm2/crypto/openssl/CryptCmac.c', - 'tpm2/crypto/openssl/CryptDes.c', 'tpm2/crypto/openssl/CryptEccCrypt.c', - 'tpm2/crypto/openssl/CryptEccKeyExchange.c', 'tpm2/crypto/openssl/CryptEccMain.c', - 'tpm2/crypto/openssl/CryptEccSignature.c', 'tpm2/crypto/openssl/CryptHash.c', - 'tpm2/crypto/openssl/CryptPrime.c', 'tpm2/crypto/openssl/CryptPrimeSieve.c', - 'tpm2/crypto/openssl/CryptRand.c', 'tpm2/crypto/openssl/CryptRsa.c', - 'tpm2/crypto/openssl/CryptSmac.c', 'tpm2/crypto/openssl/CryptSym.c', - 'tpm2/crypto/openssl/ExpDCache.c', 'tpm2/crypto/openssl/Helpers.c', - 'tpm2/crypto/openssl/TpmToOsslDesSupport.c', 'tpm2/crypto/openssl/TpmToOsslSupport.c' ) tpm2_lib = static_library('tpms_tpm2', tpm2_sources,