Skip to content

Add run-time check of app vs. library build configuration - #11954

Open
SparkiDev wants to merge 1 commit into
wolfSSL:masterfrom
SparkiDev:build_config_api
Open

SparkiDev wants to merge 1 commit into
wolfSSL:masterfrom
SparkiDev:build_config_api

Conversation

@SparkiDev

@SparkiDev SparkiDev commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Description

An application compiled with different feature macros from the wolfSSL library it loads compiles cleanly and then corrupts memory, because struct layouts and available APIs differ. Comparing version numbers does not catch a different configuration of the same version.

Add wolfssl/wolfcrypt/build_check.h. An application calls wc_CheckBuildConfig(), or wc_CheckBuildConfigEx() for a readable list of differences, before wolfSSL_Init(). It compares the application's compile-time view with the library's:

  • the library version;
  • 183 ABI-affecting macros as feature bits;
  • sizeof() of 64 public structs, including the OpenSSL compatibility layer's EVP/SHA/HMAC contexts;
  • a hash of options.h, when both sides have one.

The list of macros and structs is in build_check_list.h. It is expanded as an X-macro list into the header-side fill function, the library's name table and the unit test. Slots and bits are append-only, and the struct is versioned, so a newer library accepts an older application's struct.

New exported APIs: wc_GetBuildConfig(), wc_CompareBuildConfig(), wc_BuildConfigMismatchString(), wc_BuildConfigFeatureName() and wc_BuildConfigSizeName(). They are also exported from the Linux kernel module. A mismatch returns the new error
BUILD_CONFIG_MISMATCH_E (-1043) and a bitmask of what differed. Everything is gated on HAVE_WC_INTROSPECTION.

Build system:

  • configure writes WOLFSSL_OPTIONS_HASH (a CRC of options.h) into options.h and .build_params.
  • CMake writes a SHA-256 prefix and gains the WOLFSSL_INTROSPECTION option, on by default, which defines HAVE_WC_INTROSPECTION.
  • Neither writes a hash for user_settings.h builds.

asn.h defines WC_DECODEDCERT_DEFINED. When openssl/obj_mac.h is included first, the DecodedCert slots record WC_BUILD_SIZE_UNKNOWN, and the comparison skips them.

Fix an undefined reference to sp_zero() when linking an opensslextra build with neither RSA nor ECC; the BIGNUM compat functions call it.

CI: the new build-config-check.yml workflow

  • checks that build_check_list.h covers every public struct whose layout depends on the configuration (.github/scripts/check-build-config-list.py);
  • builds two differently configured libraries and checks that an application detects and names the differences (.github/scripts/build-config-mismatch.sh).

Testing

Tested with different configuration with configure and CMake and user_settings.h.

@SparkiDev SparkiDev self-assigned this Nov 2, 2026
Copilot AI balanced review requested due to automatic review settings November 2, 2026 08:11
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

MemBrowse Memory Report · Explore what changed →

gcc-arm-cortex-m4

  • FLASH: .rodata.CSWTCH.2 +4 B, .rodata.str1.1 +58 B (+0.0%, 208,686 B / 262,144 B, total: 80% used)

gcc-arm-cortex-m4-crypto-only

  • FLASH: .rodata.CSWTCH.2 +4 B, .rodata.str1.1 +58 B (+0.0%, 181,713 B / 262,144 B, total: 69% used)

gcc-arm-cortex-m4-openssl-compat

  • FLASH: .rodata +56 B (+0.0%, 797,364 B / 1,048,576 B, total: 76% used)

gcc-arm-cortex-m4-pkcs7

  • FLASH: .rodata.CSWTCH.2 +4 B, .rodata.str1.1 +58 B (+0.0%, 222,866 B / 262,144 B, total: 85% used)

gcc-arm-cortex-m4-pq

  • FLASH: .rodata +60 B (+0.0%, 312,076 B / 1,048,576 B, total: 30% used)

gcc-arm-cortex-m4-rsa-only

  • FLASH: .rodata +56 B (+0.0%, 342,656 B / 1,048,576 B, total: 33% used)

gcc-arm-cortex-m4-tls13

  • FLASH: .rodata.CSWTCH.2 +4 B, .rodata.str1.1 +58 B (+0.0%, 248,992 B / 262,144 B, total: 95% used)

gcc-arm-cortex-m7

  • FLASH: .rodata.CSWTCH.2 +4 B, .rodata.str1.1 +58 B (+0.0%, 208,686 B / 262,144 B, total: 80% used)

gcc-arm-cortex-m7-pq

  • FLASH: .rodata +60 B (+0.0%, 312,908 B / 1,048,576 B, total: 30% used)

gcc-arm-cortex-m7-tls13

  • FLASH: .rodata.CSWTCH.2 +4 B, .rodata.str1.1 +58 B (+0.0%, 248,992 B / 262,144 B, total: 95% used)

stm32-sim-stm32h753

  • FLASH: .text +64 B (+0.0%, 204,652 B / 2,097,152 B, total: 10% used)

zephyr-frdm_rw612

  • FLASH: log_const_area -8 B, rodata -8 B, text +1,584 B (+0.6%, 284,032 B / 67,108,864 B, total: 0% used)

No memory changes detected for:


Catch memory regressions in CI with MemBrowse. Free for open source.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical issues allow incompatible caller-allocated layouts to pass verification and let wc_GetBuildConfig() overwrite older callers’ smaller allocations.

7 open issues
What changed in this PR

Adds runtime checks for differences between an application's wolfSSL build configuration and the loaded library, helping detect incompatible layouts before initialization.

