Merge pull request #10416 from bensze01/abicheck-worktree-submodules

Use submodule work trees during ABI check
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 12ddc27..659fd50 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,15 +37,20 @@
 # is deprecated and will be removed in future versions.
 cmake_policy(SET CMP0012 NEW)
 
+set(MBEDTLS_VERSION 4.0.0)
+set(MBEDTLS_CRYPTO_SOVERSION 17)
+set(MBEDTLS_X509_SOVERSION 8)
+set(MBEDTLS_TLS_SOVERSION 22)
+
 if(TEST_CPP)
     project("Mbed TLS"
         LANGUAGES C CXX
-        VERSION 4.0.0
+        VERSION ${MBEDTLS_VERSION}
     )
 else()
     project("Mbed TLS"
         LANGUAGES C
-        VERSION 4.0.0
+        VERSION ${MBEDTLS_VERSION}
     )
 endif()
 
diff --git a/ChangeLog.d/replace_time_t.txt b/ChangeLog.d/replace_time_t.txt
new file mode 100644
index 0000000..ec0282a
--- /dev/null
+++ b/ChangeLog.d/replace_time_t.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix a build error or incorrect TLS session
+     lifetime on platforms where mbedtls_time_t
+     is not time_t. Fixes #10236.
diff --git a/docs/4.0-migration-guide/configuration.md b/docs/4.0-migration-guide/configuration.md
new file mode 100644
index 0000000..25bddf4
--- /dev/null
+++ b/docs/4.0-migration-guide/configuration.md
@@ -0,0 +1,44 @@
+## Compile-time configuration
+
+### Configuration file split
+
+All configuration options that are relevant to TF-PSA-Crypto must now be configured in one of its configuration files, namely:
+
+* `TF_PSA_CRYPTO_CONFIG_FILE`, if set on the preprocessor command line;
+* otherwise `<psa/crypto_config.h>`;
+* additionally `TF_PSA_CRYPTO_USER_CONFIG_FILE`, if set.
+
+Configuration options that are relevant to X.509 or TLS should still be set in the Mbed TLS configuration file (`MBEDTLS_CONFIG_FILE` or `<mbedtls/mbedtls_config.h>`, plus `MBEDTLS_USER_CONFIG_FILE` if it is set). However, you can define all options in the crypto configuration, and Mbed TLS will pick them up.
+
+Generally speaking, the options that must be configured in TF-PSA-Crypto are:
+
+* options related to platform settings;
+* options related to the choice of cryptographic mechanisms included in the build;
+* options related to the inner workings of cryptographic mechanisms, such as size/memory/performance compromises;
+* options related to crypto-adjacent features, such as ASN.1 and Base64.
+
+See `include/psa/crypto_config.h` in TF-PSA-Crypto and `include/mbedtls/mbedtls_config.h` in Mbed TLS for details.
+
+Notably, `<psa/crypto_config.h>` is no longer limited to `PSA_WANT_xxx` options.
+
+Note that many options related to cryptography have changed; see the TF-PSA-Crypto migration guide for details.
+
+### Split of `build_info.h` and `version.h`
+
+The header file `<mbedtls/build_info.h>`, which includes the configuration file and provides the adjusted configuration macros, now has an similar file `<tf-psa-crypto/build_info.h>` in TF-PSA-Crypto. The Mbed TLS header includes the TF-PSA-Crypto header, so including `<mbedtls/build_info.h>` remains sufficient to obtain information about the crypto configuration.
+
+TF-PSA-Crypto exposes its version through `<tf-psa-crypto/version.h>`, similar to `<mbedtls/version.h>` in Mbed TLS.
+
+### Removal of `check_config.h`
+
+The header `mbedtls/check_config.h` is no longer present. Including it from user configuration files was already obsolete in Mbed TLS 3.x, since it enforces properties the configuration as adjusted by `mbedtls/build_info.h`, not properties that the user configuration is expected to meet.
+
+### Changes to TLS options
+
+#### Enabling null cipher suites
+
+The option to enable null cipher suites in TLS 1.2 has been renamed from `MBEDTLS_CIPHER_NULL_CIPHER` to `MBEDTLS_SSL_NULL_CIPHERSUITES`. It remains disabled in the default configuration.
+
+#### Removal of backward compatibility options
+
+The option `MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT` has been removed. Only the version standardized in RFC 9146 is supported now.
diff --git a/docs/4.0-migration-guide/feature-removals.md b/docs/4.0-migration-guide/feature-removals.md
index ae611a1..b958f86 100644
--- a/docs/4.0-migration-guide/feature-removals.md
+++ b/docs/4.0-migration-guide/feature-removals.md
@@ -12,6 +12,7 @@
 * RSA (i.e. cipher suites using only RSA decryption: cipher suites using RSA signatures remain supported);
 * DHE-PSK (except in TLS 1.3);
 * DHE-RSA (except in TLS 1.3).
