From 262d9cab424718624e5326686edfb48647c9bf3c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 23 Dec 2025 12:33:13 +0100 Subject: [PATCH 1/9] Update framework with config_macros.py Signed-off-by: Gilles Peskine --- framework | 2 +- tf-psa-crypto | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/framework b/framework index 5ef7e74c53..77f707a557 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 5ef7e74c537193912a31e1e03b56261116578896 +Subproject commit 77f707a5576c5bdd1ff9463c7b25d2488497f57e diff --git a/tf-psa-crypto b/tf-psa-crypto index 85af1a8fdc..ae74d3276a 160000 --- a/tf-psa-crypto +++ b/tf-psa-crypto @@ -1 +1 @@ -Subproject commit 85af1a8fdc7b1caa85d99380c1607c3ec11bf87d +Subproject commit ae74d3276a75c2419ee51621150006bd8fd3883c From 35821e7c77ef00c3b9f53dc09844ba6ef7fd98f3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 23 Dec 2025 12:44:59 +0100 Subject: [PATCH 2/9] Switch from config_history to config_macros Switch from the `config_history` module to the new module `config_macros`. No behavior change. Signed-off-by: Gilles Peskine --- scripts/generate_config_checks.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/generate_config_checks.py b/scripts/generate_config_checks.py index bae93c3662..bf8889f32b 100755 --- a/scripts/generate_config_checks.py +++ b/scripts/generate_config_checks.py @@ -8,7 +8,7 @@ from typing import Iterator import framework_scripts_path # pylint: disable=unused-import from mbedtls_framework.config_checks_generator import * \ #pylint: disable=wildcard-import,unused-wildcard-import -from mbedtls_framework import config_history +from mbedtls_framework import config_macros class CryptoInternal(SubprojectInternal): SUBPROJECT = 'TF-PSA-Crypto' @@ -23,17 +23,17 @@ ALWAYS_ENABLED_SINCE_4_0 = frozenset([ def checkers_for_removed_options() -> Iterator[Checker]: """Discover removed options. Yield corresponding checkers.""" - history = config_history.ConfigHistory() - old_public = history.options('mbedtls', '3.6') - new_public = history.options('mbedtls', '4.0') - crypto_public = history.options('tfpsacrypto', '1.0') - crypto_internal = history.internal('tfpsacrypto', '1.0') + previous_major = config_macros.History('mbedtls', '3.6') + this_major = config_macros.History('mbedtls', '4.0') + old_public = previous_major.options() + new_public = this_major.options() + crypto = config_macros.History('tfpsacrypto', '1.0') for option in sorted(old_public - new_public): if option in ALWAYS_ENABLED_SINCE_4_0: continue - if option in crypto_public: + if option in crypto.options(): yield CryptoOption(option) - elif option in crypto_internal: + elif option in crypto.internal(): yield CryptoInternal(option) else: yield Removed(option, 'Mbed TLS 4.0') From 30323afa6ccfe8b8bf6e92a6b28efb7dcdafdf36 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 23 Dec 2025 13:44:22 +0100 Subject: [PATCH 3/9] Read current data rather than data about 4.0 It doesn't matter how a macro was used in a previous minor version of the library. What matters is current information about options and internal symbols, and information about past versions from which a macro may have been removed. The output is mostly the same, but: * Macros that were options in 3.6, became internal in 4.0 and have now been completely removed are now shown as removed, not internal. * Macros that were options in 3.6, were completely removed in 4.0, and are now back but internal, are now shown as internal, not removed. * Macros that were options in 3.6, were removed in 4.0 and are back to being options are no longer rejected. * Macros that were options in 3.6, were removed in 4.0 and are back to being internal derived macros in TF-PSA-Crypto are no longer rejected. Signed-off-by: Gilles Peskine --- scripts/generate_config_checks.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/generate_config_checks.py b/scripts/generate_config_checks.py index bf8889f32b..2e9faa6714 100755 --- a/scripts/generate_config_checks.py +++ b/scripts/generate_config_checks.py @@ -24,10 +24,10 @@ ALWAYS_ENABLED_SINCE_4_0 = frozenset([ def checkers_for_removed_options() -> Iterator[Checker]: """Discover removed options. Yield corresponding checkers.""" previous_major = config_macros.History('mbedtls', '3.6') - this_major = config_macros.History('mbedtls', '4.0') + current = config_macros.Current() + crypto = config_macros.Current('tf-psa-crypto') old_public = previous_major.options() - new_public = this_major.options() - crypto = config_macros.History('tfpsacrypto', '1.0') + new_public = current.options() for option in sorted(old_public - new_public): if option in ALWAYS_ENABLED_SINCE_4_0: continue From 1de879c6dd089ef5a8df4d88fc590e52c41e74fd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 23 Dec 2025 13:50:23 +0100 Subject: [PATCH 4/9] Also reject internal macros that weren't options in 3.6 Signed-off-by: Gilles Peskine --- scripts/generate_config_checks.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/generate_config_checks.py b/scripts/generate_config_checks.py index 2e9faa6714..0f55936c8c 100755 --- a/scripts/generate_config_checks.py +++ b/scripts/generate_config_checks.py @@ -37,6 +37,9 @@ def checkers_for_removed_options() -> Iterator[Checker]: yield CryptoInternal(option) else: yield Removed(option, 'Mbed TLS 4.0') + for option in (current.internal() - new_public - old_public - + crypto.options() - crypto.internal()): + yield Internal(option) def all_checkers() -> Iterator[Checker]: """Yield all checkers.""" From 0e2eb22145fceef8347d9f7d769df7972ff73225 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 30 Dec 2025 15:34:05 +0100 Subject: [PATCH 5/9] New script to check or update config-options-current.txt This script may be generalized to check other files that need lists of current options. But for now, the script just checks `scripts/data_files/config-options-current.txt`. This script is identical to the file in crypto. If the file grows to support multiple targets, we'll probably want to split it, with a generic part in the framework and a project-specific part (probably little more than the list of targets) in each project. But for now the file is too simple to split. Signed-off-by: Gilles Peskine --- tests/scripts/check_option_lists.py | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 tests/scripts/check_option_lists.py diff --git a/tests/scripts/check_option_lists.py b/tests/scripts/check_option_lists.py new file mode 100755 index 0000000000..dcf5c3a74d --- /dev/null +++ b/tests/scripts/check_option_lists.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +""" +Check that files with lists of config options are up-to-date, or update them. + +This script checks the following file: +scripts/data_files/config-options-current.txt +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import argparse +import sys + +import scripts_path # pylint: disable=unused-import +from mbedtls_framework import config_macros + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + # For now this script only acts on one target file. + # If we check/update more files, we should add a way to select which + # file(s) to operate on. + parser.add_argument('--always-update', '-U', + action='store_true', + help=('Update target files unconditionally ' + '(overrides --update)')) + parser.add_argument('--update', '-u', + action='store_true', + help='Update target files if needed') + args = parser.parse_args() + data = config_macros.Current(shadow_missing_ok=True) + if args.update or args.always_update: + data.update_shadow_file(args.always_update) + else: + up_to_date = True + up_to_date &= data.compare_shadow_file_verbosely() + sys.exit(0 if up_to_date else 1) + +if __name__ == "__main__": + main() From 43784b54cd3c977351abebe7528b0672ae931272 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 30 Dec 2025 15:49:43 +0100 Subject: [PATCH 6/9] Create the config option list shadow file ``` tests/scripts/check_option_lists.py -u ``` Signed-off-by: Gilles Peskine --- scripts/data_files/config-options-current.txt | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 scripts/data_files/config-options-current.txt diff --git a/scripts/data_files/config-options-current.txt b/scripts/data_files/config-options-current.txt new file mode 100644 index 0000000000..81b233804c --- /dev/null +++ b/scripts/data_files/config-options-current.txt @@ -0,0 +1,79 @@ +MBEDTLS_CONFIG_FILE +MBEDTLS_CONFIG_VERSION +MBEDTLS_DEBUG_C +MBEDTLS_ERROR_C +MBEDTLS_ERROR_STRERROR_DUMMY +MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED +MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +MBEDTLS_KEY_EXCHANGE_PSK_ENABLED +MBEDTLS_NET_C +MBEDTLS_PKCS7_C +MBEDTLS_PSK_MAX_LEN +MBEDTLS_SSL_ALL_ALERT_MESSAGES +MBEDTLS_SSL_ALPN +MBEDTLS_SSL_ASYNC_PRIVATE +MBEDTLS_SSL_CACHE_C +MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES +MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT +MBEDTLS_SSL_CID_IN_LEN_MAX +MBEDTLS_SSL_CID_OUT_LEN_MAX +MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY +MBEDTLS_SSL_CIPHERSUITES +MBEDTLS_SSL_CLI_C +MBEDTLS_SSL_CONTEXT_SERIALIZATION +MBEDTLS_SSL_COOKIE_C +MBEDTLS_SSL_COOKIE_TIMEOUT +MBEDTLS_SSL_DEBUG_ALL +MBEDTLS_SSL_DTLS_ANTI_REPLAY +MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE +MBEDTLS_SSL_DTLS_CONNECTION_ID +MBEDTLS_SSL_DTLS_HELLO_VERIFY +MBEDTLS_SSL_DTLS_MAX_BUFFERING +MBEDTLS_SSL_DTLS_SRTP +MBEDTLS_SSL_EARLY_DATA +MBEDTLS_SSL_ENCRYPT_THEN_MAC +MBEDTLS_SSL_EXTENDED_MASTER_SECRET +MBEDTLS_SSL_IN_CONTENT_LEN +MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +MBEDTLS_SSL_KEYING_MATERIAL_EXPORT +MBEDTLS_SSL_MAX_EARLY_DATA_SIZE +MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +MBEDTLS_SSL_NULL_CIPHERSUITES +MBEDTLS_SSL_OUT_CONTENT_LEN +MBEDTLS_SSL_PROTO_DTLS +MBEDTLS_SSL_PROTO_TLS1_2 +MBEDTLS_SSL_PROTO_TLS1_3 +MBEDTLS_SSL_RECORD_SIZE_LIMIT +MBEDTLS_SSL_RENEGOTIATION +MBEDTLS_SSL_SERVER_NAME_INDICATION +MBEDTLS_SSL_SESSION_TICKETS +MBEDTLS_SSL_SRV_C +MBEDTLS_SSL_TICKET_C +MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS +MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE +MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH +MBEDTLS_SSL_TLS_C +MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH +MBEDTLS_TIMING_ALT +MBEDTLS_TIMING_C +MBEDTLS_USER_CONFIG_FILE +MBEDTLS_VERSION_C +MBEDTLS_VERSION_FEATURES +MBEDTLS_X509_CREATE_C +MBEDTLS_X509_CRL_PARSE_C +MBEDTLS_X509_CRT_PARSE_C +MBEDTLS_X509_CRT_WRITE_C +MBEDTLS_X509_CSR_PARSE_C +MBEDTLS_X509_CSR_WRITE_C +MBEDTLS_X509_MAX_FILE_PATH_LEN +MBEDTLS_X509_MAX_INTERMEDIATE_CA +MBEDTLS_X509_REMOVE_INFO +MBEDTLS_X509_RSASSA_PSS_SUPPORT +MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK +MBEDTLS_X509_USE_C From 93ef003cdc2b5bdeea803dff471a2a6189beba49 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 30 Dec 2025 15:52:43 +0100 Subject: [PATCH 7/9] Check that the config option list shadow file is up to date Test that `scripts/data_files/config-options-current.txt` is up-to-date. This file needs to change every time we add or remove a config option. Signed-off-by: Gilles Peskine --- tests/scripts/components-basic-checks.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/scripts/components-basic-checks.sh b/tests/scripts/components-basic-checks.sh index e791ad065c..199396df30 100644 --- a/tests/scripts/components-basic-checks.sh +++ b/tests/scripts/components-basic-checks.sh @@ -46,6 +46,9 @@ component_check_generated_files () { # This component ends with the generated files present in the source tree. # This is necessary for subsequent components! + + msg "Check committed generated files" + tests/scripts/check_option_lists.py } component_check_doxy_blocks () { From b6c30c36393e0981436cd80e55a649baeb9862b4 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 2 Jan 2026 22:23:28 +0100 Subject: [PATCH 8/9] Print a useful message when the file is out of date Don't print the differences: interested users can just run `git diff` (or save the old file and run `comm`). Signed-off-by: Gilles Peskine --- tests/scripts/check_option_lists.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/scripts/check_option_lists.py b/tests/scripts/check_option_lists.py index dcf5c3a74d..7ce55c1da9 100755 --- a/tests/scripts/check_option_lists.py +++ b/tests/scripts/check_option_lists.py @@ -35,7 +35,11 @@ def main(): data.update_shadow_file(args.always_update) else: up_to_date = True - up_to_date &= data.compare_shadow_file_verbosely() + if not data.is_shadow_file_up_to_date(): + print(f'{data.shadow_file_path()} is out of date') + print(f'After adding or removing a conifg option, you need to run') + print(f'{sys.argv[0]} and commit the result.') + up_to_date = False sys.exit(0 if up_to_date else 1) if __name__ == "__main__": From 168c6ec50ce8e606a7dc8d421189e59ab610c991 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 5 Jan 2026 09:45:07 +0100 Subject: [PATCH 9/9] Improve out-of-date message Signed-off-by: Gilles Peskine --- tests/scripts/check_option_lists.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/check_option_lists.py b/tests/scripts/check_option_lists.py index 7ce55c1da9..c9b643bb6d 100755 --- a/tests/scripts/check_option_lists.py +++ b/tests/scripts/check_option_lists.py @@ -37,8 +37,8 @@ def main(): up_to_date = True if not data.is_shadow_file_up_to_date(): print(f'{data.shadow_file_path()} is out of date') - print(f'After adding or removing a conifg option, you need to run') - print(f'{sys.argv[0]} and commit the result.') + print(f'After adding or removing a config option, you need to run') + print(f'{sys.argv[0]} -u and commit the result.') up_to_date = False sys.exit(0 if up_to_date else 1)