diff --git a/framework b/framework
index 59d77ef0528..0bfaf0ed972 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit 59d77ef0528f368b7c8cc39870fef6adab5241db
+Subproject commit 0bfaf0ed9721b3858e8982698c618ee748b21a7d
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index e40482a99a4..7b7ff49f5aa 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -68,6 +68,11 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
+/* For the sake of consistency checks in mbedtls_config.c */
+#if defined(MBEDTLS_INCLUDE_AFTER_RAW_CONFIG)
+#include MBEDTLS_INCLUDE_AFTER_RAW_CONFIG
+#endif
+
/* Indicate that all configuration files have been read.
* It is now time to adjust the configuration (follow through on dependencies,
* make PSA and legacy crypto consistent, etc.).
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 063703bfe8c..6c2b6bb0e6e 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -118,6 +118,13 @@ if(GEN_FILES)
${CMAKE_CURRENT_BINARY_DIR}/ssl_debug_helpers_generated.c
${CMAKE_CURRENT_BINARY_DIR}/version_features.c
)
+
+ # List generated headers as sources explicitly. Normally CMake finds
+ # headers by tracing include directives, but if that happens before the
+ # generated headers are generated, this process doesn't find them.
+ list(APPEND src_x509
+ ${MBEDTLS_GENERATED_CONFIG_CHECKS_HEADERS}
+ )
endif()
if(CMAKE_COMPILER_IS_GNUCC)
@@ -237,7 +244,9 @@ foreach(target IN LISTS target_libraries)
$
PRIVATE ${MBEDTLS_DIR}/library/
${MBEDTLS_DIR}/tf-psa-crypto/core
- ${MBEDTLS_DIR}/tf-psa-crypto/drivers/builtin/src)
+ ${MBEDTLS_DIR}/tf-psa-crypto/drivers/builtin/src
+ # needed for generated headers
+ ${CMAKE_CURRENT_BINARY_DIR})
set_config_files_compile_definitions(${target})
install(
TARGETS ${target}
diff --git a/library/Makefile b/library/Makefile
index a0b6d6eb1d3..9085ab481c6 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -346,6 +346,8 @@ $(GENERATED_CONFIG_CHECK_FILES):
echo " Gen $(GENERATED_CONFIG_CHECK_FILES)"
$(PYTHON) ../scripts/generate_config_checks.py
+mbedtls_config.o: $(GENERATED_CONFIG_CHECK_FILES)
+
TF_PSA_CRYPTO_GENERATED_CONFIG_CHECK_FILES = $(shell $(PYTHON) \
$(TF_PSA_CRYPTO_CORE_PATH)/../scripts/generate_config_checks.py \
--list $(TF_PSA_CRYPTO_CORE_PATH))
diff --git a/library/mbedtls_config.c b/library/mbedtls_config.c
index 679f8e36f9a..a3deae31526 100644
--- a/library/mbedtls_config.c
+++ b/library/mbedtls_config.c
@@ -6,8 +6,29 @@
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
+/* Apply the TF-PSA-Crypto configuration first. We need to do this
+ * before , because "mbedtls_config_check_before.h"
+ * needs to run after the crypto config (including derived macros) is
+ * finalized, but before the user's mbedtls config is applied. This way
+ * it is possible to differentiate macros set by the user's mbedtls config
+ * from macros set or derived by the crypto config. */
+#include
+
+/* Consistency checks on the user's configuration.
+ * Check that it doesn't define macros that we assume are under full
+ * control of the library, or options from past major versions that
+ * no longer have any effect.
+ * These headers are automatically generated. See
+ * framework/scripts/mbedtls_framework/config_checks_generator.py
+ */
+#include "mbedtls_config_check_before.h"
+#define MBEDTLS_INCLUDE_AFTER_RAW_CONFIG "mbedtls_config_check_user.h"
+
#include
/* Consistency checks in the configuration: check for incompatible options,
* missing options when at least one of a set needs to be enabled, etc. */
+/* Manually written checks */
#include "mbedtls_check_config.h"
+/* Automatically generated checks */
+#include "mbedtls_config_check_final.h"
diff --git a/scripts/generate_config_checks.py b/scripts/generate_config_checks.py
index b0dc26b1916..bae93c36628 100755
--- a/scripts/generate_config_checks.py
+++ b/scripts/generate_config_checks.py
@@ -3,18 +3,50 @@
"""Generate C preprocessor code to check for bad configurations.
"""
+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
+
+class CryptoInternal(SubprojectInternal):
+ SUBPROJECT = 'TF-PSA-Crypto'
+
+class CryptoOption(SubprojectOption):
+ SUBPROJECT = 'psa/crypto_config.h'
+
+ALWAYS_ENABLED_SINCE_4_0 = frozenset([
+ 'MBEDTLS_PSA_CRYPTO_CONFIG',
+ 'MBEDTLS_USE_PSA_CRYPTO',
+])
+
+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')
+ for option in sorted(old_public - new_public):
+ if option in ALWAYS_ENABLED_SINCE_4_0:
+ continue
+ if option in crypto_public:
+ yield CryptoOption(option)
+ elif option in crypto_internal:
+ yield CryptoInternal(option)
+ else:
+ yield Removed(option, 'Mbed TLS 4.0')
+
+def all_checkers() -> Iterator[Checker]:
+ """Yield all checkers."""
+ yield from checkers_for_removed_options()
MBEDTLS_CHECKS = BranchData(
header_directory='library',
header_prefix='mbedtls_',
project_cpp_prefix='MBEDTLS',
- checkers=[
- Removed('MBEDTLS_KEY_EXCHANGE_RSA_ENABLED', 'Mbed TLS 4.0'),
- Removed('MBEDTLS_PADLOCK_C', 'Mbed TLS 4.0'),
- ],
+ checkers=list(all_checkers()),
)
if __name__ == '__main__':
diff --git a/tests/scripts/test_config_checks.py b/tests/scripts/test_config_checks.py
index 7403f7ebdbe..2c6f6b3c816 100755
--- a/tests/scripts/test_config_checks.py
+++ b/tests/scripts/test_config_checks.py
@@ -22,12 +22,27 @@ class MbedtlsTestConfigChecks(unittest_config_checks.TestConfigChecks):
'tf-psa-crypto/drivers/builtin/include',
]
+ ## Method naming convention:
+ ## * test_crypto_xxx when testing a tweak of crypto_config.h
+ ## * test_mbedtls_xxx when testing a tweak of mbedtls_config.h
+
+ def test_crypto_config_read(self) -> None:
+ """Check that crypto_config.h is read in mbedtls."""
+ self.bad_case('#error witness',
+ None,
+ error='witness')
+
+ def test_mbedtls_config_read(self) -> None:
+ """Check that mbedtls_config.h is read in mbedtls."""
+ self.bad_case(''
+ '#error witness',
+ error='witness')
+
@unittest.skip("At this time, mbedtls does not go through crypto's check_config.h.")
- def test_crypto_no_fs_io(self) -> None:
+ def test_crypto_undef_MBEDTLS_FS_IO(self) -> None:
"""A sample error expected from crypto's check_config.h."""
self.bad_case('#undef MBEDTLS_FS_IO',
- None,
- error=('MBEDTLS_PSA_ITS_FILE_C'))
+ error='MBEDTLS_PSA_ITS_FILE_C')
def test_mbedtls_no_session_tickets_for_early_data(self) -> None:
"""An error expected from mbedtls_check_config.h based on the TLS configuration."""
@@ -36,9 +51,9 @@ def test_mbedtls_no_session_tickets_for_early_data(self) -> None:
#define MBEDTLS_SSL_EARLY_DATA
#undef MBEDTLS_SSL_SESSION_TICKETS
''',
- error=('MBEDTLS_SSL_EARLY_DATA'))
+ error='MBEDTLS_SSL_EARLY_DATA')
- def test_mbedtls_no_ecdsa(self) -> None:
+ def test_crypto_mbedtls_no_ecdsa(self) -> None:
"""An error expected from mbedtls_check_config.h based on crypto+TLS configuration."""
self.bad_case('''
#undef PSA_WANT_ALG_ECDSA
@@ -52,7 +67,75 @@ def test_mbedtls_no_ecdsa(self) -> None:
#error PSA_WANT_ALG_DETERMINSTIC_ECDSA unexpected
#endif
''',
- error=('MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED'))
+ error='MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED')
+
+ def test_crypto_define_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED(self) -> None:
+ """Error when setting a removed option via crypto_config.h."""
+ self.bad_case('#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED',
+ error='MBEDTLS_KEY_EXCHANGE_RSA_ENABLED was removed')
+
+ def test_mbedtls_define_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED(self) -> None:
+ """Error when setting a removed option via mbedtls_config.h."""
+ self.bad_case(None,
+ '#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED',
+ error='MBEDTLS_KEY_EXCHANGE_RSA_ENABLED was removed')
+
+ def test_crypto_exempt_define_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED(self) -> None:
+ """Bypassed error when setting a removed option via crypto_config.h."""
+ self.good_case('#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED',
+ extra_options=['-DMBEDTLS_CONFIG_CHECK_BYPASS'])
+
+ def test_mbedtls_exempt_define_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED(self) -> None:
+ """Bypassed error when setting a removed option via mbedtls_config.h."""
+ self.good_case(None,
+ '#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED',
+ extra_options=['-DMBEDTLS_CONFIG_CHECK_BYPASS'])
+
+ def test_mbedtls_define_MBEDTLS_MD5_C_redundant(self) -> None:
+ """Error when redundantly setting a subproject internal option."""
+ self.bad_case('#define PSA_WANT_ALG_MD5 1',
+ '#define MBEDTLS_MD5_C',
+ error=r'MBEDTLS_MD5_C is an internal macro')
+
+ def test_mbedtls_define_MBEDTLS_MD5_C_added(self) -> None:
+ """Error when setting a subproject internal option that was disabled."""
+ self.bad_case('''
+ #undef PSA_WANT_ALG_MD5
+ #undef MBEDTLS_MD5_C
+ ''',
+ '#define MBEDTLS_MD5_C',
+ error=r'MBEDTLS_MD5_C is an internal macro')
+
+ def test_mbedtls_define_MBEDTLS_BASE64_C_redundant(self) -> None:
+ """Ok to redundantly set a subproject option."""
+ self.good_case(None,
+ '#define MBEDTLS_BASE64_C')
+
+ def test_mbedtls_define_MBEDTLS_BASE64_C_added(self) -> None:
+ """Error when setting a subproject option that was disabled."""
+ self.bad_case('''
+ #undef MBEDTLS_BASE64_C
+ #undef MBEDTLS_PEM_PARSE_C
+ #undef MBEDTLS_PEM_WRITE_C
+ ''',
+ '#define MBEDTLS_BASE64_C',
+ error=r'MBEDTLS_BASE64_C .*psa/crypto_config\.h')
+
+ @unittest.skip("Checks for #undef are not implemented yet.")
+ def test_mbedtls_define_MBEDTLS_BASE64_C_unset(self) -> None:
+ """Error when unsetting a subproject option that was enabled."""
+ self.bad_case(None,
+ '#undef MBEDTLS_BASE64_C',
+ error=r'MBEDTLS_BASE64_C .*psa/crypto_config\.h')
+
+ def test_crypto_define_MBEDTLS_USE_PSA_CRYPTO(self) -> None:
+ """It's ok to set MBEDTLS_USE_PSA_CRYPTO (now effectively always on)."""
+ self.good_case('#define MBEDTLS_USE_PSA_CRYPTO')
+
+ def test_mbedtls_define_MBEDTLS_USE_PSA_CRYPTO(self) -> None:
+ """It's ok to set MBEDTLS_USE_PSA_CRYPTO (now effectively always on)."""
+ self.good_case(None,
+ '#define MBEDTLS_USE_PSA_CRYPTO')
if __name__ == '__main__':