Changes:

  • Adds configuration fingerprints, comparison APIs, readable mismatch reports, and a dedicated error code.
  • Integrates options hashes into Autotools and CMake, adds kernel-module exposure, and fixes the OpenSSL compatibility sp_zero() link guard.
  • Adds API tests, cross-configuration CI checks, and integration documentation.
File Description
wolfssl/​wolfcrypt/​include.am Installs the new public headers.
wolfssl/​wolfcrypt/​error-crypt.h Defines the configuration-mismatch error.
wolfssl/​wolfcrypt/​build_check.h Defines fingerprints and application-side check wrappers.
wolfssl/​wolfcrypt/​build_check_list.h Lists feature bits and public-type size slots.
wolfssl/​wolfcrypt/​asn.h Marks availability of the full certificate definition.
wolfcrypt/​src/​sp_int.c Enables sp_zero() for OpenSSL compatibility builds.
wolfcrypt/​src/​logging.c Implements comparison and mismatch-reporting APIs.
wolfcrypt/​src/​error.c Adds the mismatch error string.
tests/​api.c Tests fingerprints, comparisons, names, and buffer handling.
linuxkm/​module_exports.c.template Includes build-check APIs for kernel exports.
doc/​dox_comments/​header_files/​doxygen_pages.h Links the build-check documentation group.
doc/​dox_comments/​header_files/​doxygen_groups.h Defines the build-check documentation group.
doc/​dox_comments/​header_files/​build_check.h Documents APIs and usage examples.
configure.ac Generates and embeds the options hash.
CMakeLists.txt Adds introspection configuration and options hashing.
cmake/​options.h.in Emits introspection and hash definitions.
ChangeLog.md Records the new checks and linking fix.
AGENTS.md Documents runtime verification for integrations.
.github/​workflows/​build-config-check.yml Runs coverage and mismatch checks in CI.
.github/​scripts/​check-build-config-list.py Checks fingerprint coverage of public layouts.
.github/​scripts/​build-config-mismatch.sh Tests applications against differently configured libraries.

Review effort: Balanced

Comment thread wolfssl/wolfcrypt/build_check.h Resolved
Comment thread wolfssl/wolfcrypt/build_check_list.h Resolved
Comment thread wolfssl/wolfcrypt/build_check_list.h Resolved
Comment thread tests/api.c Resolved
Comment thread wolfssl/wolfcrypt/build_check_list.h Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread wolfssl/wolfcrypt/build_check_list.h Resolved
Comment thread wolfssl/wolfcrypt/build_check_list.h Resolved
Comment thread wolfssl/wolfcrypt/build_check_list.h Resolved
Comment thread wolfssl/wolfcrypt/build_check_list.h Resolved
@SparkiDev
SparkiDev force-pushed the build_config_api branch 3 times, most recently from 4f441bf to 1716886 Compare November 3, 2026 00:37
@SparkiDev

Copy link
Copy Markdown
Contributor Author

Jenkins: retest this please

An application compiled with different feature macros from the wolfSSL
library it loads compiles cleanly and then corrupts memory, because
struct layouts and available APIs differ. Comparing version numbers
does not catch a different configuration of the same version.

Add wolfssl/wolfcrypt/build_check.h. An application calls
wc_CheckBuildConfig(), or wc_CheckBuildConfigEx() for a readable list
of differences, before wolfSSL_Init(). It compares the application's
compile-time view with the library's:
- the library version;
- 243 ABI-affecting macros as feature bits;
- sizeof() of 66 public structs, including the OpenSSL compatibility
  layer's EVP/SHA/HMAC contexts, and of void*, long and size_t;
- the math digit width (sizeof(mp_digit)) and radix (DIGIT_BIT);
- a hash of options.h, when both sides have one.

The list of macros and structs is in build_check_list.h. It is
expanded as an X-macro list into the header-side fill function, the
library's name table and the unit test. Slots and bits are
append-only, and the struct is versioned, so a newer library accepts
an older application's struct.

New exported APIs: wc_GetBuildConfig(), wc_CompareBuildConfig(),
wc_BuildConfigMismatchString(), wc_BuildConfigFeatureName() and
wc_BuildConfigSizeName(). They are also exported from the Linux
kernel module. A mismatch returns the new error
BUILD_CONFIG_MISMATCH_E (-1043) and a bitmask of what differed.
Everything is gated on HAVE_WC_INTROSPECTION.

Build system:
- configure writes WOLFSSL_OPTIONS_HASH (a CRC of options.h) into
  options.h and .build_params.
- CMake writes a SHA-256 prefix and gains the WOLFSSL_INTROSPECTION
  option, on by default, which defines HAVE_WC_INTROSPECTION.
- Neither writes a hash for user_settings.h builds.

asn.h defines WC_DECODEDCERT_DEFINED. When openssl/obj_mac.h is
included first, the DecodedCert slots record WC_BUILD_SIZE_UNKNOWN,
and the comparison skips them.

Fix an undefined reference to sp_zero() when linking an opensslextra
build with neither RSA nor ECC; the BIGNUM compat functions call it.

CI: the new build-config-check.yml workflow
- checks that build_check_list.h covers every public struct whose
  layout depends on the configuration
  (.github/scripts/check-build-config-list.py);
- builds two differently configured libraries and checks that an
  application detects and names the differences
  (.github/scripts/build-config-mismatch.sh).
@SparkiDev

Copy link
Copy Markdown
Contributor Author

Jenkins: retest this please

@SparkiDev SparkiDev assigned wolfSSL-Bot and unassigned SparkiDev Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants