Merge pull request #9385 from eleuzi01/replace-ecdsa-some
Replace MBEDTLS_PK_HAVE_ECDSA* with PSA_WANT counterparts
diff --git a/CMakeLists.txt b/CMakeLists.txt
index df4bf6b..b1af566 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,12 +40,12 @@
if(TEST_CPP)
project("Mbed TLS"
LANGUAGES C CXX
- VERSION 3.6.0
+ VERSION 4.0.0
)
else()
project("Mbed TLS"
LANGUAGES C
- VERSION 3.6.0
+ VERSION 4.0.0
)
endif()
@@ -458,7 +458,7 @@
write_basic_package_version_file(
"cmake/MbedTLSConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
- VERSION 3.6.0)
+ VERSION 4.0.0)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"
diff --git a/ChangeLog.d/fix-rsa-performance-regression.txt b/ChangeLog.d/fix-rsa-performance-regression.txt
new file mode 100644
index 0000000..603612a
--- /dev/null
+++ b/ChangeLog.d/fix-rsa-performance-regression.txt
@@ -0,0 +1,3 @@
+Bugfix
+ * Fix unintended performance regression when using short RSA public keys.
+ Fixes #9232.
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 3eb5f75..fb4439a 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -10,7 +10,7 @@
*/
/**
- * @mainpage Mbed TLS v3.6.0 API Documentation
+ * @mainpage Mbed TLS v4.0.0 API Documentation
*
* This documentation describes the internal structure of Mbed TLS. It was
* automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index 1e494a0..917b88d 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -1,4 +1,4 @@
-PROJECT_NAME = "Mbed TLS v3.6.0"
+PROJECT_NAME = "Mbed TLS v4.0.0"
OUTPUT_DIRECTORY = ../apidoc/
FULL_PATH_NAMES = NO
OPTIMIZE_OUTPUT_FOR_C = YES
diff --git a/framework b/framework
index 94599c0..071831e 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit 94599c0e3b5036e086446a51a3f79640f70f22f6
+Subproject commit 071831e25bd336baa58bbdf65e985283f56e1b86
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index cf38f90..2b48e50 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -24,8 +24,8 @@
* The version number x.y.z is split into three parts.
* Major, Minor, Patchlevel
*/
-#define MBEDTLS_VERSION_MAJOR 3
-#define MBEDTLS_VERSION_MINOR 6
+#define MBEDTLS_VERSION_MAJOR 4
+#define MBEDTLS_VERSION_MINOR 0
#define MBEDTLS_VERSION_PATCH 0
/**
@@ -33,9 +33,9 @@
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x03060000
-#define MBEDTLS_VERSION_STRING "3.6.0"
-#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.0"
+#define MBEDTLS_VERSION_NUMBER 0x04000000
+#define MBEDTLS_VERSION_STRING "4.0.0"
+#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 4.0.0"
/* Macros for build-time platform detection */
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 2e18d2b..0f75822 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -304,7 +304,7 @@
if(USE_SHARED_MBEDTLS_LIBRARY)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
add_library(${mbedcrypto_target} SHARED ${src_crypto})
- set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.6.0 SOVERSION 16)
+ set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 4.0.0 SOVERSION 16)
target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
if(TARGET ${everest_target})
@@ -316,11 +316,11 @@
endif()
add_library(${mbedx509_target} SHARED ${src_x509})
- set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.0 SOVERSION 7)
+ set_target_properties(${mbedx509_target} PROPERTIES VERSION 4.0.0 SOVERSION 7)
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
add_library(${mbedtls_target} SHARED ${src_tls})
- set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.0 SOVERSION 21)
+ set_target_properties(${mbedtls_target} PROPERTIES VERSION 4.0.0 SOVERSION 21)
target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
endif(USE_SHARED_MBEDTLS_LIBRARY)
diff --git a/tests/include/test/bignum_codepath_check.h b/tests/include/test/bignum_codepath_check.h
new file mode 100644
index 0000000..3d72be1
--- /dev/null
+++ b/tests/include/test/bignum_codepath_check.h
@@ -0,0 +1,94 @@
+/** Support for path tracking in optionally safe bignum functions
+ *
+ * The functions are called when an optionally safe path is taken and logs it with a single
+ * variable. This variable is at any time in one of three states:
+ * - MBEDTLS_MPI_IS_TEST: No optionally safe path has been taken since the last reset
+ * - MBEDTLS_MPI_IS_SECRET: Only safe paths were teken since the last reset
+ * - MBEDTLS_MPI_IS_PUBLIC: At least one unsafe path has been taken since the last reset
+ *
+ * Use a simple global variable to track execution path. Making it work with multithreading
+ * isn't worth the effort as multithreaded tests add little to no value here.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef BIGNUM_CODEPATH_CHECK_H
+#define BIGNUM_CODEPATH_CHECK_H
+
+#include "bignum_core.h"
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+
+extern int mbedtls_codepath_check;
+
+/**
+ * \brief Setup the codepath test hooks used by optionally safe bignum functions to signal
+ * the path taken.
+ */
+void mbedtls_codepath_test_hooks_setup(void);
+
+/**
+ * \brief Teardown the codepath test hooks used by optionally safe bignum functions to
+ * signal the path taken.
+ */
+void mbedtls_codepath_test_hooks_teardown(void);
+
+/**
+ * \brief Reset the state of the codepath to the initial state.
+ */
+static inline void mbedtls_codepath_reset(void)
+{
+ mbedtls_codepath_check = MBEDTLS_MPI_IS_TEST;
+}
+
+/** Check the codepath taken and fail if it doesn't match.
+ *
+ * When a function returns with an error, it can do so before reaching any interesting codepath. The
+ * same can happen if a parameter to the function is zero. In these cases we need to allow
+ * the codepath tracking variable to still have its initial "not set" value.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param path The expected codepath.
+ * This expression may be evaluated multiple times.
+ * \param ret The expected return value.
+ * \param E The MPI parameter that can cause shortcuts.
+ */
+#define ASSERT_BIGNUM_CODEPATH(path, ret, E) \
+ do { \
+ if ((ret) != 0 || (E).n == 0) { \
+ TEST_ASSERT(mbedtls_codepath_check == (path) || \
+ mbedtls_codepath_check == MBEDTLS_MPI_IS_TEST); \
+ } else { \
+ TEST_EQUAL(mbedtls_codepath_check, (path)); \
+ } \
+ } while (0)
+
+/** Check the codepath taken and fail if it doesn't match.
+ *
+ * When a function returns with an error, it can do so before reaching any interesting codepath. In
+ * this case we need to allow the codepath tracking variable to still have its
+ * initial "not set" value.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param path The expected codepath.
+ * This expression may be evaluated multiple times.
+ * \param ret The expected return value.
+ */
+#define ASSERT_RSA_CODEPATH(path, ret) \
+ do { \
+ if ((ret) != 0) { \
+ TEST_ASSERT(mbedtls_codepath_check == (path) || \
+ mbedtls_codepath_check == MBEDTLS_MPI_IS_TEST); \
+ } else { \
+ TEST_EQUAL(mbedtls_codepath_check, (path)); \
+ } \
+ } while (0)
+#endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
+
+#endif /* BIGNUM_CODEPATH_CHECK_H */
diff --git a/tests/scripts/components-build-system.sh b/tests/scripts/components-build-system.sh
index 4bb41ae..2c2d460 100644
--- a/tests/scripts/components-build-system.sh
+++ b/tests/scripts/components-build-system.sh
@@ -65,7 +65,7 @@
mkdir "$OUT_OF_SOURCE_DIR"
cd "$OUT_OF_SOURCE_DIR"
# Note: Explicitly generate files as these are turned off in releases
- cmake -D CMAKE_BUILD_TYPE:String=Check -D GEN_FILES=ON _D TEST_CPP=1 "$MBEDTLS_ROOT_DIR"
+ cmake -D CMAKE_BUILD_TYPE:String=Check -D GEN_FILES=ON -D TEST_CPP=1 "$MBEDTLS_ROOT_DIR"
make
msg "test: cmake 'out-of-source' build"
@@ -108,10 +108,15 @@
make neat
msg "build: cmake 'as-package' build"
+ root_dir="$(pwd)"
cd programs/test/cmake_package
+ build_variant_dir="$(pwd)"
cmake .
make
./cmake_package
+ if [[ "$OSTYPE" == linux* ]]; then
+ PKG_CONFIG_PATH="${build_variant_dir}/mbedtls/pkgconfig" ${root_dir}/tests/scripts/pkgconfig.sh
+ fi
}
support_test_cmake_as_package () {
diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh
index 2a770f5..d3741de 100644
--- a/tests/scripts/components-configuration-crypto.sh
+++ b/tests/scripts/components-configuration-crypto.sh
@@ -2288,11 +2288,19 @@
# MBEDTLS_BLOCK_CIPHER_NO_DECRYPT is incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES,
# manually set or unset those configurations to check
# MBEDTLS_BLOCK_CIPHER_NO_DECRYPT with various combinations in aes.o.
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
- scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
- scripts/config.py unset MBEDTLS_DES_C
scripts/config.py unset MBEDTLS_NIST_KW_C
+
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CBC_NO_PADDING
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_CBC_PKCS7
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECB_NO_PADDING
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DES
+ # Note: The two unsets below are to be removed for Mbed TLS 4.0
+ scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+ scripts/config.py unset MBEDTLS_DES_C
+
build_test_config_combos ${BUILTIN_SRC_PATH}/aes.o validate_aes_config_variations \
"MBEDTLS_AES_ROM_TABLES" \
"MBEDTLS_AES_FEWER_TABLES" "MBEDTLS_AES_USE_HARDWARE_ONLY" \
@@ -2303,9 +2311,21 @@
msg "sha3 loop unroll variations"
# define minimal config sufficient to test SHA3
- cat > include/mbedtls/mbedtls_config.h << END
- #define MBEDTLS_SELF_TEST
- #define MBEDTLS_SHA3_C
+ cat > include/mbedtls/mbedtls_config.h << END
+ #define MBEDTLS_AES_C
+ #define MBEDTLS_CTR_DRBG_C
+ #define MBEDTLS_ENTROPY_C
+ #define MBEDTLS_PSA_CRYPTO_C
+ #define MBEDTLS_PSA_CRYPTO_CONFIG
+ #define MBEDTLS_SELF_TEST
+END
+
+ cat > tf-psa-crypto/include/psa/crypto_config.h << END
+ #define PSA_WANT_ALG_SHA_256 1
+ #define PSA_WANT_ALG_SHA3_224 1
+ #define PSA_WANT_ALG_SHA3_256 1
+ #define PSA_WANT_ALG_SHA3_384 1
+ #define PSA_WANT_ALG_SHA3_512 1
END
msg "all loops unrolled"
@@ -2427,7 +2447,7 @@
make test
}
-# helper for common_block_cipher_no_decrypt() which:
+# helper for component_test_block_cipher_no_decrypt_aesni() which:
# - enable/disable the list of config options passed from -s/-u respectively.
# - build
# - test for tests_suite_xxx
@@ -2481,13 +2501,32 @@
programs/test/selftest
}
-# This is a common configuration function used in:
-# - component_test_block_cipher_no_decrypt_aesni_legacy()
-# - component_test_block_cipher_no_decrypt_aesni_use_psa()
-# in order to test BLOCK_CIPHER_NO_DECRYPT with AESNI intrinsics,
-# AESNI assembly and AES C implementation on x86_64 and with AESNI intrinsics
-# on x86.
-common_block_cipher_no_decrypt () {
+# This is a configuration function used in component_test_block_cipher_no_decrypt_xxx:
+config_block_cipher_no_decrypt () {
+ scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
+ scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
+ scripts/config.py unset MBEDTLS_NIST_KW_C
+
+ # Enable support for cryptographic mechanisms through the PSA API.
+ # Note: XTS, KW are not yet supported via the PSA API in Mbed TLS.
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_ECB_NO_PADDING
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_DES
+ # Note: The two unsets below are to be removed for Mbed TLS 4.0
+ scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
+ scripts/config.py unset MBEDTLS_DES_C
+}
+
+component_test_block_cipher_no_decrypt_aesni () {
+ # Test BLOCK_CIPHER_NO_DECRYPT with AESNI intrinsics, AESNI assembly and
+ # AES C implementation on x86_64 and with AESNI intrinsics on x86.
+
+ # This consistently causes an llvm crash on clang 3.8, so use gcc
+ export CC=gcc
+ config_block_cipher_no_decrypt
+
# test AESNI intrinsics
helper_block_cipher_no_decrypt_build_test \
-s "MBEDTLS_AESNI_C" \
@@ -2509,43 +2548,6 @@
-l "-m32"
}
-# This is a configuration function used in component_test_block_cipher_no_decrypt_xxx:
-# usage: 0: no PSA crypto configuration
-# 1: use PSA crypto configuration
-config_block_cipher_no_decrypt () {
- use_psa=$1
-
- scripts/config.py set MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
- scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
- scripts/config.py unset MBEDTLS_CIPHER_MODE_XTS
- scripts/config.py unset MBEDTLS_DES_C
- scripts/config.py unset MBEDTLS_NIST_KW_C
-
- if [ "$use_psa" -eq 1 ]; then
- # Enable support for cryptographic mechanisms through the PSA API.
- # Note: XTS, KW are not yet supported via the PSA API in Mbed TLS.
- scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
- scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
- scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
- scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_ECB_NO_PADDING
- scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_DES
- fi
-}
-
-component_test_block_cipher_no_decrypt_aesni () {
- # This consistently causes an llvm crash on clang 3.8, so use gcc
- export CC=gcc
- config_block_cipher_no_decrypt 0
- common_block_cipher_no_decrypt
-}
-
-component_test_block_cipher_no_decrypt_aesni_use_psa () {
- # This consistently causes an llvm crash on clang 3.8, so use gcc
- export CC=gcc
- config_block_cipher_no_decrypt 1
- common_block_cipher_no_decrypt
-}
-
support_test_block_cipher_no_decrypt_aesce_armcc () {
support_build_armcc
}
@@ -2565,7 +2567,7 @@
scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
scripts/config.py set MBEDTLS_HAVE_ASM
- config_block_cipher_no_decrypt 1
+ config_block_cipher_no_decrypt
# test AESCE baremetal build
scripts/config.py set MBEDTLS_AESCE_C
diff --git a/tests/scripts/components-configuration-tls.sh b/tests/scripts/components-configuration-tls.sh
index f936042..d81303b 100644
--- a/tests/scripts/components-configuration-tls.sh
+++ b/tests/scripts/components-configuration-tls.sh
@@ -404,15 +404,35 @@
msg "build: TLS 1.3 only from default, only PSK key exchange mode"
scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
- scripts/config.py unset MBEDTLS_ECDH_C
- scripts/config.py unset MBEDTLS_DHM_C
scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
- scripts/config.py unset MBEDTLS_ECDSA_C
- scripts/config.py unset MBEDTLS_PKCS1_V21
scripts/config.py unset MBEDTLS_PKCS7_C
scripts/config.py set MBEDTLS_SSL_EARLY_DATA
+
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECDH
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECDSA
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_RSA_OAEP
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_RSA_PSS
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_FFDH
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_DH_RFC7919_2048
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_DH_RFC7919_3072
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_DH_RFC7919_4096
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_DH_RFC7919_6144
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_DH_RFC7919_8192
+ # Note: The four unsets below are to be removed for Mbed TLS 4.0
+ scripts/config.py unset MBEDTLS_ECDH_C
+ scripts/config.py unset MBEDTLS_ECDSA_C
+ scripts/config.py unset MBEDTLS_PKCS1_V21
+ scripts/config.py unset MBEDTLS_DHM_C
+
make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
msg "test_suite_ssl: TLS 1.3 only, only PSK key exchange mode enabled"
@@ -441,6 +461,10 @@
scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
scripts/config.py unset MBEDTLS_SSL_EARLY_DATA
+
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECDH
+ # Note: The unset below is to be removed for Mbed TLS 4.0
scripts/config.py unset MBEDTLS_ECDH_C
make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
@@ -459,10 +483,18 @@
scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
- scripts/config.py unset MBEDTLS_ECDSA_C
- scripts/config.py unset MBEDTLS_PKCS1_V21
scripts/config.py unset MBEDTLS_PKCS7_C
scripts/config.py set MBEDTLS_SSL_EARLY_DATA
+
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECDSA
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_RSA_OAEP
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_RSA_PSS
+ # Note: The two unsets below are to be removed for Mbed TLS 4.0
+ scripts/config.py unset MBEDTLS_ECDSA_C
+ scripts/config.py unset MBEDTLS_PKCS1_V21
+
make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
msg "test_suite_ssl: TLS 1.3 only, only PSK ephemeral key exchange mode"
@@ -479,11 +511,20 @@
scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
- scripts/config.py unset MBEDTLS_ECDSA_C
- scripts/config.py unset MBEDTLS_PKCS1_V21
scripts/config.py unset MBEDTLS_PKCS7_C
scripts/config.py set MBEDTLS_SSL_EARLY_DATA
+
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECDH
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECDSA
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_RSA_OAEP
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_RSA_PSS
+ # Note: The three unsets below are to be removed for Mbed TLS 4.0
scripts/config.py unset MBEDTLS_ECDH_C
+ scripts/config.py unset MBEDTLS_ECDSA_C
+ scripts/config.py unset MBEDTLS_PKCS1_V21
+
make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
msg "test_suite_ssl: TLS 1.3 only, only PSK ephemeral ffdh key exchange mode"
@@ -499,10 +540,18 @@
scripts/config.py unset MBEDTLS_X509_CRT_PARSE_C
scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION
- scripts/config.py unset MBEDTLS_ECDSA_C
- scripts/config.py unset MBEDTLS_PKCS1_V21
scripts/config.py unset MBEDTLS_PKCS7_C
scripts/config.py set MBEDTLS_SSL_EARLY_DATA
+
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_ECDSA
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_RSA_OAEP
+ scripts/config.py -f $CRYPTO_CONFIG_H unset PSA_WANT_ALG_RSA_PSS
+ # Note: The two unsets below are to be removed for Mbed TLS 4.0
+ scripts/config.py unset MBEDTLS_ECDSA_C
+ scripts/config.py unset MBEDTLS_PKCS1_V21
+
make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'"
msg "test_suite_ssl: TLS 1.3 only, PSK and PSK ephemeral key exchange modes"
diff --git a/tests/scripts/pkgconfig.sh b/tests/scripts/pkgconfig.sh
new file mode 100755
index 0000000..2702bfa
--- /dev/null
+++ b/tests/scripts/pkgconfig.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# Purpose
+#
+# Test pkgconfig files.
+#
+# For each of the build pkg-config files, .pc files, check that
+# they validate and do some basic sanity testing on the output,
+# i.e. that the strings are non-empty.
+#
+# NOTE: This requires the built pc files to be on the pkg-config
+# search path, this can be controlled with env variable
+# PKG_CONFIG_PATH. See man(1) pkg-config for details.
+#
+
+set -e -u
+
+# These are the EXPECTED package names. Renaming these could break
+# consumers of pkg-config, consider carefully.
+all_pcs="mbedtls mbedx509 mbedcrypto"
+
+for pc in $all_pcs; do
+ printf "testing package config file: ${pc} ... "
+ pkg-config --validate "${pc}"
+ version="$(pkg-config --modversion "${pc}")"
+ test -n "$version"
+ cflags="$(pkg-config --cflags "${pc}")"
+ test -n "$cflags"
+ libs="$(pkg-config --libs "${pc}")"
+ test -n "$libs"
+ printf "passed\n"
+done
+
+exit 0
diff --git a/tests/src/bignum_codepath_check.c b/tests/src/bignum_codepath_check.c
new file mode 100644
index 0000000..b752d13
--- /dev/null
+++ b/tests/src/bignum_codepath_check.c
@@ -0,0 +1,38 @@
+/** Support for path tracking in optionally safe bignum functions
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#include "test/bignum_codepath_check.h"
+#include "bignum_core_invasive.h"
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+int mbedtls_codepath_check = MBEDTLS_MPI_IS_TEST;
+
+void mbedtls_codepath_take_safe(void)
+{
+ if (mbedtls_codepath_check == MBEDTLS_MPI_IS_TEST) {
+ mbedtls_codepath_check = MBEDTLS_MPI_IS_SECRET;
+ }
+}
+
+void mbedtls_codepath_take_unsafe(void)
+{
+ mbedtls_codepath_check = MBEDTLS_MPI_IS_PUBLIC;
+}
+
+void mbedtls_codepath_test_hooks_setup(void)
+{
+ mbedtls_safe_codepath_hook = mbedtls_codepath_take_safe;
+ mbedtls_unsafe_codepath_hook = mbedtls_codepath_take_unsafe;
+}
+
+void mbedtls_codepath_test_hooks_teardown(void)
+{
+ mbedtls_safe_codepath_hook = NULL;
+ mbedtls_unsafe_codepath_hook = NULL;
+}
+
+#endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index 065d17d..db50296 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -16,6 +16,9 @@
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C)
#include <test/psa_memory_poisoning_wrappers.h>
#endif
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+#include <test/bignum_codepath_check.h>
+#endif
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
@@ -342,6 +345,11 @@
mbedtls_mutex_init(&mbedtls_test_info_mutex);
#endif /* MBEDTLS_THREADING_C */
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_test_hooks_setup();
+#endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
+
return ret;
}
@@ -359,6 +367,10 @@
#if defined(MBEDTLS_PLATFORM_C)
mbedtls_platform_teardown(&platform_ctx);
#endif /* MBEDTLS_PLATFORM_C */
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_test_hooks_teardown();
+#endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
}
int mbedtls_test_ascii2uc(const char c, unsigned char *uc)
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 6afc26a..beb9aa5 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -273,31 +273,39 @@
}
requires_all_configs_enabled() {
- if ! $P_QUERY -all $* 2>&1 > /dev/null
- then
- SKIP_NEXT="YES"
- fi
+ for x in "$@"; do
+ if ! is_config_enabled "$x"; then
+ SKIP_NEXT="YES"
+ return
+ fi
+ done
}
requires_all_configs_disabled() {
- if $P_QUERY -any $* 2>&1 > /dev/null
- then
- SKIP_NEXT="YES"
- fi
+ for x in "$@"; do
+ if is_config_enabled "$x"; then
+ SKIP_NEXT="YES"
+ return
+ fi
+ done
}
requires_any_configs_enabled() {
- if ! $P_QUERY -any $* 2>&1 > /dev/null
- then
- SKIP_NEXT="YES"
- fi
+ for x in "$@"; do
+ if is_config_enabled "$x"; then
+ return
+ fi
+ done
+ SKIP_NEXT="YES"
}
requires_any_configs_disabled() {
- if $P_QUERY -all $* 2>&1 > /dev/null
- then
- SKIP_NEXT="YES"
- fi
+ for x in "$@"; do
+ if ! is_config_enabled "$x"; then
+ return
+ fi
+ done
+ SKIP_NEXT="YES"
}
TLS1_2_KEY_EXCHANGES_WITH_CERT="MBEDTLS_KEY_EXCHANGE_RSA_ENABLED \
@@ -317,13 +325,14 @@
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED \
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled() {
- if $P_QUERY -all MBEDTLS_SSL_PROTO_TLS1_2
+requires_certificate_authentication () {
+ if is_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
then
+ # TLS 1.3 is negotiated by default, so check whether it supports
+ # certificate-based authentication.
+ requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+ else # Only TLS 1.2 is enabled.
requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT
- elif ! $P_QUERY -all MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
- then
- SKIP_NEXT="YES"
fi
}
@@ -475,10 +484,19 @@
requires_config_enabled MBEDTLS_SSL_ALPN;;
esac
+ case " $CMD_LINE " in
+ *\ auth_mode=*|*[-_\ =]crt[_=]*)
+ # The test case involves certificates (crt), or a relevant
+ # aspect of it is the (certificate-based) authentication mode.
+ requires_certificate_authentication;;
+ esac
+
case "$CMD_LINE" in
+ *[-_\ =]psk*|*[-_\ =]PSK*) :;; # No certificate requirement with PSK
*/server5*|\
*/server7*|\
*/dir-maxpath*)
+ requires_certificate_authentication
if [ "$TLS_VERSION" = "TLS13" ]; then
# In case of TLS13 the support for ECDSA is enough
requires_pk_alg "ECDSA"
@@ -510,9 +528,11 @@
esac
case "$CMD_LINE" in
+ *[-_\ =]psk*|*[-_\ =]PSK*) :;; # No certificate requirement with PSK
*/server1*|\
*/server2*|\
*/server7*)
+ requires_certificate_authentication
# Certificates with an RSA key. The algorithm requirement is
# some subset of {PKCS#1v1.5 encryption, PKCS#1v1.5 signature,
# PSS signature}. We can't easily tell which subset works, and
@@ -525,17 +545,12 @@
unset tmp
}
-requires_certificate_authentication () {
- if [ "$PSK_ONLY" = "YES" ]; then
- SKIP_NEXT="YES"
- fi
-}
-
adapt_cmd_for_psk () {
case "$2" in
*openssl*s_server*) s='-psk 73776f726466697368 -nocert';;
*openssl*) s='-psk 73776f726466697368';;
- *gnutls-*) s='--pskusername=Client_identity --pskkey=73776f726466697368';;
+ *gnutls-cli*) s='--pskusername=Client_identity --pskkey=73776f726466697368';;
+ *gnutls-serv*) s='--pskpasswd=../framework/data_files/simplepass.psk';;
*) s='psk=73776f726466697368';;
esac
eval $1='"$2 $s"'
@@ -586,14 +601,28 @@
adapt_cmd_for_psk SRV_CMD "$SRV_CMD"
}
-case " $CONFIGS_ENABLED " in
- *\ MBEDTLS_KEY_EXCHANGE_[^P]*) PSK_ONLY="NO";;
- *\ MBEDTLS_KEY_EXCHANGE_P[^S]*) PSK_ONLY="NO";;
- *\ MBEDTLS_KEY_EXCHANGE_PS[^K]*) PSK_ONLY="NO";;
- *\ MBEDTLS_KEY_EXCHANGE_PSK[^_]*) PSK_ONLY="NO";;
- *\ MBEDTLS_KEY_EXCHANGE_PSK_ENABLED\ *) PSK_ONLY="YES";;
- *) PSK_ONLY="NO";;
-esac
+# PSK_PRESENT="YES" if at least one protocol versions supports at least
+# one PSK key exchange mode.
+PSK_PRESENT="NO"
+# PSK_ONLY="YES" if all the available key exchange modes are PSK-based
+# (pure-PSK or PSK-ephemeral, possibly both).
+PSK_ONLY=""
+for c in $CONFIGS_ENABLED; do
+ case $c in
+ MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) PSK_PRESENT="YES";;
+ MBEDTLS_KEY_EXCHANGE_*_PSK_ENABLED) PSK_PRESENT="YES";;
+ MBEDTLS_KEY_EXCHANGE_*_ENABLED) PSK_ONLY="NO";;
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) PSK_PRESENT="YES";;
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_*_ENABLED) PSK_PRESENT="YES";;
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_*_ENABLED) PSK_ONLY="NO";;
+ esac
+done
+# At this stage, $PSK_ONLY is empty if we haven't detected a non-PSK
+# key exchange, i.e. if we're in a PSK-only build or a build with no
+# key exchanges at all. We avoid triggering PSK-only adaptation code in
+# the edge case of no key exchanges.
+: ${PSK_ONLY:=$PSK_PRESENT}
+unset c
HAS_ALG_MD5="NO"
HAS_ALG_SHA_1="NO"
@@ -795,6 +824,14 @@
fi
}
+# OpenSSL servers forbid client renegotiation by default since OpenSSL 3.0.
+# Older versions always allow it and have no command-line option.
+OPENSSL_S_SERVER_CLIENT_RENEGOTIATION=
+case $($OPENSSL s_server -help 2>&1) in
+ *-client_renegotiation*)
+ OPENSSL_S_SERVER_CLIENT_RENEGOTIATION=-client_renegotiation;;
+esac
+
# skip next test if tls1_3 is not available
requires_gnutls_tls1_3() {
requires_gnutls_next
@@ -1645,7 +1682,7 @@
esac
# Third if the version is not forced, if TLS 1.3 is enabled then the test
# is aimed to run a TLS 1.3 handshake.
- if $P_QUERY -all MBEDTLS_SSL_PROTO_TLS1_3
+ if is_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
then
echo "TLS13"
else
@@ -1731,14 +1768,14 @@
TLS_VERSION="TLS12"
fi
+ # If we're in a PSK-only build and the test can be adapted to PSK, do that.
+ maybe_adapt_for_psk "$@"
+
# If the client or server requires certain features that can be detected
# from their command-line arguments, check whether they're enabled.
detect_required_features "$SRV_CMD" "server" "$TLS_VERSION" "$EXT_WO_ECDH" "$@"
detect_required_features "$CLI_CMD" "client" "$TLS_VERSION" "$EXT_WO_ECDH" "$@"
- # If we're in a PSK-only build and the test can be adapted to PSK, do that.
- maybe_adapt_for_psk "$@"
-
# should we skip?
if [ "X$SKIP_NEXT" = "XYES" ]; then
SKIP_NEXT="NO"
@@ -2070,8 +2107,8 @@
# - the expected parameters are selected
requires_ciphersuite_enabled TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256
requires_hash_alg SHA_512 # "signature_algorithm ext: 6"
-requires_any_configs_enabled "MBEDTLS_ECP_DP_CURVE25519_ENABLED \
- PSA_WANT_ECC_MONTGOMERY_255"
+requires_any_configs_enabled MBEDTLS_ECP_DP_CURVE25519_ENABLED \
+ PSA_WANT_ECC_MONTGOMERY_255
run_test "Default, TLS 1.2" \
"$P_SRV debug_level=3" \
"$P_CLI force_version=tls12" \
@@ -2092,7 +2129,6 @@
-s "Protocol is DTLSv1.2" \
-s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "TLS client auth: required" \
"$P_SRV auth_mode=required" \
"$P_CLI" \
@@ -2696,8 +2732,8 @@
-U "IV used"
# Test for correctness of sent single supported algorithm
-requires_any_configs_enabled "MBEDTLS_ECP_DP_SECP256R1_ENABLED \
- PSA_WANT_ECC_SECP_R1_256"
+requires_any_configs_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED \
+ PSA_WANT_ECC_SECP_R1_256
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2712,8 +2748,8 @@
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_SRV_C
-requires_any_configs_enabled "MBEDTLS_ECP_DP_SECP256R1_ENABLED \
- PSA_WANT_ECC_SECP_R1_256"
+requires_any_configs_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED \
+ PSA_WANT_ECC_SECP_R1_256
requires_hash_alg SHA_256
run_test "Single supported algorithm sending: openssl client" \
"$P_SRV sig_algs=ecdsa_secp256r1_sha256 auth_mode=required" \
@@ -2722,7 +2758,6 @@
0
# Tests for certificate verification callback
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Configuration-specific CRT verification callback" \
"$P_SRV debug_level=3" \
"$P_CLI context_crt_cb=0 debug_level=3" \
@@ -2733,7 +2768,6 @@
-C "Use context-specific verification callback" \
-C "error"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Context-specific CRT verification callback" \
"$P_SRV debug_level=3" \
"$P_CLI context_crt_cb=1 debug_level=3" \
@@ -5550,7 +5584,7 @@
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Renegotiation: openssl server, client-initiated" \
- "$O_SRV -www -tls1_2" \
+ "$O_SRV -www $OPENSSL_S_SERVER_CLIENT_RENEGOTIATION -tls1_2" \
"$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
0 \
-c "client hello, adding renegotiation extension" \
@@ -5812,7 +5846,6 @@
# When updating these tests, modify the matching authentication tests accordingly
# The next 4 cases test the 3 auth modes with a badly signed server cert.
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: server badcert, client required" \
"$P_SRV crt_file=$DATA_FILES_PATH/server5-badsign.crt \
key_file=$DATA_FILES_PATH/server5.key" \
@@ -5884,7 +5917,6 @@
-C "send alert level=2 message=48" \
-C "X509 - Certificate verification failed"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: server goodcert, client required, no trusted CA" \
"$P_SRV" \
"$P_CLI debug_level=3 auth_mode=required ca_file=none ca_path=none" \
@@ -5906,7 +5938,6 @@
-c "! mbedtls_ssl_handshake returned" \
-c "SSL - No CA Chain is set, but required to operate"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: server goodcert, client optional, no trusted CA" \
"$P_SRV" \
"$P_CLI debug_level=3 auth_mode=optional ca_file=none ca_path=none" \
@@ -5930,7 +5961,6 @@
-C "X509 - Certificate verification failed" \
-C "SSL - No CA Chain is set, but required to operate"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: server goodcert, client none, no trusted CA" \
"$P_SRV" \
"$P_CLI debug_level=3 auth_mode=none ca_file=none ca_path=none" \
@@ -5999,7 +6029,6 @@
-c "Supported Signature Algorithm found: 04 " \
-c "Supported Signature Algorithm found: 05 "
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: client has no cert, server required (TLS)" \
"$P_SRV debug_level=3 auth_mode=required" \
"$P_CLI debug_level=3 crt_file=none \
@@ -6015,7 +6044,6 @@
-s "! mbedtls_ssl_handshake returned" \
-s "No client certification received from the client, but required by the authentication mode"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: client badcert, server required" \
"$P_SRV debug_level=3 auth_mode=required" \
"$P_CLI debug_level=3 crt_file=$DATA_FILES_PATH/server5-badsign.crt \
@@ -6036,7 +6064,6 @@
# detect that its write end of the connection is closed and abort
# before reading the alert message.
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: client cert self-signed and trusted, server required" \
"$P_SRV debug_level=3 auth_mode=required ca_file=$DATA_FILES_PATH/server5-selfsigned.crt" \
"$P_CLI debug_level=3 crt_file=$DATA_FILES_PATH/server5-selfsigned.crt \
@@ -6052,7 +6079,6 @@
-S "! The certificate is not correctly signed" \
-S "X509 - Certificate verification failed"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: client cert not trusted, server required" \
"$P_SRV debug_level=3 auth_mode=required" \
"$P_CLI debug_level=3 crt_file=$DATA_FILES_PATH/server5-selfsigned.crt \
@@ -6069,7 +6095,6 @@
-s "! mbedtls_ssl_handshake returned" \
-s "X509 - Certificate verification failed"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: client badcert, server optional" \
"$P_SRV debug_level=3 auth_mode=optional" \
"$P_CLI debug_level=3 crt_file=$DATA_FILES_PATH/server5-badsign.crt \
@@ -6087,7 +6112,6 @@
-C "! mbedtls_ssl_handshake returned" \
-S "X509 - Certificate verification failed"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: client badcert, server none" \
"$P_SRV debug_level=3 auth_mode=none" \
"$P_CLI debug_level=3 crt_file=$DATA_FILES_PATH/server5-badsign.crt \
@@ -6105,7 +6129,6 @@
-C "! mbedtls_ssl_handshake returned" \
-S "X509 - Certificate verification failed"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: client no cert, server optional" \
"$P_SRV debug_level=3 auth_mode=optional" \
"$P_CLI debug_level=3 crt_file=none key_file=none" \
@@ -6123,7 +6146,6 @@
-S "X509 - Certificate verification failed"
requires_openssl_tls1_3_with_compatible_ephemeral
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Authentication: openssl client no cert, server optional" \
"$P_SRV debug_level=3 auth_mode=optional" \
"$O_NEXT_CLI_NO_CERT -no_middlebox" \
@@ -6537,7 +6559,6 @@
# tests for SNI
requires_config_disabled MBEDTLS_X509_REMOVE_INFO
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: no SNI callback" \
"$P_SRV debug_level=3 \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key" \
@@ -6547,7 +6568,6 @@
-c "subject name *: C=NL, O=PolarSSL, CN=localhost"
requires_config_disabled MBEDTLS_X509_REMOVE_INFO
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: matching cert 1" \
"$P_SRV debug_level=3 \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6559,7 +6579,6 @@
-c "subject name *: C=NL, O=PolarSSL, CN=localhost"
requires_config_disabled MBEDTLS_X509_REMOVE_INFO
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: matching cert 2" \
"$P_SRV debug_level=3 \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6571,7 +6590,6 @@
-c "subject name *: C=NL, O=PolarSSL, CN=polarssl.example"
requires_config_disabled MBEDTLS_X509_REMOVE_INFO
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: no matching cert" \
"$P_SRV debug_level=3 \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6584,7 +6602,6 @@
-c "mbedtls_ssl_handshake returned" \
-c "SSL - A fatal alert message was received from our peer"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: client auth no override: optional" \
"$P_SRV debug_level=3 auth_mode=optional \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6598,7 +6615,6 @@
-C "skip write certificate verify" \
-S "skip parse certificate verify"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: client auth override: none -> optional" \
"$P_SRV debug_level=3 auth_mode=none \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6612,7 +6628,6 @@
-C "skip write certificate verify" \
-S "skip parse certificate verify"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: client auth override: optional -> none" \
"$P_SRV debug_level=3 auth_mode=optional \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6624,7 +6639,6 @@
-c "got no certificate request" \
-c "skip write certificate"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: CA no override" \
"$P_SRV debug_level=3 auth_mode=optional \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6643,7 +6657,6 @@
-s "! The certificate is not correctly signed by the trusted CA" \
-S "The certificate has been revoked (is on a CRL)"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: CA override" \
"$P_SRV debug_level=3 auth_mode=optional \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6662,7 +6675,6 @@
-S "! The certificate is not correctly signed by the trusted CA" \
-S "The certificate has been revoked (is on a CRL)"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "SNI: CA override with CRL" \
"$P_SRV debug_level=3 auth_mode=optional \
crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key \
@@ -6835,7 +6847,6 @@
# Tests for non-blocking I/O: exercise a variety of handshake flows
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Non-blocking I/O: basic handshake" \
"$P_SRV nbio=2 tickets=0 auth_mode=none" \
"$P_CLI nbio=2 tickets=0" \
@@ -6844,7 +6855,6 @@
-C "mbedtls_ssl_handshake returned" \
-c "Read from server: .* bytes read"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Non-blocking I/O: client auth" \
"$P_SRV nbio=2 tickets=0 auth_mode=required" \
"$P_CLI nbio=2 tickets=0" \
@@ -6853,7 +6863,6 @@
-C "mbedtls_ssl_handshake returned" \
-c "Read from server: .* bytes read"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
run_test "Non-blocking I/O: ticket" \
"$P_SRV nbio=2 tickets=1 auth_mode=none" \
@@ -6863,7 +6872,6 @@
-C "mbedtls_ssl_handshake returned" \
-c "Read from server: .* bytes read"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
run_test "Non-blocking I/O: ticket + client auth" \
"$P_SRV nbio=2 tickets=1 auth_mode=required" \
@@ -6928,7 +6936,6 @@
# Tests for event-driven I/O: exercise a variety of handshake flows
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Event-driven I/O: basic handshake" \
"$P_SRV event=1 tickets=0 auth_mode=none" \
"$P_CLI event=1 tickets=0" \
@@ -6937,7 +6944,6 @@
-C "mbedtls_ssl_handshake returned" \
-c "Read from server: .* bytes read"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "Event-driven I/O: client auth" \
"$P_SRV event=1 tickets=0 auth_mode=required" \
"$P_CLI event=1 tickets=0" \
@@ -6946,7 +6952,6 @@
-C "mbedtls_ssl_handshake returned" \
-c "Read from server: .* bytes read"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
run_test "Event-driven I/O: ticket" \
"$P_SRV event=1 tickets=1 auth_mode=none" \
@@ -6956,7 +6961,6 @@
-C "mbedtls_ssl_handshake returned" \
-c "Read from server: .* bytes read"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
run_test "Event-driven I/O: ticket + client auth" \
"$P_SRV event=1 tickets=1 auth_mode=required" \
@@ -7651,7 +7655,6 @@
# Tests for ALPN extension
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "ALPN: none" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3" \
@@ -7664,7 +7667,6 @@
-C "Application Layer Protocol is" \
-S "Application Layer Protocol is"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "ALPN: client only" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3 alpn=abc,1234" \
@@ -7677,7 +7679,6 @@
-c "Application Layer Protocol is (none)" \
-S "Application Layer Protocol is"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "ALPN: server only" \
"$P_SRV debug_level=3 alpn=abc,1234" \
"$P_CLI debug_level=3" \
@@ -7690,7 +7691,6 @@
-C "Application Layer Protocol is" \
-s "Application Layer Protocol is (none)"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "ALPN: both, common cli1-srv1" \
"$P_SRV debug_level=3 alpn=abc,1234" \
"$P_CLI debug_level=3 alpn=abc,1234" \
@@ -7703,7 +7703,6 @@
-c "Application Layer Protocol is abc" \
-s "Application Layer Protocol is abc"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "ALPN: both, common cli2-srv1" \
"$P_SRV debug_level=3 alpn=abc,1234" \
"$P_CLI debug_level=3 alpn=1234,abc" \
@@ -7716,7 +7715,6 @@
-c "Application Layer Protocol is abc" \
-s "Application Layer Protocol is abc"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "ALPN: both, common cli1-srv2" \
"$P_SRV debug_level=3 alpn=abc,1234" \
"$P_CLI debug_level=3 alpn=1234,abcde" \
@@ -7729,7 +7727,6 @@
-c "Application Layer Protocol is 1234" \
-s "Application Layer Protocol is 1234"
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "ALPN: both, no common" \
"$P_SRV debug_level=3 alpn=abc,123" \
"$P_CLI debug_level=3 alpn=1234,abcde" \
@@ -8161,28 +8158,24 @@
# Tests for extendedKeyUsage, part 1: server-side certificate/suite selection
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "extKeyUsage srv: serverAuth -> OK" \
"$P_SRV key_file=$DATA_FILES_PATH/server5.key \
crt_file=$DATA_FILES_PATH/server5.eku-srv.crt" \
"$P_CLI" \
0
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "extKeyUsage srv: serverAuth,clientAuth -> OK" \
"$P_SRV key_file=$DATA_FILES_PATH/server5.key \
crt_file=$DATA_FILES_PATH/server5.eku-srv.crt" \
"$P_CLI" \
0
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "extKeyUsage srv: codeSign,anyEKU -> OK" \
"$P_SRV key_file=$DATA_FILES_PATH/server5.key \
crt_file=$DATA_FILES_PATH/server5.eku-cs_any.crt" \
"$P_CLI" \
0
-requires_key_exchange_with_cert_in_tls12_or_tls13_enabled
run_test "extKeyUsage srv: codeSign -> fail" \
"$P_SRV key_file=$DATA_FILES_PATH/server5.key \
crt_file=$DATA_FILES_PATH/server5.eku-cli.crt" \
@@ -12262,7 +12255,7 @@
client_needs_more_time 2
run_test "DTLS proxy: 3d (drop, delay, duplicate), \"short\" PSK handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
- "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
+ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 \
psk=73776f726466697368" \
"$P_CLI dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 psk=73776f726466697368 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
diff --git a/tf-psa-crypto/drivers/builtin/include/mbedtls/bignum.h b/tf-psa-crypto/drivers/builtin/include/mbedtls/bignum.h
index 71d7b97..8367cd3 100644
--- a/tf-psa-crypto/drivers/builtin/include/mbedtls/bignum.h
+++ b/tf-psa-crypto/drivers/builtin/include/mbedtls/bignum.h
@@ -880,7 +880,7 @@
mbedtls_mpi_sint b);
/**
- * \brief Perform a sliding-window exponentiation: X = A^E mod N
+ * \brief Perform a modular exponentiation: X = A^E mod N
*
* \param X The destination MPI. This must point to an initialized MPI.
* This must not alias E or N.
diff --git a/tf-psa-crypto/drivers/builtin/src/bignum.c b/tf-psa-crypto/drivers/builtin/src/bignum.c
index c45fd5b..4244909 100644
--- a/tf-psa-crypto/drivers/builtin/src/bignum.c
+++ b/tf-psa-crypto/drivers/builtin/src/bignum.c
@@ -27,6 +27,7 @@
#include "mbedtls/bignum.h"
#include "bignum_core.h"
+#include "bignum_internal.h"
#include "bn_mul.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@@ -1610,9 +1611,13 @@
return 0;
}
-int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
- const mbedtls_mpi *E, const mbedtls_mpi *N,
- mbedtls_mpi *prec_RR)
+/*
+ * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
+ * this function is not constant time with respect to the exponent (parameter E).
+ */
+static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *E, int E_public,
+ const mbedtls_mpi *N, mbedtls_mpi *prec_RR)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -1695,7 +1700,11 @@
{
mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
- mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
+ if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
+ mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
+ } else {
+ mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
+ }
mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
}
@@ -1720,6 +1729,20 @@
return ret;
}
+int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *E, const mbedtls_mpi *N,
+ mbedtls_mpi *prec_RR)
+{
+ return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);
+}
+
+int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *E, const mbedtls_mpi *N,
+ mbedtls_mpi *prec_RR)
+{
+ return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
+}
+
/*
* Greatest common divisor: G = gcd(A, B) (HAC 14.54)
*/
diff --git a/tf-psa-crypto/drivers/builtin/src/bignum_core.c b/tf-psa-crypto/drivers/builtin/src/bignum_core.c
index 39ab6e9..60f48f9 100644
--- a/tf-psa-crypto/drivers/builtin/src/bignum_core.c
+++ b/tf-psa-crypto/drivers/builtin/src/bignum_core.c
@@ -747,8 +747,96 @@
}
}
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+void (*mbedtls_safe_codepath_hook)(void) = NULL;
+void (*mbedtls_unsafe_codepath_hook)(void) = NULL;
+#endif
+
+/*
+ * This function calculates the indices of the exponent where the exponentiation algorithm should
+ * start processing.
+ *
+ * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
+ * this function is not constant time with respect to the exponent (parameter E).
+ */
+static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E,
+ size_t E_limbs,
+ int E_public,
+ size_t *E_limb_index,
+ size_t *E_bit_index)
+{
+ if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
+ /*
+ * Skip leading zero bits.
+ */
+ size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);
+ if (E_bits == 0) {
+ /*
+ * If E is 0 mbedtls_mpi_core_bitlen() returns 0. Even if that is the case, we will want
+ * to represent it as a single 0 bit and as such the bitlength will be 1.
+ */
+ E_bits = 1;
+ }
+
+ *E_limb_index = E_bits / biL;
+ *E_bit_index = E_bits % biL;
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ if (mbedtls_unsafe_codepath_hook != NULL) {
+ mbedtls_unsafe_codepath_hook();
+ }
+#endif
+ } else {
+ /*
+ * Here we need to be constant time with respect to E and can't do anything better than
+ * start at the first allocated bit.
+ */
+ *E_limb_index = E_limbs;
+ *E_bit_index = 0;
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ if (mbedtls_safe_codepath_hook != NULL) {
+ mbedtls_safe_codepath_hook();
+ }
+#endif
+ }
+}
+
+/*
+ * Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is
+ * not constant time with respect to the window parameter and consequently the exponent of the
+ * exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe).
+ */
+static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect,
+ mbedtls_mpi_uint *Wtable,
+ size_t AN_limbs, size_t welem,
+ mbedtls_mpi_uint window,
+ int window_public)
+{
+ if (window_public == MBEDTLS_MPI_IS_PUBLIC) {
+ memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ if (mbedtls_unsafe_codepath_hook != NULL) {
+ mbedtls_unsafe_codepath_hook();
+ }
+#endif
+ } else {
+ /* Select Wtable[window] without leaking window through
+ * memory access patterns. */
+ mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
+ AN_limbs, welem, window);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ if (mbedtls_safe_codepath_hook != NULL) {
+ mbedtls_safe_codepath_hook();
+ }
+#endif
+ }
+}
+
/* Exponentiation: X := A^E mod N.
*
+ * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
+ * this function is not constant time with respect to the exponent (parameter E).
+ *
* A must already be in Montgomery form.
*
* As in other bignum functions, assume that AN_limbs and E_limbs are nonzero.
@@ -759,16 +847,25 @@
* (The difference is that the body in our loop processes a single bit instead
* of a full window.)
*/
-void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
- const mbedtls_mpi_uint *A,
- const mbedtls_mpi_uint *N,
- size_t AN_limbs,
- const mbedtls_mpi_uint *E,
- size_t E_limbs,
- const mbedtls_mpi_uint *RR,
- mbedtls_mpi_uint *T)
+static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X,
+ const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_uint *N,
+ size_t AN_limbs,
+ const mbedtls_mpi_uint *E,
+ size_t E_limbs,
+ int E_public,
+ const mbedtls_mpi_uint *RR,
+ mbedtls_mpi_uint *T)
{
- const size_t wsize = exp_mod_get_window_size(E_limbs * biL);
+ /* We'll process the bits of E from most significant
+ * (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
+ * (limb_index=0, E_bit_index=0). */
+ size_t E_limb_index = E_limbs;
+ size_t E_bit_index = 0;
+ exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public,
+ &E_limb_index, &E_bit_index);
+
+ const size_t wsize = exp_mod_get_window_size(E_limb_index * biL);
const size_t welem = ((size_t) 1) << wsize;
/* This is how we will use the temporary storage T, which must have space
@@ -787,7 +884,7 @@
const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N);
- /* Set Wtable[i] = A^(2^i) (in Montgomery representation) */
+ /* Set Wtable[i] = A^i (in Montgomery representation) */
exp_mod_precompute_window(A, N, AN_limbs,
mm, RR,
welem, Wtable, temp);
@@ -799,11 +896,6 @@
/* X = 1 (in Montgomery presentation) initially */
memcpy(X, Wtable, AN_limbs * ciL);
- /* We'll process the bits of E from most significant
- * (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
- * (limb_index=0, E_bit_index=0). */
- size_t E_limb_index = E_limbs;
- size_t E_bit_index = 0;
/* At any given time, window contains window_bits bits from E.
* window_bits can go up to wsize. */
size_t window_bits = 0;
@@ -829,10 +921,9 @@
* when we've finished processing the exponent. */
if (window_bits == wsize ||
(E_bit_index == 0 && E_limb_index == 0)) {
- /* Select Wtable[window] without leaking window through
- * memory access patterns. */
- mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
- AN_limbs, welem, window);
+
+ exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem,
+ window, E_public);
/* Multiply X by the selected element. */
mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm,
temp);
@@ -842,6 +933,42 @@
} while (!(E_bit_index == 0 && E_limb_index == 0));
}
+void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
+ const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_uint *N, size_t AN_limbs,
+ const mbedtls_mpi_uint *E, size_t E_limbs,
+ const mbedtls_mpi_uint *RR,
+ mbedtls_mpi_uint *T)
+{
+ mbedtls_mpi_core_exp_mod_optionally_safe(X,
+ A,
+ N,
+ AN_limbs,
+ E,
+ E_limbs,
+ MBEDTLS_MPI_IS_SECRET,
+ RR,
+ T);
+}
+
+void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
+ const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_uint *N, size_t AN_limbs,
+ const mbedtls_mpi_uint *E, size_t E_limbs,
+ const mbedtls_mpi_uint *RR,
+ mbedtls_mpi_uint *T)
+{
+ mbedtls_mpi_core_exp_mod_optionally_safe(X,
+ A,
+ N,
+ AN_limbs,
+ E,
+ E_limbs,
+ MBEDTLS_MPI_IS_PUBLIC,
+ RR,
+ T);
+}
+
mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
mbedtls_mpi_uint c, /* doubles as carry */
diff --git a/tf-psa-crypto/drivers/builtin/src/bignum_core.h b/tf-psa-crypto/drivers/builtin/src/bignum_core.h
index 51ecca5..484fa8c 100644
--- a/tf-psa-crypto/drivers/builtin/src/bignum_core.h
+++ b/tf-psa-crypto/drivers/builtin/src/bignum_core.h
@@ -70,9 +70,7 @@
#include "common.h"
-#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
-#endif
#include "constant_time_internal.h"
@@ -90,6 +88,34 @@
#define GET_BYTE(X, i) \
(((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff)
+/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by
+ * this constant, the function must be constant time with respect to the parameter.
+ *
+ * This is only needed for functions with the _optionally_safe postfix. All other functions have
+ * fixed behavior that can't be changed at runtime and are constant time with respect to their
+ * parameters as prescribed by their documentation or by conventions in their module's documentation.
+ *
+ * Parameters should be named X_public where X is the name of the
+ * corresponding input parameter.
+ *
+ * Implementation should always check using
+ * if (X_public == MBEDTLS_MPI_IS_PUBLIC) {
+ * // unsafe path
+ * } else {
+ * // safe path
+ * }
+ * not the other way round, in order to prevent misuse. (That is, if a value
+ * other than the two below is passed, default to the safe path.)
+ *
+ * The value of MBEDTLS_MPI_IS_PUBLIC is chosen in a way that is unlikely to happen by accident, but
+ * which can be used as an immediate value in a Thumb2 comparison (for code size). */
+#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a2a2a
+#define MBEDTLS_MPI_IS_SECRET 0
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+// Default value for testing that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
+#define MBEDTLS_MPI_IS_TEST 1
+#endif
+
/** Count leading zero bits in a given integer.
*
* \warning The result is undefined if \p a == 0
@@ -615,6 +641,42 @@
size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs);
/**
+ * \brief Perform a modular exponentiation with public or secret exponent:
+ * X = A^E mod N, where \p A is already in Montgomery form.
+ *
+ * \warning This function is not constant time with respect to \p E (the exponent).
+ *
+ * \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs ==
+ * \p AN_limbs.
+ *
+ * \param[out] X The destination MPI, as a little endian array of length
+ * \p AN_limbs.
+ * \param[in] A The base MPI, as a little endian array of length \p AN_limbs.
+ * Must be in Montgomery form.
+ * \param[in] N The modulus, as a little endian array of length \p AN_limbs.
+ * \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR.
+ * \param[in] E The exponent, as a little endian array of length \p E_limbs.
+ * \param E_limbs The number of limbs in \p E.
+ * \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little
+ * endian array of length \p AN_limbs.
+ * \param[in,out] T Temporary storage of at least the number of limbs returned
+ * by `mbedtls_mpi_core_exp_mod_working_limbs()`.
+ * Its initial content is unused and its final content is
+ * indeterminate.
+ * It must not alias or otherwise overlap any of the other
+ * parameters.
+ * It is up to the caller to zeroize \p T when it is no
+ * longer needed, and before freeing it if it was dynamically
+ * allocated.
+ */
+void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
+ const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_uint *N, size_t AN_limbs,
+ const mbedtls_mpi_uint *E, size_t E_limbs,
+ const mbedtls_mpi_uint *RR,
+ mbedtls_mpi_uint *T);
+
+/**
* \brief Perform a modular exponentiation with secret exponent:
* X = A^E mod N, where \p A is already in Montgomery form.
*
diff --git a/tf-psa-crypto/drivers/builtin/src/bignum_core_invasive.h b/tf-psa-crypto/drivers/builtin/src/bignum_core_invasive.h
new file mode 100644
index 0000000..167099d
--- /dev/null
+++ b/tf-psa-crypto/drivers/builtin/src/bignum_core_invasive.h
@@ -0,0 +1,23 @@
+/**
+ * \file bignum_core_invasive.h
+ *
+ * \brief Function declarations for invasive functions of bignum core.
+ */
+/**
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef MBEDTLS_BIGNUM_CORE_INVASIVE_H
+#define MBEDTLS_BIGNUM_CORE_INVASIVE_H
+
+#include "bignum_core.h"
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+
+extern void (*mbedtls_safe_codepath_hook)(void);
+extern void (*mbedtls_unsafe_codepath_hook)(void);
+
+#endif /* MBEDTLS_TEST_HOOKS && !MBEDTLS_THREADING_C */
+
+#endif /* MBEDTLS_BIGNUM_CORE_INVASIVE_H */
diff --git a/tf-psa-crypto/drivers/builtin/src/bignum_internal.h b/tf-psa-crypto/drivers/builtin/src/bignum_internal.h
new file mode 100644
index 0000000..aceaf55
--- /dev/null
+++ b/tf-psa-crypto/drivers/builtin/src/bignum_internal.h
@@ -0,0 +1,50 @@
+/**
+ * \file bignum_internal.h
+ *
+ * \brief Internal-only bignum public-key cryptosystem API.
+ *
+ * This file declares bignum-related functions that are to be used
+ * only from within the Mbed TLS library itself.
+ *
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+#ifndef MBEDTLS_BIGNUM_INTERNAL_H
+#define MBEDTLS_BIGNUM_INTERNAL_H
+
+/**
+ * \brief Perform a modular exponentiation: X = A^E mod N
+ *
+ * \warning This function is not constant time with respect to \p E (the exponent).
+ *
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * This must not alias E or N.
+ * \param A The base of the exponentiation.
+ * This must point to an initialized MPI.
+ * \param E The exponent MPI. This must point to an initialized MPI.
+ * \param N The base for the modular reduction. This must point to an
+ * initialized MPI.
+ * \param prec_RR A helper MPI depending solely on \p N which can be used to
+ * speed-up multiple modular exponentiations for the same value
+ * of \p N. This may be \c NULL. If it is not \c NULL, it must
+ * point to an initialized MPI. If it hasn't been used after
+ * the call to mbedtls_mpi_init(), this function will compute
+ * the helper value and store it in \p prec_RR for reuse on
+ * subsequent calls to this function. Otherwise, the function
+ * will assume that \p prec_RR holds the helper value set by a
+ * previous call to mbedtls_mpi_exp_mod(), and reuse it.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or
+ * even, or if \c E is negative.
+ * \return Another negative error code on different kinds of failures.
+ *
+ */
+int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
+ const mbedtls_mpi *E, const mbedtls_mpi *N,
+ mbedtls_mpi *prec_RR);
+
+#endif /* bignum_internal.h */
diff --git a/tf-psa-crypto/drivers/builtin/src/ccm.c b/tf-psa-crypto/drivers/builtin/src/ccm.c
index 2503e9f..68af903 100644
--- a/tf-psa-crypto/drivers/builtin/src/ccm.c
+++ b/tf-psa-crypto/drivers/builtin/src/ccm.c
@@ -167,11 +167,12 @@
}
/* CCM expects non-empty tag.
- * CCM* allows empty tag. For CCM* without tag, ignore plaintext length.
+ * CCM* allows empty tag. For CCM* without tag, the tag calculation is skipped.
*/
if (ctx->tag_len == 0) {
if (ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT || ctx->mode == MBEDTLS_CCM_STAR_DECRYPT) {
ctx->plaintext_len = 0;
+ return 0;
} else {
return MBEDTLS_ERR_CCM_BAD_INPUT;
}
diff --git a/tf-psa-crypto/drivers/builtin/src/rsa.c b/tf-psa-crypto/drivers/builtin/src/rsa.c
index 5e7e762..33bb1d3 100644
--- a/tf-psa-crypto/drivers/builtin/src/rsa.c
+++ b/tf-psa-crypto/drivers/builtin/src/rsa.c
@@ -29,6 +29,7 @@
#include "mbedtls/rsa.h"
#include "bignum_core.h"
+#include "bignum_internal.h"
#include "rsa_alt_helpers.h"
#include "rsa_internal.h"
#include "mbedtls/oid.h"
@@ -1257,7 +1258,7 @@
}
olen = ctx->len;
- MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
+ MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod_unsafe(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
cleanup:
diff --git a/tf-psa-crypto/scripts/project_name.txt b/tf-psa-crypto/scripts/project_name.txt
new file mode 100644
index 0000000..94a73fa
--- /dev/null
+++ b/tf-psa-crypto/scripts/project_name.txt
@@ -0,0 +1 @@
+TF-PSA-Crypto
diff --git a/tf-psa-crypto/tests/suites/test_suite_bignum.function b/tf-psa-crypto/tests/suites/test_suite_bignum.function
index 1830e5a..3d2b8a1 100644
--- a/tf-psa-crypto/tests/suites/test_suite_bignum.function
+++ b/tf-psa-crypto/tests/suites/test_suite_bignum.function
@@ -3,7 +3,9 @@
#include "mbedtls/entropy.h"
#include "constant_time_internal.h"
#include "bignum_core.h"
+#include "bignum_internal.h"
#include "test/constant_flow.h"
+#include "test/bignum_codepath_check.h"
#if MBEDTLS_MPI_MAX_BITS > 792
#define MPI_MAX_BITS_LARGER_THAN_792
@@ -988,7 +990,13 @@
* against a smaller RR. */
TEST_LE_U(RR.n, N.n - 1);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, res, E);
+#endif
/* We know that exp_mod internally needs RR to be as large as N.
* Validate that it is the case now, otherwise there was probably
* a buffer overread. */
@@ -1021,7 +1029,26 @@
TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, res, E);
+#endif
+ TEST_ASSERT(res == exp_result);
+ if (res == 0) {
+ TEST_ASSERT(sign_is_valid(&Z));
+ TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
+ }
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
+ res = mbedtls_mpi_exp_mod_unsafe(&Z, &A, &E, &N, NULL);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_PUBLIC, res, E);
+#endif
TEST_ASSERT(res == exp_result);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&Z));
@@ -1029,7 +1056,13 @@
}
/* Now test again with the speed-up parameter supplied as an output. */
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, res, E);
+#endif
TEST_ASSERT(res == exp_result);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&Z));
@@ -1037,7 +1070,13 @@
}
/* Now test again with the speed-up parameter supplied in calculated form. */
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, res, E);
+#endif
TEST_ASSERT(res == exp_result);
if (res == 0) {
TEST_ASSERT(sign_is_valid(&Z));
@@ -1077,7 +1116,21 @@
TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
}
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, exp_result, E);
+#endif
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
+ TEST_ASSERT(mbedtls_mpi_exp_mod_unsafe(&Z, &A, &E, &N, &RR) == exp_result);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_PUBLIC, exp_result, E);
+#endif
exit:
mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
diff --git a/tf-psa-crypto/tests/suites/test_suite_bignum_core.function b/tf-psa-crypto/tests/suites/test_suite_bignum_core.function
index 6c0bd1e..c755287 100644
--- a/tf-psa-crypto/tests/suites/test_suite_bignum_core.function
+++ b/tf-psa-crypto/tests/suites/test_suite_bignum_core.function
@@ -4,6 +4,7 @@
#include "bignum_core.h"
#include "constant_time_internal.h"
#include "test/constant_flow.h"
+#include "test/bignum_codepath_check.h"
/** Verifies mbedtls_mpi_core_add().
*
@@ -1246,6 +1247,7 @@
char *input_E, char *input_X)
{
mbedtls_mpi_uint *A = NULL;
+ mbedtls_mpi_uint *A_copy = NULL;
mbedtls_mpi_uint *E = NULL;
mbedtls_mpi_uint *N = NULL;
mbedtls_mpi_uint *X = NULL;
@@ -1297,6 +1299,7 @@
TEST_CALLOC(T, working_limbs);
+ /* Test the safe variant */
TEST_CF_SECRET(A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_CF_SECRET(N, N_limbs * sizeof(mbedtls_mpi_uint));
TEST_CF_SECRET(E, E_limbs * sizeof(mbedtls_mpi_uint));
@@ -1304,22 +1307,48 @@
mbedtls_mpi_core_exp_mod(Y, A, N, N_limbs, E, E_limbs, R2, T);
TEST_CF_PUBLIC(Y, N_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint)));
+
+ /* Test the unsafe variant */
+ TEST_CF_PUBLIC(A, A_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_CF_PUBLIC(N, N_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_CF_PUBLIC(E, E_limbs * sizeof(mbedtls_mpi_uint));
+
+ mbedtls_mpi_core_exp_mod_unsafe(Y, A, N, N_limbs, E, E_limbs, R2, T);
TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint)));
+ /*
+ * Check both with output aliased to input
+ */
+
+ TEST_CALLOC(A_copy, A_limbs);
+ memcpy(A_copy, A, sizeof(*A_copy) * A_limbs); // save A
+
+ /* Safe */
TEST_CF_SECRET(A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_CF_SECRET(N, N_limbs * sizeof(mbedtls_mpi_uint));
TEST_CF_SECRET(E, E_limbs * sizeof(mbedtls_mpi_uint));
- /* Check when output aliased to input */
mbedtls_mpi_core_exp_mod(A, A, N, N_limbs, E, E_limbs, R2, T);
TEST_CF_PUBLIC(A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint)));
+ /* Unsafe */
+ memcpy(A, A_copy, sizeof(*A) * A_limbs); // restore A
+ TEST_CF_PUBLIC(A, A_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_CF_PUBLIC(N, N_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_CF_PUBLIC(E, E_limbs * sizeof(mbedtls_mpi_uint));
+
+ mbedtls_mpi_core_exp_mod_unsafe(A, A, N, N_limbs, E, E_limbs, R2, T);
+
+ TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint)));
+
exit:
mbedtls_free(T);
mbedtls_free(A);
+ mbedtls_free(A_copy);
mbedtls_free(E);
mbedtls_free(N);
mbedtls_free(X);
diff --git a/tf-psa-crypto/tests/suites/test_suite_rsa.function b/tf-psa-crypto/tests/suites/test_suite_rsa.function
index e824529..98ea9ef 100644
--- a/tf-psa-crypto/tests/suites/test_suite_rsa.function
+++ b/tf-psa-crypto/tests/suites/test_suite_rsa.function
@@ -1,7 +1,9 @@
/* BEGIN_HEADER */
#include "mbedtls/rsa.h"
+#include "bignum_core.h"
#include "rsa_alt_helpers.h"
#include "rsa_internal.h"
+#include "test/bignum_codepath_check.h"
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -489,7 +491,13 @@
TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
TEST_ASSERT(mbedtls_rsa_public(&ctx, message_str->x, output) == result);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_RSA_CODEPATH(MBEDTLS_MPI_IS_PUBLIC, result);
+#endif
if (result == 0) {
TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
@@ -554,9 +562,15 @@
/* repeat three times to test updating of blinding values */
for (i = 0; i < 3; i++) {
memset(output, 0x00, sizeof(output));
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ mbedtls_codepath_reset();
+#endif
TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_pseudo_rand,
&rnd_info, message_str->x,
output) == result);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+ ASSERT_RSA_CODEPATH(MBEDTLS_MPI_IS_SECRET, result);
+#endif
if (result == 0) {
TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
diff --git a/tf-psa-crypto/tests/suites/test_suite_version.data b/tf-psa-crypto/tests/suites/test_suite_version.data
index 0edee96..3a21f1b 100644
--- a/tf-psa-crypto/tests/suites/test_suite_version.data
+++ b/tf-psa-crypto/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
Check compile time library version
-check_compiletime_version:"3.6.0"
+check_compiletime_version:"4.0.0"
Check runtime library version
-check_runtime_version:"3.6.0"
+check_runtime_version:"4.0.0"
Check for MBEDTLS_VERSION_C
check_feature:"MBEDTLS_VERSION_C":0