+* static ECDH (ECDH-RSA and ECDH-ECDSA, as opposed to ephemeral ECDH (ECDHE) which remains supported).
 
 The full list of removed cipher suites is:
 
@@ -59,6 +60,36 @@
 TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256
 TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384
 TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256
+TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA
+TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256
+TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256
+TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA
+TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384
+TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384
+TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256
+TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256
+TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384
+TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384
+TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256
+TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256
+TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384
+TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384
+TLS-ECDH-ECDSA-WITH-NULL-SHA
+TLS-ECDH-RSA-WITH-AES-128-CBC-SHA
+TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256
+TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256
+TLS-ECDH-RSA-WITH-AES-256-CBC-SHA
+TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384
+TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384
+TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256
+TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256
+TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384
+TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384
+TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256
+TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256
+TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384
+TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384
+TLS-ECDH-RSA-WITH-NULL-SHA
 TLS-RSA-PSK-WITH-AES-128-CBC-SHA
 TLS-RSA-PSK-WITH-AES-128-CBC-SHA256
 TLS-RSA-PSK-WITH-AES-128-GCM-SHA256
@@ -109,3 +140,13 @@
 mbedtls_ssl_conf_dh_param_ctx()
 mbedtls_ssl_conf_dhm_min_bitlen()
 ```
+
+### Removal of elliptic curves
+
+Following their removal from the crypto library, elliptic curves of less than 250 bits (secp192r1, secp192k1, secp224r1, secp224k1) are no longer supported in certificates and in TLS.
+
+### Removal of deprecated functions
+
+The deprecated functions `mbedtls_ssl_conf_min_version()` and `mbedtls_ssl_conf_max_version()`, and the associated constants `MBEDTLS_SSL_MAJOR_VERSION_3`, `MBEDTLS_SSL_MINOR_VERSION_3` and `MBEDTLS_SSL_MINOR_VERSION_4` have been removed. Use `mbedtls_ssl_conf_min_tls_version()` and `mbedtls_ssl_conf_max_tls_version()` with `MBEDTLS_SSL_VERSION_TLS1_2` or `MBEDTLS_SSL_VERSION_TLS1_3` instead.
+
+The deprecated function `mbedtls_ssl_conf_sig_hashes()` has been removed. Use `mbedtls_ssl_conf_sig_algs()` instead.
diff --git a/framework b/framework
index 59d77ef..0bfaf0e 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 e40482a..7b7ff49 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 063703b..6d8c788 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -107,17 +107,24 @@
             ${tls_error_headers}
     )
 
-    add_custom_target(${MBEDTLS_TARGET_PREFIX}mbedx509_generated_files_target
+    add_custom_target(${MBEDTLS_TARGET_PREFIX}libmbedx509_generated_files_target
         DEPENDS
             ${CMAKE_CURRENT_BINARY_DIR}/error.c
             ${MBEDTLS_GENERATED_CONFIG_CHECKS_HEADERS}
     )
 
-    add_custom_target(${MBEDTLS_TARGET_PREFIX}mbedtls_generated_files_target
+    add_custom_target(${MBEDTLS_TARGET_PREFIX}libmbedtls_generated_files_target
         DEPENDS
             ${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)
@@ -198,9 +205,9 @@
 
     if(GEN_FILES)
         add_dependencies(${mbedx509_static_target}
-            ${MBEDTLS_TARGET_PREFIX}mbedx509_generated_files_target)
+            ${MBEDTLS_TARGET_PREFIX}libmbedx509_generated_files_target)
         add_dependencies(${mbedtls_static_target}
-            ${MBEDTLS_TARGET_PREFIX}mbedtls_generated_files_target)
+            ${MBEDTLS_TARGET_PREFIX}libmbedtls_generated_files_target)
     endif()
 endif(USE_STATIC_MBEDTLS_LIBRARY)
 
@@ -208,20 +215,20 @@
     add_library(${mbedx509_target} SHARED ${src_x509})
     set_base_compile_options(${mbedx509_target})
     target_compile_options(${mbedx509_target} PRIVATE ${LIBS_C_FLAGS})
-    set_target_properties(${mbedx509_target} PROPERTIES VERSION 4.0.0 SOVERSION 8)
+    set_target_properties(${mbedx509_target} PROPERTIES VERSION ${MBEDTLS_VERSION} SOVERSION ${MBEDTLS_X509_SOVERSION})
     target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${tfpsacrypto_target})
 
     add_library(${mbedtls_target} SHARED ${src_tls})
     set_base_compile_options(${mbedtls_target})
     target_compile_options(${mbedtls_target} PRIVATE ${LIBS_C_FLAGS})
-    set_target_properties(${mbedtls_target} PROPERTIES VERSION 4.0.0 SOVERSION 21)
+    set_target_properties(${mbedtls_target} PROPERTIES VERSION ${MBEDTLS_VERSION} SOVERSION ${MBEDTLS_TLS_SOVERSION})
     target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
 
     if(GEN_FILES)
         add_dependencies(${mbedx509_target}
-            ${MBEDTLS_TARGET_PREFIX}mbedx509_generated_files_target)
+            ${MBEDTLS_TARGET_PREFIX}libmbedx509_generated_files_target)
         add_dependencies(${mbedtls_target}
-            ${MBEDTLS_TARGET_PREFIX}mbedtls_generated_files_target)
+            ${MBEDTLS_TARGET_PREFIX}libmbedtls_generated_files_target)
     endif()
 endif(USE_SHARED_MBEDTLS_LIBRARY)
 
@@ -237,7 +244,9 @@
                $<INSTALL_INTERFACE:include/>
         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}
@@ -259,22 +268,109 @@
     get_target_property(target_type ${target} TYPE)
     if (target_type STREQUAL STATIC_LIBRARY)
         add_custom_command(
-            TARGET ${mbedtls_target}
-            POST_BUILD
-            COMMAND ${CMAKE_COMMAND}
-            ARGS -E copy $<TARGET_FILE:${target}> ${CMAKE_BINARY_DIR}/library)
+            TARGET ${mbedtls_target} POST_BUILD
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                    $<TARGET_FILE:${target}>
+                    $<TARGET_FILE_NAME:${target}>
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                    $<TARGET_FILE:${target}>
+                    "libmbedcrypto.a"
+        )
+        install(FILES $<TARGET_FILE:${target}>
+                DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                RENAME "libmbedcrypto.a"
+        )
     else()
+        # Copy the crypto shared library from tf-psa-crypto:
+        # - ".so.<VERSION>" on Unix
+        # - ".dylib" on macOS
+        # - ".dll" on Windows
+        # The full path to the file is given by $<TARGET_FILE:${target}>.
+        #
+        # On systems that use .so versioning, also create the symbolic links
+        # ".so.<SOVERSION>" and ".so", which correspond to
+        # $<TARGET_SONAME_FILE_NAME:${target}> and $<TARGET_LINKER_FILE_NAME:${target}>,
+        # respectively.
+        #
+        # On Windows, also copy the ".lib" file, whose full path is
+        # $<TARGET_LINKER_FILE:${target}>.
+        #
+        # Provide also the crypto libraries under their historical names:
+        # "libmbedcrypto.*"
         add_custom_command(
-            TARGET ${mbedtls_target}
-            POST_BUILD
-            COMMAND ${CMAKE_COMMAND}
-            ARGS -E copy $<TARGET_FILE:${target}>
-            ${CMAKE_BINARY_DIR}/library/$<TARGET_FILE_NAME:${target}>)
-        add_custom_command(
-            TARGET ${mbedtls_target}
-            POST_BUILD
-            COMMAND ${CMAKE_COMMAND}
-            ARGS -E copy $<TARGET_LINKER_FILE:${target}>
-            ${CMAKE_BINARY_DIR}/library/$<TARGET_LINKER_FILE_NAME:${target}>)
+            TARGET ${mbedtls_target} POST_BUILD
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                    $<TARGET_FILE:${target}>
+                    $<TARGET_FILE_NAME:${target}>
+        )
+        if(APPLE)
+            add_custom_command(
+                TARGET ${mbedtls_target} POST_BUILD
+                COMMAND ${CMAKE_COMMAND} -E create_symlink
+                $<TARGET_FILE_NAME:${target}>
+                libmbedcrypto.dylib
+            )
+            install(FILES $<TARGET_FILE:${target}>
+                    DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                    RENAME "libmbedcrypto.dylib"
+            )
+        elseif(WIN32 AND NOT CYGWIN)
+            add_custom_command(
+                TARGET ${mbedtls_target} POST_BUILD
+                COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                        $<TARGET_FILE:${target}>
+                        libmbedcrypto.dll
+            )
+            add_custom_command(
+                TARGET ${mbedtls_target} POST_BUILD
+                COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                        $<TARGET_LINKER_FILE:${target}>
+                        $<TARGET_LINKER_FILE_NAME:${target}>
+                COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                        $<TARGET_LINKER_FILE:${target}>
+                        libmbedcrypto.lib
+            )
+            install(FILES $<TARGET_FILE:${target}>
+                    DESTINATION ${CMAKE_INSTALL_BINDIR}
+                    RENAME "libmbedcrypto.dll"
+            )
+            install(FILES $<TARGET_LINKER_FILE:${target}>
+                    DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                    RENAME "libmbedcrypto.lib"
+            )
+        else()
+            add_custom_command(
+              TARGET ${mbedtls_target} POST_BUILD
+              COMMAND ${CMAKE_COMMAND} -E create_symlink
+                      $<TARGET_FILE_NAME:${target}>
+                      $<TARGET_SONAME_FILE_NAME:${target}>
+              COMMAND ${CMAKE_COMMAND} -E create_symlink
+                      $<TARGET_SONAME_FILE_NAME:${target}>
+                      $<TARGET_LINKER_FILE_NAME:${target}>
+              COMMAND ${CMAKE_COMMAND} -E create_symlink
+                      $<TARGET_FILE_NAME:${target}>
+                      libmbedcrypto.so.${MBEDTLS_VERSION}
+              COMMAND ${CMAKE_COMMAND} -E create_symlink
+                      libmbedcrypto.so.${MBEDTLS_VERSION}
+                      libmbedcrypto.so.${MBEDTLS_CRYPTO_SOVERSION}
+              COMMAND ${CMAKE_COMMAND} -E create_symlink
+                      libmbedcrypto.so.${MBEDTLS_CRYPTO_SOVERSION}
+                      libmbedcrypto.so
+            )
+            install(FILES $<TARGET_FILE:${target}>
+                    DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                    RENAME "libmbedcrypto.so.${MBEDTLS_VERSION}"
+            )
+            install(CODE "
+                set(_libdir \"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\")
+
+                execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E create_symlink
+                                \"libmbedcrypto.so.${MBEDTLS_VERSION}\"
+                                \${_libdir}/libmbedcrypto.so.${MBEDTLS_CRYPTO_SOVERSION})
+                execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E create_symlink
+                                \"libmbedcrypto.so.${MBEDTLS_CRYPTO_SOVERSION}\"
+                                \${_libdir}/libmbedcrypto.so)
+            ")
+        endif()
     endif()
 endforeach(target)
diff --git a/library/Makefile b/library/Makefile
index a0b6d6e..9085ab4 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -346,6 +346,8 @@
 	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 679f8e3..a3deae3 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 <mbedtls/build_info.h>, 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 <tf-psa-crypto/build_info.h>
+
+/* 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 <mbedtls/build_info.h>
 
 /* 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/library/ssl_tls.c b/library/ssl_tls.c
index 37e4259..75c59a9 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3178,7 +3178,7 @@
     start = MBEDTLS_GET_UINT64_BE(p, 0);
     p += 8;
 
-    session->start = (time_t) start;
+    session->start = (mbedtls_time_t) start;
 #endif /* MBEDTLS_HAVE_TIME */
 
     /*
diff --git a/programs/test/cmake_package_install/CMakeLists.txt b/programs/test/cmake_package_install/CMakeLists.txt
index 60a4481..723538f 100644
--- a/programs/test/cmake_package_install/CMakeLists.txt
+++ b/programs/test/cmake_package_install/CMakeLists.txt
@@ -17,6 +17,7 @@
         "-DENABLE_TESTING=NO"
         # Turn on generated files explicitly in case this is a release
         "-DGEN_FILES=ON"
+        "-DUSE_SHARED_MBEDTLS_LIBRARY=ON"
         "-DCMAKE_INSTALL_PREFIX=${MbedTLS_INSTALL_DIR}")
 
 execute_process(
diff --git a/programs/test/dlopen.c b/programs/test/dlopen.c
index 58a6af5..2a67635 100644
--- a/programs/test/dlopen.c
+++ b/programs/test/dlopen.c
@@ -84,13 +84,13 @@
 
 #if defined(MBEDTLS_MD_C)
     const char *crypto_so_filename = NULL;
-    void *crypto_so = dlopen(MBEDCRYPTO_SO_FILENAME, RTLD_NOW);
+    void *crypto_so = dlopen(TFPSACRYPTO_SO_FILENAME, RTLD_NOW);
     if (dlerror() == NULL) {
-        crypto_so_filename = MBEDCRYPTO_SO_FILENAME;
-    } else {
-        crypto_so = dlopen(TFPSACRYPTO_SO_FILENAME, RTLD_NOW);
-        CHECK_DLERROR("dlopen", TFPSACRYPTO_SO_FILENAME);
         crypto_so_filename = TFPSACRYPTO_SO_FILENAME;
+    } else {
+        crypto_so = dlopen(MBEDCRYPTO_SO_FILENAME, RTLD_NOW);
+        CHECK_DLERROR("dlopen", MBEDCRYPTO_SO_FILENAME);
+        crypto_so_filename = MBEDCRYPTO_SO_FILENAME;
     }
 #pragma GCC diagnostic push
     /* dlsym() returns an object pointer which is meant to be used as a
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index c80a3f5..efa003d 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -17,15 +17,14 @@
 #include "mbedtls/build_info.h"
 
 #include <limits.h>
+#include <stdlib.h>
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #include <stdio.h>
-#include <stdlib.h>
 #if defined(MBEDTLS_HAVE_TIME)
 #include <time.h>
 #define mbedtls_time            time
-#define mbedtls_time_t          time_t
 #endif
 #define mbedtls_printf          printf
 #define mbedtls_calloc          calloc
diff --git a/scripts/bump_version.sh b/scripts/bump_version.sh
index 62939e3..9966dea 100755
--- a/scripts/bump_version.sh
+++ b/scripts/bump_version.sh
@@ -70,18 +70,14 @@
 fi
 
 [ $VERBOSE ] && echo "Bumping VERSION in CMakeLists.txt"
-sed -e "s/ VERSION [0-9.]\{1,\}/ VERSION $VERSION/g" < CMakeLists.txt > tmp
+sed -e "s/(MBEDTLS_VERSION [0-9.]\{1,\})/(MBEDTLS_VERSION $VERSION)/g" < CMakeLists.txt > tmp
 mv tmp CMakeLists.txt
 
-[ $VERBOSE ] && echo "Bumping VERSION in library/CMakeLists.txt"
-sed -e "s/ VERSION [0-9.]\{1,\}/ VERSION $VERSION/g" < library/CMakeLists.txt > tmp
-mv tmp library/CMakeLists.txt
-
 if [ "X" != "X$SO_CRYPTO" ];
 then
-  [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedcrypto in library/CMakeLists.txt"
-  sed -e "/mbedcrypto/ s/ SOVERSION [0-9]\{1,\}/ SOVERSION $SO_CRYPTO/g" < library/CMakeLists.txt > tmp
-  mv tmp library/CMakeLists.txt
+  [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedcrypto in CMakeLists.txt"
+  sed -e "s/(MBEDTLS_CRYPTO_SOVERSION [0-9]\{1,\})/(MBEDTLS_CRYPTO_SOVERSION $SO_CRYPTO)/g" < CMakeLists.txt > tmp
+  mv tmp CMakeLists.txt
 
   [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedcrypto in library/Makefile"
   sed -e "s/SOEXT_CRYPTO?=so.[0-9]\{1,\}/SOEXT_CRYPTO?=so.$SO_CRYPTO/g" < library/Makefile > tmp
@@ -90,9 +86,9 @@
 
 if [ "X" != "X$SO_X509" ];
 then
-  [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedx509 in library/CMakeLists.txt"
-  sed -e "/mbedx509/ s/ SOVERSION [0-9]\{1,\}/ SOVERSION $SO_X509/g" < library/CMakeLists.txt > tmp
-  mv tmp library/CMakeLists.txt
+  [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedx509 in CMakeLists.txt"
+  sed -e "s/(MBEDTLS_X509_SOVERSION [0-9]\{1,\})/(MBEDTLS_X509_SOVERSION $SO_X509)/g" < CMakeLists.txt > tmp
+  mv tmp CMakeLists.txt
 
   [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedx509 in library/Makefile"
   sed -e "s/SOEXT_X509?=so.[0-9]\{1,\}/SOEXT_X509?=so.$SO_X509/g" < library/Makefile > tmp
@@ -101,9 +97,9 @@
 
 if [ "X" != "X$SO_TLS" ];
 then
-  [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedtls in library/CMakeLists.txt"
-  sed -e "/mbedtls/ s/ SOVERSION [0-9]\{1,\}/ SOVERSION $SO_TLS/g" < library/CMakeLists.txt > tmp
-  mv tmp library/CMakeLists.txt
+  [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedtls in CMakeLists.txt"
+  sed -e "s/(MBEDTLS_TLS_SOVERSION [0-9]\{1,\})/(MBEDTLS_TLS_SOVERSION $SO_TLS)/g" < CMakeLists.txt > tmp
+  mv tmp CMakeLists.txt
 
   [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedtls in library/Makefile"
   sed -e "s/SOEXT_TLS?=so.[0-9]\{1,\}/SOEXT_TLS?=so.$SO_TLS/g" < library/Makefile > tmp
diff --git a/scripts/generate_config_checks.py b/scripts/generate_config_checks.py
index b0dc26b..bae93c3 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/psa-client-server/psasim/include/util.h b/tests/psa-client-server/psasim/include/util.h
index 5eb8238..dfc9a32 100644
--- a/tests/psa-client-server/psasim/include/util.h
+++ b/tests/psa-client-server/psasim/include/util.h
@@ -7,6 +7,8 @@
 
 #include "service.h"
 
+#include <stdio.h>
+
 #define PRINT(fmt, ...) \
     fprintf(stdout, fmt "\n", ##__VA_ARGS__)
 
diff --git a/tests/scripts/components-build-system.sh b/tests/scripts/components-build-system.sh
index 8a84911..ce923b5 100644
--- a/tests/scripts/components-build-system.sh
+++ b/tests/scripts/components-build-system.sh
@@ -138,6 +138,16 @@
     cd programs/test/cmake_package_install
     cmake .
     make
+
+    if ! cmp -s "mbedtls/lib/libtfpsacrypto.a" "mbedtls/lib/libmbedcrypto.a"; then
+        echo "Error: Crypto static libraries are different or one of them is missing/unreadable." >&2
+        exit 1
+    fi
+    if ! cmp -s "mbedtls/lib/libtfpsacrypto.so" "mbedtls/lib/libmbedcrypto.so"; then
+        echo "Error: Crypto shared libraries are different or one of them is missing/unreadable." >&2
+        exit 1
+    fi
+
     ./cmake_package_install
 }
 
diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh
index c9c6a13..0551e6a 100644
--- a/tests/scripts/components-configuration-crypto.sh
+++ b/tests/scripts/components-configuration-crypto.sh
@@ -100,6 +100,7 @@
     # tests in 'test_suite_psa_crypto_op_fail' that would never be executed.
     scripts/config.py set PSA_WANT_ECC_SECP_K1_192
     scripts/config.py set PSA_WANT_ECC_SECP_R1_192
+    scripts/config.py set TF_PSA_CRYPTO_ALLOW_REMOVED_MECHANISMS || true
 
     # Accelerate all PSA features (which are still enabled in CRYPTO_CONFIG_H).
     PSA_SYM_LIST=$(./scripts/config.py get-all-enabled PSA_WANT)
diff --git a/tests/scripts/test_config_checks.py b/tests/scripts/test_config_checks.py
index 7403f7e..2c6f6b3 100755
--- a/tests/scripts/test_config_checks.py
+++ b/tests/scripts/test_config_checks.py
@@ -22,12 +22,27 @@
         '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 @@
                       #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 @@
                       #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__':