Merge pull request #3953 from gilles-peskine-arm/python-mypy-mkdir
Python upscale: pass mypy and create library directory
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ac24bf4..fdaa2f1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,18 @@
#
cmake_minimum_required(VERSION 2.8.12)
+
+# https://cmake.org/cmake/help/latest/policy/CMP0011.html
+# Setting this policy is required in CMake >= 3.18.0, otherwise a warning is generated. The OLD
+# policy setting is deprecated, and will be removed in future versions.
+cmake_policy(SET CMP0011 NEW)
+# https://cmake.org/cmake/help/latest/policy/CMP0012.html
+# Setting the CMP0012 policy to NEW is required for FindPython3 to work with CMake 3.18.2
+# (there is a bug in this particular version), otherwise, setting the CMP0012 policy is required
+# for CMake versions >= 3.18.3 otherwise a deprecated warning is generated. The OLD policy setting
+# is deprecated and will be removed in future versions.
+cmake_policy(SET CMP0012 NEW)
+
if(TEST_CPP)
project("mbed TLS" C CXX)
else()
diff --git a/ChangeLog b/ChangeLog
index 594c3cf..fb231aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,171 @@
mbed TLS ChangeLog (Sorted per branch, date)
+= mbed TLS 2.25.0 branch released 2020-12-11
+
+API changes
+ * The numerical values of the PSA Crypto API macros have been updated to
+ conform to version 1.0.0 of the specification.
+ * PSA_ALG_STREAM_CIPHER replaces PSA_ALG_CHACHA20 and PSA_ALG_ARC4.
+ The underlying stream cipher is determined by the key type
+ (PSA_KEY_TYPE_CHACHA20 or PSA_KEY_TYPE_ARC4).
+ * The functions mbedtls_cipher_auth_encrypt() and
+ mbedtls_cipher_auth_decrypt() no longer accept NIST_KW contexts,
+ as they have no way to check if the output buffer is large enough.
+ Please use mbedtls_cipher_auth_encrypt_ext() and
+ mbedtls_cipher_auth_decrypt_ext() instead. Credit to OSS-Fuzz and
+ Cryptofuzz. Fixes #3665.
+
+Requirement changes
+ * Update the minimum required CMake version to 2.8.12. This silences a
+ warning on CMake 3.19.0. #3801
+
+New deprecations
+ * PSA_KEY_TYPE_CHACHA20 and PSA_KEY_TYPE_ARC4 have been deprecated.
+ Use PSA_ALG_STREAM_CIPHER instead.
+ * The functions mbedtls_cipher_auth_encrypt() and
+ mbedtls_cipher_auth_decrypt() are deprecated in favour of the new
+ functions mbedtls_cipher_auth_encrypt_ext() and
+ mbedtls_cipher_auth_decrypt_ext(). Please note that with AEAD ciphers,
+ these new functions always append the tag to the ciphertext, and include
+ the tag in the ciphertext length.
+
+Features
+ * Partial implementation of the new PSA Crypto accelerator APIs. (Symmetric
+ ciphers, asymmetric signing/verification and key generation, validate_key
+ entry point, and export_public_key interface.)
+ * Add support for ECB to the PSA cipher API.
+ * In PSA, allow using a key declared with a base key agreement algorithm
+ in combined key agreement and derivation operations, as long as the key
+ agreement algorithm in use matches the algorithm the key was declared with.
+ This is currently non-standard behaviour, but expected to make it into a
+ future revision of the PSA Crypto standard.
+ * Add MBEDTLS_TARGET_PREFIX CMake variable, which is prefixed to the mbedtls,
+ mbedcrypto, mbedx509 and apidoc CMake target names. This can be used by
+ external CMake projects that include this one to avoid CMake target name
+ clashes. The default value of this variable is "", so default target names
+ are unchanged.
+ * Add support for DTLS-SRTP as defined in RFC 5764. Contributed by Johan
+ Pascal, improved by Ron Eldor.
+ * In the PSA API, it is no longer necessary to open persistent keys:
+ operations now accept the key identifier. The type psa_key_handle_t is now
+ identical to psa_key_id_t instead of being platform-defined. This bridges
+ the last major gap to compliance with the PSA Cryptography specification
+ version 1.0.0. Opening persistent keys is still supported for backward
+ compatibility, but will be deprecated and later removed in future
+ releases.
+ * PSA_AEAD_NONCE_LENGTH, PSA_AEAD_NONCE_MAX_SIZE, PSA_CIPHER_IV_LENGTH and
+ PSA_CIPHER_IV_MAX_SIZE macros have been added as defined in version
+ 1.0.0 of the PSA Crypto API specification.
+
+Security
+ * The functions mbedtls_cipher_auth_encrypt() and
+ mbedtls_cipher_auth_decrypt() would write past the minimum documented
+ size of the output buffer when used with NIST_KW. As a result, code using
+ those functions as documented with NIST_KW could have a buffer overwrite
+ of up to 15 bytes, with consequences ranging up to arbitrary code
+ execution depending on the location of the output buffer.
+ * Limit the size of calculations performed by mbedtls_mpi_exp_mod to
+ MBEDTLS_MPI_MAX_SIZE to prevent a potential denial of service when
+ generating Diffie-Hellman key pairs. Credit to OSS-Fuzz.
+ * A failure of the random generator was ignored in mbedtls_mpi_fill_random(),
+ which is how most uses of randomization in asymmetric cryptography
+ (including key generation, intermediate value randomization and blinding)
+ are implemented. This could cause failures or the silent use of non-random
+ values. A random generator can fail if it needs reseeding and cannot not
+ obtain entropy, or due to an internal failure (which, for Mbed TLS's own
+ CTR_DRBG or HMAC_DRBG, can only happen due to a misconfiguration).
+ * Fix a compliance issue whereby we were not checking the tag on the
+ algorithm parameters (only the size) when comparing the signature in the
+ description part of the cert to the real signature. This meant that a
+ NULL algorithm parameters entry would look identical to an array of REAL
+ (size zero) to the library and thus the certificate would be considered
+ valid. However, if the parameters do not match in *any* way then the
+ certificate should be considered invalid, and indeed OpenSSL marks these
+ certs as invalid when mbedtls did not.
+ Many thanks to guidovranken who found this issue via differential fuzzing
+ and reported it in #3629.
+ * Zeroising of local buffers and variables which are used for calculations
+ in mbedtls_pkcs5_pbkdf2_hmac(), mbedtls_internal_sha*_process(),
+ mbedtls_internal_md*_process() and mbedtls_internal_ripemd160_process()
+ functions to erase sensitive data from memory. Reported by
+ Johan Malmgren and Johan Uppman Bruce from Sectra.
+
+Bugfix
+ * Fix an invalid (but nonzero) return code from mbedtls_pk_parse_subpubkey()
+ when the input has trailing garbage. Fixes #2512.
+ * Fix build failure in configurations where MBEDTLS_USE_PSA_CRYPTO is
+ enabled but ECDSA is disabled. Contributed by jdurkop. Fixes #3294.
+ * Include the psa_constant_names generated source code in the source tree
+ instead of generating it at build time. Fixes #3524.
+ * Fix rsa_prepare_blinding() to retry when the blinding value is not
+ invertible (mod N), instead of returning MBEDTLS_ERR_RSA_RNG_FAILED. This
+ addresses a regression but is rare in practice (approx. 1 in 2/sqrt(N)).
+ Found by Synopsys Coverity, fix contributed by Peter Kolbus (Garmin).
+ Fixes #3647.
+ * Use socklen_t on Android and other POSIX-compliant system
+ * Fix the build when the macro _GNU_SOURCE is defined to a non-empty value.
+ Fix #3432.
+ * Consistently return PSA_ERROR_INVALID_ARGUMENT on invalid cipher input
+ sizes (instead of PSA_ERROR_BAD_STATE in some cases) to make the
+ psa_cipher_* functions compliant with the PSA Crypto API specification.
+ * mbedtls_ecp_curve_list() now lists Curve25519 and Curve448 under the names
+ "x25519" and "x448". These curves support ECDH but not ECDSA. If you need
+ only the curves that support ECDSA, filter the list with
+ mbedtls_ecdsa_can_do().
+ * Fix psa_generate_key() returning an error when asked to generate
+ an ECC key pair on Curve25519 or secp244k1.
+ * Fix psa_key_derivation_output_key() to allow the output of a combined key
+ agreement and subsequent key derivation operation to be used as a key
+ inside of the PSA Crypto core.
+ * Fix handling of EOF against 0xff bytes and on platforms with unsigned
+ chars. Fixes a build failure on platforms where char is unsigned. Fixes
+ #3794.
+ * Fix an off-by-one error in the additional data length check for
+ CCM, which allowed encryption with a non-standard length field.
+ Fixes #3719.
+ * Correct the default IV size for mbedtls_cipher_info_t structures using
+ MBEDTLS_MODE_ECB to 0, since ECB mode ciphers don't use IVs.
+ * Make arc4random_buf available on NetBSD and OpenBSD when _POSIX_C_SOURCE is
+ defined. Fix contributed in #3571.
+ * Fix conditions for including string.h in error.c. Fixes #3866.
+ * psa_set_key_id() now also sets the lifetime to persistent for keys located
+ in a secure element.
+ * Attempting to create a volatile key with a non-zero key identifier now
+ fails. Previously the key identifier was just ignored when creating a
+ volatile key.
+ * Attempting to create or register a key with a key identifier in the vendor
+ range now fails.
+ * Fix build failures on GCC 11. Fixes #3782.
+ * Add missing arguments of debug message in mbedtls_ssl_decrypt_buf.
+ * Fix a memory leak in mbedtls_mpi_sub_abs() when the result was negative
+ (an error condition) and the second operand was aliased to the result.
+ * Fix a case in elliptic curve arithmetic where an out-of-memory condition
+ could go undetected, resulting in an incorrect result.
+ * In CTR_DRBG and HMAC_DRBG, don't reset the reseed interval in seed().
+ Fixes #2927.
+ * In PEM writing functions, fill the trailing part of the buffer with null
+ bytes. This guarantees that the corresponding parsing function can read
+ the buffer back, which was the case for mbedtls_x509write_{crt,csr}_pem
+ until this property was inadvertently broken in Mbed TLS 2.19.0.
+ Fixes #3682.
+ * Fix a build failure that occurred with the MBEDTLS_AES_SETKEY_DEC_ALT
+ option on. In this configuration key management methods that are required
+ for MBEDTLS_CIPHER_MODE_XTS were excluded from the build and made it fail.
+ Fixes #3818. Reported by John Stroebel.
+
+Changes
+ * Reduce stack usage significantly during sliding window exponentiation.
+ Reported in #3591 and fix contributed in #3592 by Daniel Otte.
+ * The PSA persistent storage format is updated to always store the key bits
+ attribute. No automatic upgrade path is provided. Previously stored keys
+ must be erased, or manually upgraded based on the key storage format
+ specification (docs/architecture/mbed-crypto-storage-specification.md).
+ Fixes #3740.
+ * Remove the zeroization of a pointer variable in AES rounds. It was valid
+ but spurious and misleading since it looked like a mistaken attempt to
+ zeroize the pointed-to buffer. Reported by Antonio de la Piedra, CEA
+ Leti, France.
+
= mbed TLS 2.24.0 branch released 2020-09-01
API changes
diff --git a/ChangeLog.d/_GNU_SOURCE-redefined.txt b/ChangeLog.d/_GNU_SOURCE-redefined.txt
deleted file mode 100644
index 59c8a15..0000000
--- a/ChangeLog.d/_GNU_SOURCE-redefined.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix the build when the macro _GNU_SOURCE is defined to a non-empty value.
- Fix #3432.
diff --git a/ChangeLog.d/add-aes-ecb-to-psa.txt b/ChangeLog.d/add-aes-ecb-to-psa.txt
deleted file mode 100644
index b0de67c..0000000
--- a/ChangeLog.d/add-aes-ecb-to-psa.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Features
- * Add support for ECB to the PSA cipher API.
diff --git a/ChangeLog.d/add_MBEDTLS_TARGET_PREFIX_to_cmake.txt b/ChangeLog.d/add_MBEDTLS_TARGET_PREFIX_to_cmake.txt
deleted file mode 100644
index 533f309..0000000
--- a/ChangeLog.d/add_MBEDTLS_TARGET_PREFIX_to_cmake.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Features
- * Add MBEDTLS_TARGET_PREFIX CMake variable, which is prefixed to the mbedtls,
- mbedcrypto, mbedx509 and apidoc CMake target names. This can be used by
- external CMake projects that include this one to avoid CMake target name
- clashes. The default value of this variable is "", so default target names
- are unchanged.
diff --git a/ChangeLog.d/add_cipher_transparent_driver.txt b/ChangeLog.d/add_cipher_transparent_driver.txt
deleted file mode 100644
index ce6f33d..0000000
--- a/ChangeLog.d/add_cipher_transparent_driver.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Features
- * Partial implementation of the new PSA Crypto accelerator APIs for
- enabling symmetric cipher acceleration through crypto accelerators.
- Contributed by Steven Cooreman in #3644.
diff --git a/ChangeLog.d/add_export_public_key_driver.txt b/ChangeLog.d/add_export_public_key_driver.txt
deleted file mode 100644
index a9bffbc..0000000
--- a/ChangeLog.d/add_export_public_key_driver.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Features
- * Implementation of the export_public_key interface for PSA Crypto
- accelerator drivers, as defined in #3493. Contributed in #3786.
diff --git a/ChangeLog.d/add_sign_verify_keygen_transparent_driver.txt b/ChangeLog.d/add_sign_verify_keygen_transparent_driver.txt
deleted file mode 100644
index fe43899..0000000
--- a/ChangeLog.d/add_sign_verify_keygen_transparent_driver.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Features
- * Partial implementation of the new PSA Crypto accelerator APIs for
- enabling key generation and asymmetric signing/verification through crypto
- accelerators. Contributed by Steven Cooreman in #3501.
diff --git a/ChangeLog.d/adjusting sliding_window_size_PR3592.txt b/ChangeLog.d/adjusting sliding_window_size_PR3592.txt
deleted file mode 100644
index 6089565..0000000
--- a/ChangeLog.d/adjusting sliding_window_size_PR3592.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Changes
- * Reduce stack usage significantly during sliding window exponentiation.
- Reported in #3591 and fix contributed in #3592 by Daniel Otte.
diff --git a/ChangeLog.d/aes-zeroize-pointer.txt b/ChangeLog.d/aes-zeroize-pointer.txt
deleted file mode 100644
index ccc6dc1..0000000
--- a/ChangeLog.d/aes-zeroize-pointer.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Changes
- * Remove the zeroization of a pointer variable in AES rounds. It was valid
- but spurious and misleading since it looked like a mistaken attempt to
- zeroize the pointed-to buffer. Reported by Antonio de la Piedra, CEA
- Leti, France.
diff --git a/ChangeLog.d/android-socklen_t.txt b/ChangeLog.d/android-socklen_t.txt
deleted file mode 100644
index d795a52..0000000
--- a/ChangeLog.d/android-socklen_t.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Use socklen_t on Android and other POSIX-compliant system
-
diff --git a/ChangeLog.d/arc4random_buf-implicit.txt b/ChangeLog.d/arc4random_buf-implicit.txt
deleted file mode 100644
index 81c245e..0000000
--- a/ChangeLog.d/arc4random_buf-implicit.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Make arc4random_buf available on NetBSD and OpenBSD when _POSIX_C_SOURCE is
- defined. Fix contributed in #3571.
diff --git a/ChangeLog.d/bugfix-2927.txt b/ChangeLog.d/bugfix-2927.txt
deleted file mode 100644
index 2213c6e..0000000
--- a/ChangeLog.d/bugfix-2927.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * In CTR_DRBG and HMAC_DRBG, don't reset the reseed interval in seed().
- Fixes #2927.
diff --git a/ChangeLog.d/bugfix_3524.txt b/ChangeLog.d/bugfix_3524.txt
deleted file mode 100644
index e038340..0000000
--- a/ChangeLog.d/bugfix_3524.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Include the psa_constant_names generated source code in the source tree
- instead of generating it at build time. Fixes #3524.
diff --git a/ChangeLog.d/bugfix_3782.txt b/ChangeLog.d/bugfix_3782.txt
deleted file mode 100644
index 25e18cb..0000000
--- a/ChangeLog.d/bugfix_3782.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Bugfix
- * Fix build failures on GCC 11. Fixes #3782.
diff --git a/ChangeLog.d/bugfix_3794.txt b/ChangeLog.d/bugfix_3794.txt
deleted file mode 100644
index a483ea7..0000000
--- a/ChangeLog.d/bugfix_3794.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix handling of EOF against 0xff bytes and on platforms with
- unsigned chars. Fixes a build failure on platforms where char is
- unsigned. Fixes #3794.
diff --git a/ChangeLog.d/bugfix_PR3294.txt b/ChangeLog.d/bugfix_PR3294.txt
deleted file mode 100644
index a6ea75e..0000000
--- a/ChangeLog.d/bugfix_PR3294.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix build failure in configurations where MBEDTLS_USE_PSA_CRYPTO is
- enabled but ECDSA is disabled. Contributed by jdurkop. Fixes #3294.
-
diff --git a/ChangeLog.d/clean_pem_buffers.txt b/ChangeLog.d/clean_pem_buffers.txt
deleted file mode 100644
index 818fad9..0000000
--- a/ChangeLog.d/clean_pem_buffers.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Bugfix
- * In PEM writing functions, fill the trailing part of the buffer with null
- bytes. This guarantees that the corresponding parsing function can read
- the buffer back, which was the case for mbedtls_x509write_{crt,csr}_pem
- until this property was inadvertently broken in Mbed TLS 2.19.0.
- Fixes #3682.
diff --git a/ChangeLog.d/ecb_iv_fix.txt b/ChangeLog.d/ecb_iv_fix.txt
deleted file mode 100644
index ae2ae25..0000000
--- a/ChangeLog.d/ecb_iv_fix.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Correct the default IV size for mbedtls_cipher_info_t structures using
- MBEDTLS_MODE_ECB to 0, since ECB mode ciphers don't use IVs.
diff --git a/ChangeLog.d/ecp-bignum-error-checks.txt b/ChangeLog.d/ecp-bignum-error-checks.txt
deleted file mode 100644
index 8cad08e..0000000
--- a/ChangeLog.d/ecp-bignum-error-checks.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
- * Fix a memory leak in mbedtls_mpi_sub_abs() when the result was negative
- (an error condition) and the second operand was aliased to the result.
- * Fix a case in elliptic curve arithmetic where an out-of-memory condition
- could go undetected, resulting in an incorrect result.
diff --git a/ChangeLog.d/ecp_curve_list.txt b/ChangeLog.d/ecp_curve_list.txt
deleted file mode 100644
index 55745d3..0000000
--- a/ChangeLog.d/ecp_curve_list.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
- * mbedtls_ecp_curve_list() now lists Curve25519 and Curve448 under the names
- "x25519" and "x448". These curves support ECDH but not ECDSA. If you need
- only the curves that support ECDSA, filter the list with
- mbedtls_ecdsa_can_do().
diff --git a/ChangeLog.d/error-include-string.txt b/ChangeLog.d/error-include-string.txt
deleted file mode 100644
index 0a12c7b..0000000
--- a/ChangeLog.d/error-include-string.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Bugfix
- * Fix conditions for including string.h in error.c. Fixes #3866.
diff --git a/ChangeLog.d/feature-dtls-srtp.txt b/ChangeLog.d/feature-dtls-srtp.txt
deleted file mode 100644
index 8b9186b..0000000
--- a/ChangeLog.d/feature-dtls-srtp.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Features
-* Add support for DTLS-SRTP as defined in RFC 5764. Contributed by Johan Pascal, improved by Ron Eldor.
diff --git a/ChangeLog.d/fix-rsa-blinding.txt b/ChangeLog.d/fix-rsa-blinding.txt
deleted file mode 100644
index a13572c..0000000
--- a/ChangeLog.d/fix-rsa-blinding.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Bugfix
- * Fix rsa_prepare_blinding() to retry when the blinding value is not
- invertible (mod N), instead of returning MBEDTLS_ERR_RSA_RNG_FAILED. This
- addresses a regression but is rare in practice (approx. 1 in 2/sqrt(N)).
- Found by Synopsys Coverity, fix contributed by Peter Kolbus (Garmin).
- Fixes #3647.
diff --git a/ChangeLog.d/fix_ccm_add_length_check.txt b/ChangeLog.d/fix_ccm_add_length_check.txt
deleted file mode 100644
index 259399f..0000000
--- a/ChangeLog.d/fix_ccm_add_length_check.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
- * Fix an off-by-one error in the additional data length check for
- CCM, which allowed encryption with a non-standard length field.
- Fixes #3719.
-
diff --git a/ChangeLog.d/issue3819.txt b/ChangeLog.d/issue3819.txt
new file mode 100644
index 0000000..e41520f
--- /dev/null
+++ b/ChangeLog.d/issue3819.txt
@@ -0,0 +1,10 @@
+Security
+ * Fix a security reduction in CTR_DRBG when the initial seeding obtained a
+ nonce from entropy. Applications were affected if they called
+ mbedtls_ctr_drbg_set_nonce_len(), if they called
+ mbedtls_ctr_drbg_set_entropy_len() with a size that was 3/2 times the key
+ length, or when the entropy module uses SHA-256 and CTR_DRBG uses AES-256.
+ In such cases, a random nonce was necessary to achieve the advertised
+ security strength, but the code incorrectly used a constant instead of
+ entropy from the nonce.
+ Found by John Stroebel in #3819 and fixed in #3973.
diff --git a/ChangeLog.d/minimum_cmake_version_PR3802.txt b/ChangeLog.d/minimum_cmake_version_PR3802.txt
deleted file mode 100644
index 549f9b1..0000000
--- a/ChangeLog.d/minimum_cmake_version_PR3802.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Requirement changes
-* Update the minimum required CMake version to 2.8.12.
-* This silences a warning on CMake 3.19.0. #3801
diff --git a/ChangeLog.d/missing-debug-message-arguments_mbedtls_ssl_decrypt_buf.txt b/ChangeLog.d/missing-debug-message-arguments_mbedtls_ssl_decrypt_buf.txt
deleted file mode 100644
index e03178f..0000000
--- a/ChangeLog.d/missing-debug-message-arguments_mbedtls_ssl_decrypt_buf.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Bugfix
- * Add missing arguments of debug message in mbedtls_ssl_decrypt_buf.
diff --git a/ChangeLog.d/programs-ssl-use-after-scope.txt b/ChangeLog.d/programs-ssl-use-after-scope.txt
new file mode 100644
index 0000000..64bea61
--- /dev/null
+++ b/ChangeLog.d/programs-ssl-use-after-scope.txt
@@ -0,0 +1,2 @@
+Bugfix
+ * Fix use-after-scope error in programs/ssl/ssl_client2.c and ssl_server2.c
diff --git a/ChangeLog.d/psa-crypto-api-values-1.0.0.txt b/ChangeLog.d/psa-crypto-api-values-1.0.0.txt
deleted file mode 100644
index 0bd3764..0000000
--- a/ChangeLog.d/psa-crypto-api-values-1.0.0.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-API changes
- * The numerical values of the PSA Crypto API macros have been updated to
- conform to version 1.0.0 of the specification.
- * PSA_ALG_STREAM_CIPHER replaces PSA_ALG_CHACHA20 and PSA_ALG_ARC4.
- The underlying stream cipher is determined by the key type
- (PSA_KEY_TYPE_CHACHA20 or PSA_KEY_TYPE_ARC4).
-New deprecations
- * PSA_KEY_TYPE_CHACHA20 and PSA_KEY_TYPE_ARC4 have been deprecated.
- Use PSA_ALG_STREAM_CIPHER instead.
diff --git a/ChangeLog.d/psa-crypto-hmac-drbg.txt b/ChangeLog.d/psa-crypto-hmac-drbg.txt
new file mode 100644
index 0000000..18a0d1b
--- /dev/null
+++ b/ChangeLog.d/psa-crypto-hmac-drbg.txt
@@ -0,0 +1,5 @@
+Features
+ * The PSA crypto subsystem can now use HMAC_DRBG instead of CTR_DRBG.
+ CTR_DRBG is used by default if it is available, but you can override
+ this choice by setting MBEDTLS_PSA_HMAC_DRBG_MD_TYPE at compile time.
+ Fix #3354.
diff --git a/ChangeLog.d/psa-crypto-rename-output-buffer-size-macros.txt b/ChangeLog.d/psa-crypto-rename-output-buffer-size-macros.txt
new file mode 100644
index 0000000..1e8fb5f
--- /dev/null
+++ b/ChangeLog.d/psa-crypto-rename-output-buffer-size-macros.txt
@@ -0,0 +1,9 @@
+API changes
+ * Renamed the PSA Crypto API output buffer size macros to bring them in line
+ with version 1.0.0 of the specification.
+
+New deprecations
+ * PSA_KEY_EXPORT_MAX_SIZE, PSA_HASH_SIZE, PSA_MAC_FINAL_SIZE,
+ PSA_BLOCK_CIPHER_BLOCK_SIZE, PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE and
+ PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN have been renamed, and the old names
+ deprecated.
diff --git a/ChangeLog.d/psa-openless.txt b/ChangeLog.d/psa-openless.txt
deleted file mode 100644
index 2e40cdf..0000000
--- a/ChangeLog.d/psa-openless.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Features
- * In the PSA API, it is no longer necessary to open persistent keys:
- operations now accept the key identifier. The type psa_key_handle_t is now
- identical to psa_key_id_t instead of being platform-defined. This bridges
- the last major gap to compliance with the PSA Cryptography specification
- version 1.0.0. Opening persistent keys is still supported for backward
- compatibility, but will be deprecated and later removed in future
- releases.
-
-Bugfix
- * psa_set_key_id() now also sets the lifetime to persistent for keys located
- in a secure element.
- * Attempting to create a volatile key with a non-zero key identifier now
- fails. Previously the key identifier was just ignored when creating a
- volatile key.
- * Attempting to create or register a key with a key identifier in the vendor
- range now fails.
diff --git a/ChangeLog.d/psa_close_key_memory_leak_fix.txt b/ChangeLog.d/psa_close_key_memory_leak_fix.txt
new file mode 100644
index 0000000..91ce174
--- /dev/null
+++ b/ChangeLog.d/psa_close_key_memory_leak_fix.txt
@@ -0,0 +1,3 @@
+Bugfix
+ * Fix memory leak that occured when calling psa_close_key() on a
+ wrapped key with MBEDTLS_PSA_CRYPTO_SE_C defined.
diff --git a/ChangeLog.d/psa_error_invalid_argument_for_invalid_cipher_input_sizes.txt b/ChangeLog.d/psa_error_invalid_argument_for_invalid_cipher_input_sizes.txt
deleted file mode 100644
index 85c363b..0000000
--- a/ChangeLog.d/psa_error_invalid_argument_for_invalid_cipher_input_sizes.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Consistently return PSA_ERROR_INVALID_ARGUMENT on invalid cipher input
- sizes (instead of PSA_ERROR_BAD_STATE in some cases) to make the
- psa_cipher_* functions compliant with the PSA Crypto API specification.
diff --git a/ChangeLog.d/psa_generate_key-curve25519.txt b/ChangeLog.d/psa_generate_key-curve25519.txt
deleted file mode 100644
index 24b6fcf..0000000
--- a/ChangeLog.d/psa_generate_key-curve25519.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix psa_generate_key() returning an error when asked to generate
- an ECC key pair on Curve25519 or secp244k1.
diff --git a/ChangeLog.d/rsa_private-ret.txt b/ChangeLog.d/rsa_private-ret.txt
new file mode 100644
index 0000000..b965cea
--- /dev/null
+++ b/ChangeLog.d/rsa_private-ret.txt
@@ -0,0 +1,2 @@
+Bugfix
+ * Fix an incorrect error code if an RSA private operation glitched.
diff --git a/ChangeLog.d/support-ecdh-kdf-with-ecdh-key.txt b/ChangeLog.d/support-ecdh-kdf-with-ecdh-key.txt
deleted file mode 100644
index 6660dc3..0000000
--- a/ChangeLog.d/support-ecdh-kdf-with-ecdh-key.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Features
- * In PSA, allow using a key declared with a base key agreement algorithm
- in combined key agreement and derivation operations, as long as the key
- agreement algorithm in use matches the algorithm the key was declared with.
- This is currently non-standard behaviour, but expected to make it into a
- future revision of the PSA Crypto standard.
diff --git a/ChangeLog.d/support-key-agreement-and-derivation-output-as-key.txt b/ChangeLog.d/support-key-agreement-and-derivation-output-as-key.txt
deleted file mode 100644
index 3f61481..0000000
--- a/ChangeLog.d/support-key-agreement-and-derivation-output-as-key.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix psa_key_derivation_output_key() to allow the output of a combined key
- agreement and subsequent key derivation operation to be used as a key
- inside of the PSA Crypto core.
diff --git a/ChangeLog.d/systematically_store_bit_size_3740.txt b/ChangeLog.d/systematically_store_bit_size_3740.txt
deleted file mode 100644
index 9e63bbc..0000000
--- a/ChangeLog.d/systematically_store_bit_size_3740.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Changes
- * The PSA persistent storage format is updated to always store the key bits
- attribute. No automatic upgrade path is provided. Previously stored keys
- must be erased, or manually upgraded based on the key storage format
- specification (docs/architecture/mbed-crypto-storage-specification.md). #3740
diff --git a/docs/architecture/testing/driver-interface-test-strategy.md b/docs/architecture/testing/driver-interface-test-strategy.md
index d6769da..086fc1a 100644
--- a/docs/architecture/testing/driver-interface-test-strategy.md
+++ b/docs/architecture/testing/driver-interface-test-strategy.md
@@ -4,9 +4,19 @@
The driver interfaces are standardized through PSA Cryptography functional specifications.
-## Secure element driver interface
+## Secure element driver interface testing
-The secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed Crypto and one or more third-party drivers.
+### Secure element driver interfaces
+
+#### Opaque driver interface
+
+The [unified driver interface](../../proposed/psa-driver-interface.md) supports both transparent drivers (for accelerators) and opaque drivers (for secure elements).
+
+Drivers exposing this interface need to be registered at compile time by declaring their JSON description file.
+
+#### Dynamic secure element driver interface
+
+The dynamic secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed Crypto and one or more third-party drivers.
The SE interface consists of one function provided by Mbed Crypto (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed Crypto, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function.
@@ -18,6 +28,8 @@
#### SE driver registration
+This applies to dynamic drivers only.
+
* Test `psa_register_se_driver` with valid and with invalid arguments.
* Make at least one failing call to `psa_register_se_driver` followed by a successful call.
* Make at least one test that successfully registers the maximum number of drivers and fails to register one more.
@@ -102,14 +114,20 @@
A PKCS#11 driver would be a good candidate. It would be useful as part of our product offering.
-## Accelerator driver interface
+## Transparent driver interface testing
-The accelerator driver interface is defined by [`psa/crypto_accel_driver.h`](../../../include/psa/crypto_accel_driver.h).
+The [unified driver interface](../../proposed/psa-driver-interface.md) defines interfaces for accelerators.
-TODO
+### Test requirements
-## Entropy driver interface
+#### Requirements for transparent driver testing
-The entropy driver interface is defined by [`psa/crypto_entropy_driver.h`](../../../include/psa/crypto_entropy_driver.h).
+Every cryptographic mechanism for which a transparent driver interface exists (key creation, cryptographic operations, …) must be exercised in at least one build. The test must verify that the driver code is called.
+
+#### Requirements for fallback
+
+The driver interface includes a fallback mechanism so that a driver can reject a request at runtime and let another driver handle the request. For each entry point, there must be at least three test runs with two or more drivers available with driver A configured to fall back to driver B, with one run where A returns `PSA_SUCCESS`, one where A returns `PSA_ERROR_NOT_SUPPORTED` and B is invoked, and one where A returns a different error and B is not invoked.
+
+## Entropy and randomness interface testing
TODO
diff --git a/docs/architecture/testing/psa-storage-format-testing.md b/docs/architecture/testing/psa-storage-format-testing.md
new file mode 100644
index 0000000..71bf968
--- /dev/null
+++ b/docs/architecture/testing/psa-storage-format-testing.md
@@ -0,0 +1,103 @@
+# Mbed TLS PSA keystore format stability testing strategy
+
+## Introduction
+
+The PSA crypto subsystem includes a persistent key store. It is possible to create a persistent key and read it back later. This must work even if Mbed TLS has been upgraded in the meantime (except for deliberate breaks in the backward compatibility of the storage).
+
+The goal of this document is to define a test strategy for the key store that not only validates that it's possible to load a key that was saved with the version of Mbed TLS under test, but also that it's possible to load a key that was saved with previous versions of Mbed TLS.
+
+Interoperability is not a goal: PSA crypto implementations are not intended to have compatible storage formats. Downgrading is not required to work.
+
+## General approach
+
+### Limitations of a direct approach
+
+The goal of storage format stability testing is: as a user of Mbed TLS, I want to store a key under version V and read it back under version W, with W ≥ V.
+
+Doing the testing this way would be difficult because we'd need to have version V of Mbed TLS available when testing version W.
+
+An alternative, semi-direct approach consists of generating test data under version V, and reading it back under version W. Done naively, this would require keeping a large amount of test data (full test coverage multiplied by the number of versions that we want to preserve backward compatibility with).
+
+### Save-and-compare approach
+
+Importing and saving a key is deterministic. Therefore we can ensure the stability of the storage format by creating test cases under a version V of Mbed TLS, where the test case parameters include both the parameters to pass to key creation and the expected state of the storage after the key is created. The test case creates a key as indicated by the parameters, then compares the actual state of the storage with the expected state. In addition, the test case also loads the key and checks that it has the expected data and metadata.
+
+If the test passes with version V, this means that the test data is consistent with what the implementation does. When the test later runs under version W ≥ V, it creates and reads back a storage state which is known to be identical to the state that V would have produced. Thus, this approach validates that W can read storage states created by V.
+
+Use a similar approach for files other than keys where possible and relevant.
+
+### Keeping up with storage format evolution
+
+Test cases should normally not be removed from the code base: if something has worked before, it should keep working in future versions, so we should keep testing it.
+
+If the way certain keys are stored changes, and we don't deliberately decide to stop supporting old keys (which should only be done by retiring a version of the storage format), then we should keep the corresponding test cases in load-only mode: create a file with the expected content, load it and check the data that it contains.
+
+## Storage architecture overview
+
+The PSA subsystem provides storage on top of the PSA trusted storage interface. The state of the storage is a mapping from file identifer (a 64-bit number) to file content (a byte array). These files include:
+
+* [Key files](#key-storage) (files containing one key's metadata and, except for some secure element keys, key material).
+* The [random generator injected seed or state file](#random-generator-state) (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`).
+* [Storage transaction file](#storage-transaction-resumption).
+* [Driver state files](#driver-state-files).
+
+For a more detailed description, refer to the [Mbed Crypto storage specification](../mbed-crypto-storage-specification.md).
+
+In addition, Mbed TLS includes an implementation of the PSA trusted storage interface on top of C stdio. This document addresses the test strategy for [PSA ITS over file](#psa-its-over-file) in a separate section below.
+
+## Key storage testing
+
+This section describes the desired test cases for keys created with the current storage format version. When the storage format changes, if backward compatibility is desired, old test data should be kept as described under [“Keeping up with storage format evolution”](#keeping-up-with-storage-format-evolution).
+
+### Keystore layout
+
+Objective: test that the key file name corresponds to the key identifier.
+
+Method: Create a key with a given identifier (using `psa_import_key`) and verify that a file with the expected name is created, and no other. Repeat for different identifiers.
+
+### General key format
+
+Objective: test the format of the key file: which field goes where and how big it is.
+
+Method: Create a key with certain metadata with `psa_import_key`. Read the file content and validate that it has the expected layout, deduced from the storage specification. Repeat with different metadata. Ensure that there are test cases covering all fields.
+
+### Enumeration of test cases for keys
+
+Objective: ensure that the coverage is sufficient to have assurance that all keys are stored correctly. This requires a sufficient selection of key types, sizes, policies, etc.
+
+In particular, the tests must validate that each `PSA_xxx` constant that is stored in a key is covered by at least once test case:
+
+* Usage flags: `PSA_KEY_USAGE_xxx`.
+* Algorithms in policies: `PSA_ALG_xxx`.
+* Key types: `PSA_KEY_TYPE_xxx`, `PSA_ECC_FAMILY_xxx`, `PSA_DH_FAMILY_xxx`.
+
+Method: Each test case creates a key with `psa_import_key`, purges it from memory, then reads it back and exercises it. Generate test cases automatically based on an enumeration of available constants and some knowledge of what attributes (sizes, algorithms, …) and content to use for keys of a certain type. Note that the generated test cases will be checked into the repository (generating test cases at runtime would not allow us to test the stability of the format, only that a given version is internally consistent).
+
+### Testing with alternative lifetime values
+
+Objective: have test coverage for lifetimes other than the default persistent lifetime (`PSA_KEY_LIFETIME_PERSISTENT`).
+
+Method:
+
+* For alternative locations: have tests conditional on the presence of a driver for that location.
+* For alternative persistence levels: TODO
+
+## Random generator state
+
+TODO
+
+## Driver state files
+
+Not yet implemented.
+
+TODO
+
+## Storage transaction resumption
+
+Only relevant for secure element support. Not yet fully implemented.
+
+TODO
+
+## PSA ITS over file
+
+TODO
diff --git a/docs/getting_started.md b/docs/getting_started.md
index 15d5a31..70c5ff4 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -203,7 +203,7 @@
void encrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
{
enum {
- block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES),
+ block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
};
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -288,7 +288,7 @@
void decrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
{
enum {
- block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES),
+ block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
};
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -445,7 +445,7 @@
0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
};
- size_t expected_hash_len = PSA_HASH_SIZE(alg);
+ size_t expected_hash_len = PSA_HASH_LENGTH(alg);
printf("Verify a hash...\t");
fflush(stdout);
@@ -482,7 +482,7 @@
mbedtls_psa_crypto_free();
```
-The API provides the macro `PSA_HASH_SIZE`, which returns the expected hash length (in bytes) for the specified algorithm.
+The API provides the macro `PSA_HASH_LENGTH`, which returns the expected hash length (in bytes) for the specified algorithm.
#### Handling hash operation contexts
diff --git a/docs/proposed/psa-driver-interface.md b/docs/proposed/psa-driver-interface.md
index d825794..47d7271 100644
--- a/docs/proposed/psa-driver-interface.md
+++ b/docs/proposed/psa-driver-interface.md
@@ -5,8 +5,6 @@
This specification is work in progress and should be considered to be in a beta stage. There is ongoing work to implement this interface in Mbed TLS, which is the reference implementation of the PSA Cryptography API. At this stage, Arm does not expect major changes, but minor changes are expected based on experience from the first implementation and on external feedback.
-Time-stamp: "2020/11/24 11:03:32 GMT"
-
## Introduction
### Purpose of the driver interface
@@ -196,6 +194,8 @@
Some entry points are grouped in families that must be implemented as a whole. If a driver supports an entry point family, it must provide all the entry points in the family.
+Drivers can also have entry points related to random generation. A transparent driver can provide a [random generation interface](#random-generation-entry-points). Separately, transparent and opaque drivers can have [entropy collection entry points](#entropy-collection-entry-point).
+
#### General considerations on driver entry point parameters
Buffer parameters for driver entry points obey the following conventions:
@@ -375,6 +375,49 @@
* For elliptic curve private keys (`PSA_KEY_TYPE_ECC_KEY_PAIR`), check the size and range. TODO: what else?
* For elliptic curve public keys (`PSA_KEY_TYPE_ECC_PUBLIC_KEY`), check the size and range, and that the point is on the curve. TODO: what else?
+### Entropy collection entry point
+
+A driver can declare an entropy source by providing a `"get_entropy"` entry point. This entry point has the following prototype for a driver with the prefix `"acme"`:
+
+```
+psa_status_t acme_get_entropy(uint32_t flags,
+ size_t *estimate_bits,
+ uint8_t *output,
+ size_t output_size);
+```
+
+The semantics of the parameters is as follows:
+
+* `flags`: a bit-mask of [entropy collection flags](#entropy-collection-flags).
+* `estimate_bits`: on success, an estimate of the amount of entropy that is present in the `output` buffer, in bits. This must be at least `1` on success. The value is ignored on failure. Drivers should return a conservative estimate, even in circumstances where the quality of the entropy source is degraded due to environmental conditions (e.g. undervolting, low temperature, etc.).
+* `output`: on success, this buffer contains non-deterministic data with an estimated entropy of at least `*estimate_bits` bits. When the entropy is coming from a hardware peripheral, this should preferably be raw or lightly conditioned measurements from a physical process, such that statistical tests run over a sufficiently large amount of output can confirm the entropy estimates. But this specification also permits entropy sources that are fully conditioned, for example when the PSA Cryptography system is running as an application in an operating system and `"get_entropy"` returns data from the random generator in the operating system's kernel.
+* `output_size`: the size of the `output` buffer in bytes. This size should be large enough to allow a driver to pass unconditioned data with a low density of entropy; for example a peripheral that returns eight bytes of data with an estimated one bit of entropy cannot provide meaningful output in less than 8 bytes.
+
+Note that there is no output parameter indicating how many bytes the driver wrote to the buffer. Such an output length indication is not necessary because the entropy may be located anywhere in the buffer, so the driver may write less than `output_size` bytes but the core does not need to know this. The output parameter `estimate_bits` contains the amount of entropy, expressed in bits, which may be significantly less than `output_size * 8`.
+
+The entry point may return the following statuses:
+
+* `PSA_SUCCESS`: success. The output buffer contains some entropy.
+* `PSA_ERROR_INSUFFICIENT_ENTROPY`: no entropy is available without blocking. This is only permitted if the `PSA_DRIVER_GET_ENTROPY_BLOCK` flag is clear. The core may call `get_entropy` again later, giving time for entropy to be gathered or for adverse environmental conditions to be rectified.
+* Other error codes indicate a transient or permanent failure of the entropy source.
+
+Unlike most other entry points, if multiple transparent drivers include a `"get_entropy"` point, the core will call all of them (as well as the entry points from opaque drivers). Fallback is not applicable to `"get_entropy"`.
+
+#### Entropy collection flags
+
+* `PSA_DRIVER_GET_ENTROPY_BLOCK`: If this flag is set, the driver should block until it has at least one bit of entropy. If this flag is clear, the driver should avoid blocking if no entropy is readily available.
+* `PSA_DRIVER_GET_ENTROPY_KEEPALIVE`: This flag is intended to help with energy management for entropy-generating peripherals. If this flag is set, the driver should expect another call to `acme_get_entropy` after a short time. If this flag is clear, the core is not expecting to call the `"get_entropy"` entry point again within a short amount of time (but it may do so nonetheless).
+
+#### Entropy collection and blocking
+
+The intent of the `BLOCK` and `KEEPALIVE` [flags](#entropy-collection-flags) is to support drivers for TRNG (True Random Number Generator, i.e. an entropy source peripheral) that have a long ramp-up time, especially on platforms with multiple entropy sources.
+
+Here is a suggested call sequence for entropy collection that leverages these flags:
+
+1. The core makes a first round of calls to `"get_entropy"` on every source with the `BLOCK` flag clear and the `KEEPALIVE` flag set, so that drivers can prepare the TRNG peripheral.
+2. The core makes a second round of calls with the `BLOCK` flag set and the `KEEPALIVE` flag clear to gather needed entropy.
+3. If the second round does not collect enough entropy, the core makes more similar rounds, until the total amount of collected entropy is sufficient.
+
### Miscellaneous driver entry points
#### Driver initialization
@@ -428,6 +471,109 @@
3. [Determine the key size](#key-size-determination-on-import) and output it through `*bits`.
4. Copy the validated key data from `data` to `key_buffer`. The output must be in the canonical format documented for [`psa_export_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_key) or [`psa_export_public_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_public_key), so if the input is not in this format, the entry point must convert it.
+### Random generation entry points
+
+A transparent driver may provide an operation family that can be used as a cryptographic random number generator. The random generation mechanism must obey the following requirements:
+
+* The random output must be of cryptographic quality, with a uniform distribution. Therefore, if the random generator includes an entropy source, this entropy source must be fed through a CSPRNG (cryptographically secure pseudo-random number generator).
+* Random generation is expected to be fast. (If a device can provide entropy but is slow at generating random data, declare it as an [entropy driver](#entropy-collection-entry-point) instead.)
+* The random generator should be able to incorporate entropy provided by an outside source. If it isn't, the random generator can only be used if it's the only entropy source on the platform. (A random generator peripheral can be declared as an [entropy source](#entropy-collection-entry-point) instead of a random generator; this way the core will combine it with other entropy sources.)
+* The random generator may either be deterministic (in the sense that it always returns the same data when given the same entropy inputs) or non-deterministic (including its own entropy source). In other words, this interface is suitable both for PRNG (pseudo-random number generator, also known as DRBG (deterministic random bit generator)) and for NRBG (non-deterministic random bit generator).
+
+If no driver implements the random generation entry point family, the core provides an unspecified random generation mechanism.
+
+This operation family requires the following type, entry points and parameters (TODO: where exactly are the parameters in the JSON structure?):
+
+* Type `"random_context_t"`: the type of a random generation context.
+* `"init_random"` (entry point, optional): if this function is present, [the core calls it once](#random-generator-initialization) after allocating a `"random_context_t"` object.
+* `"add_entropy"` (entry point, optional): the core calls this function to [inject entropy](#entropy-injection). This entry point is optional if the driver is for a peripheral that includes an entropy source of its own, however [random generator drivers without entropy injection](#random-generator-drivers-without-entropy-injection) have limited portability since they can only be used on platforms with no other entropy source. This entry point is mandatory if `"initial_entropy_size"` is nonzero.
+* `"get_random"` (entry point, mandatory): the core calls this function whenever it needs to [obtain random data](#the-get_random-entry-point).
+* `"initial_entropy_size"` (integer, mandatory): the minimum number of bytes of entropy that the core must supply before the driver can output random data. This can be `0` if the driver is for a peripheral that includes an entropy source of its own.
+* `"reseed_entropy_size"` (integer, optional): the minimum number of bytes of entropy that the core should supply via [`"add_entropy"`](#entropy-injection) when the driver runs out of entropy. This value is also a hint for the size to supply if the core makes additional calls to `"add_entropy"`, for example to enforce prediction resistance. If omitted, the core should pass an amount of entropy corresponding to the expected security strength of the device (for example, pass 32 bytes of entropy when reseeding to achieve a security strength of 256 bits). If specified, the core should pass the larger of `"reseed_entropy_size"` and the amount corresponding to the security strength.
+
+Random generation is not parametrized by an algorithm. The choice of algorithm is up to the driver.
+
+#### Random generator initialization
+
+The `"init_random"` entry point has the following prototype for a driver with the prefix `"acme"`:
+
+```
+psa_status_t acme_init_random(acme_random_context_t *context);
+```
+
+The core calls this entry point once after allocating a random generation context. Initially, the context object is all-bits-zero.
+
+If a driver does not have an `"init_random"` entry point, the context object passed to the first call to `"add_entropy"` or `"get_random"` will be all-bits-zero.
+
+#### Entropy injection
+
+The `"add_entropy"` entry point has the following prototype for a driver with the prefix `"acme"`:
+
+```
+psa_status_t acme_add_entropy(acme_random_context_t *context,
+ const uint8_t *entropy,
+ size_t entropy_size);
+```
+
+The semantics of the parameters is as follows:
+
+* `context`: a random generation context. On the first call to `"add_entropy"`, this object has been initialized by a call to the driver's `"init_random"` entry point if one is present, and to all-bits-zero otherwise.
+* `entropy`: a buffer containing full-entropy data to seed the random generator. “Full-entropy” means that the data is uniformly distributed and independent of any other observable quantity.
+* `entropy_size`: the size of the `entropy` buffer in bytes. It is guaranteed to be at least `1`, but it may be smaller than the amount of entropy that the driver needs to deliver random data, in which case the core will call the `"add_entropy"` entry point again to supply more entropy.
+
+The core calls this function to supply entropy to the driver. The driver must mix this entropy into its internal state. The driver must mix the whole supplied entropy, even if there is more than what the driver requires, to ensure that all entropy sources are mixed into the random generator state. The driver may mix additional entropy of its own.
+
+The core may call this function at any time. For example, to enforce prediction resistance, the core can call `"add_entropy"` immediately after each call to `"get_random"`. The core must call this function in two circumstances:
+
+* Before the first call to the `"get_random"` entry point, to supply `"initial_entropy_size"` bytes of entropy.
+* After a call to the `"get_random"` entry point returns less than the required amount of random data, to supply at least `"reseed_entropy_size"` bytes of entropy.
+
+When the driver requires entropy, the core can supply it with one or more successive calls to the `"add_entropy"` entry point. If the required entropy size is zero, the core does not need to call `"add_entropy"`.
+
+#### Combining entropy sources with a random generation driver
+
+This section provides guidance on combining one or more [entropy sources](#entropy-collection-entry-point) (each having a `"get_entropy"` entry point) with a random generation driver (with an `"add_entropy"` entry point).
+
+Note that `"get_entropy"` returns data with an estimated amount of entropy that is in general less than the buffer size. The core must apply a mixing algorithm to the output of `"get_entropy"` to obtain full-entropy data.
+
+For example, the core may use a simple mixing scheme based on a pseudorandom function family $(F_k)$ with an $E$-bit output where $E = 8 \cdot \mathtt{entropy_size}$ and $\mathtt{entropy_size}$ is the desired amount of entropy in bytes (typically the random driver's `"initial_entropy_size"` property for the initial seeding and the `"reseed_entropy_size"` property for subsequent reseeding). The core calls the `"get_entropy"` points of the available entropy drivers, outputting a string $s_i$ and an entropy estimate $e_i$ on the $i$th call. It does so until the total entropy estimate $e_1 + e_2 + \ldots + e_n$ is at least $E$. The core then calculates $F_k(0)$ where $k = s_1 || s_2 || \ldots || s_n$. This value is a string of $\mathtt{entropy_size}$, and since $(F_k)$ is a pseudorandom function family, $F_k(0)$ is uniformly distributed over strings of $\mathtt{entropy_size}$ bytes. Therefore $F_k(0)$ is a suitable value to pass to `"add_entropy"`.
+
+Note that the mechanism above is only given as an example. Implementations may choose a different mechanism, for example involving multiple pools or intermediate compression functions.
+
+#### Random generator drivers without entropy injection
+
+Random generator drivers should have the capability to inject additional entropy through the `"add_entropy"` entry point. This ensures that the random generator depends on all the entropy sources that are available on the platform. A driver where a call to `"add_entropy"` does not affect the state of the random generator is not compliant with this specification.
+
+However, a driver may omit the `"add_entropy"` entry point. This limits the driver's portability: implementations of the PSA Cryptography specification may reject drivers without an `"add_entropy"` entry point, or only accept such drivers in certain configurations. In particular, the `"add_entropy"` entry point is required if:
+
+* the integration of PSA Cryptography includes an entropy source that is outside the driver; or
+* the core saves random data in persistent storage to be preserved across platform resets.
+
+#### The `"get_random"` entry point
+
+The `"get_random"` entry point has the following prototype for a driver with the prefix `"acme"`:
+
+```
+psa_status_t acme_get_random(acme_random_context_t *context,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+```
+
+The semantics of the parameters is as follows:
+
+* `context`: a random generation context. If the driver's `"initial_entropy_size"` property is nonzero, the core must have called `"add_entropy"` at least once with a total of at least `"initial_entropy_size"` bytes of entropy before it calls `"get_random"`. Alternatively, if the driver's `"initial_entropy_size"` property is zero and the core did not call `"add_entropy"`, or if the driver has no `"add_entropy"` entry point, the core must have called `"init_random"` if present, and otherwise the context is all-bits zero.
+* `output`: on success (including partial success), the first `*output_length` bytes of this buffer contain cryptographic-quality random data. The output is not used on error.
+* `output_size`: the size of the `output` buffer in bytes.
+* `*output_length`: on success (including partial success), the number of bytes of random data that the driver has written to the `output` buffer. This is preferably `output_size`, but the driver is allowed to return less data if it runs out of entropy as described below. The core sets this value to 0 on entry. The value is not used on error.
+
+The driver may return the following status codes:
+
+* `PSA_SUCCESS`: the `output` buffer contains `*output_length` bytes of cryptographic-quality random data. Note that this may be less than `output_size`; in this case the core should call the driver's `"add_entropy"` method to supply at least `"reseed_entropy_size"` bytes of entropy before calling `"get_random"` again.
+* `PSA_ERROR_INSUFFICIENT_ENTROPY`: the core must supply additional entropy by calling the `"add_entropy"` entry point with at least `"reseed_entropy_size"` bytes.
+* `PSA_ERROR_NOT_SUPPORTED`: the random generator is not available. This is only permitted if the driver specification for random generation has the [fallback property](#fallback) enabled.
+* Other error codes such as `PSA_ERROR_COMMUNICATION_FAILURE` or `PSA_ERROR_HARDWARE_FAILURE` indicate a transient or permanent error.
+
### Fallback
Sometimes cryptographic accelerators only support certain cryptographic mechanisms partially. The capability description language allows specifying some restrictions, including restrictions on key sizes, but it cannot cover all the possibilities that may arise in practice. Furthermore, it may be desirable to deploy the same binary image on different devices, only some of which have a cryptographic accelerators.
@@ -460,7 +606,8 @@
* `"public_key_size"` (integer or string, optional): this many bytes are included in every key context for a public key. If omitted, this value defaults to 0.
* `"symmetric_factor"` (integer or string, optional): every key context for a symmetric key includes this many times the key size. If omitted, this value defaults to 0.
* `"store_public_key"` (boolean, optional): If specified and true, for a key pair, the key context includes space for the public key. If omitted or false, no additional space is added for the public key.
-* `"size_function"` (string, optional): the name of a function that returns the number of bytes that the driver needs in a key context for a key. This may be a pointer to function. This must be a C identifier; more complex expressions are not permitted. If the core uses this function, it supersedes all the other properties.
+* `"size_function"` (string, optional): the name of a function that returns the number of bytes that the driver needs in a key context for a key. This may be a pointer to function. This must be a C identifier; more complex expressions are not permitted. If the core uses this function, it supersedes all the other properties except for `"builtin_key_size"` (where applicable, if present).
+* `"builtin_key_size"` (integer or string, optional): If specified, this overrides all other methods (including the `"size_function"` entry point) to determine the size of the key context for [built-in keys](#built-in-keys). This allows drivers to efficiently represent application keys as wrapped key material, but built-in keys by an internal identifier that takes up less space.
The integer properties must be C language constants. A typical value for `"base_size"` is `sizeof(acme_key_context_t)` where `acme_key_context_t` is a type defined in a driver header file.
@@ -516,6 +663,7 @@
* `"generate_key"`: called by `psa_generate_key()`.
* `"key_derivation_output_key"`: called by `psa_key_derivation_output_key()`.
* `"copy_key"`: called by `psa_copy_key()` when copying a key within the same [location](#lifetimes-and-locations).
+* `"get_builtin_key"`: called by functions that access a key to retrieve information about a [built-in key](#built-in-keys).
In addition, secure elements that store the key material internally must provide the following two entry points:
@@ -646,6 +794,37 @@
In a multithreaded environment, the driver may only call these two functions from the thread that is executing the entry point.
+#### Built-in keys
+
+Opaque drivers may declare built-in keys. Built-in keys can be accessed, but not created, through the PSA Cryptography API.
+
+A built-in key is identified by its location and its **slot number**. Drivers that support built-in keys must provide a `"get_builtin_key"` entry point to retrieve the key data and metadata. The core calls this entry point when it needs to access the key, typically because the application requested an operation on the key. The core may keep information about the key in cache, and successive calls to access the same slot number should return the same data. This entry point has the following prototype:
+
+```
+psa_status_t acme_get_builtin_key(psa_drv_slot_number_t slot_number,
+ psa_key_attributes_t *attributes,
+ uint8_t *key_buffer,
+ size_t key_buffer_size,
+ size_t *key_buffer_length);
+```
+
+If this function returns `PSA_SUCCESS` or `PSA_ERROR_BUFFER_TOO_SMALL`, it must fill `attributes` with the attributes of the key (except for the key identifier). On success, this function must also fill `key_buffer` with the key context.
+
+On entry, `psa_get_key_lifetime(attributes)` is the location at which the driver was declared and the persistence level `#PSA_KEY_LIFETIME_PERSISTENT`. The driver entry point may change the lifetime to one with the same location but a different persistence level. The standard attributes other than the key identifier and lifetime have the value conveyed by `PSA_KEY_ATTRIBUTES_INIT`.
+
+The output parameter `key_buffer` points to a writable buffer of `key_buffer_size` bytes. If the driver has a [`"builtin_key_size"` property](#key-format-for-opaque-drivers) property, `key_buffer_size` has this value, otherwise `key_buffer_size` has the value determined from the key type and size.
+
+Typically, for a built-in key, the key context is a reference to key material that is kept inside the secure element, similar to the format returned by [`"allocate_key"`](#key-management-in-a-secure-element-with-storage). A driver may have built-in keys even if it doesn't have an `"allocate_key"` entry point.
+
+This entry point may return the following status values:
+
+* `PSA_SUCCESS`: the requested key exists, and the output parameters `attributes` and `key_buffer` contain the key metadata and key context respectively, and `*key_buffer_length` contains the length of the data written to `key_buffer`.
+* `PSA_ERROR_BUFFER_TOO_SMALL`: `key_buffer_size` is insufficient. In this case, the driver must pass the key's attributes in `*attributes`. In particular, `get_builtin_key(slot_number, &attributes, NULL, 0)` is a way for the core to obtain the key's attributes.
+* `PSA_ERROR_DOES_NOT_EXIST`: the requested key does not exist.
+* Other error codes such as `PSA_ERROR_COMMUNICATION_FAILURE` or `PSA_ERROR_HARDWARE_FAILURE` indicate a transient or permanent error.
+
+The core will pass authorized requests to destroy a built-in key to the [`"destroy_key"`](#key-management-in-a-secure-element-with-storage) entry point if there is one. If built-in keys must not be destroyed, it is up to the driver to reject such requests.
+
## How to use drivers from an application
### Using transparent drivers
@@ -661,7 +840,7 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
PSA_KEY_PERSISTENCE_DEFAULT, PSA_KEY_LOCATION_acme));
-psa_set_key_identifer(&attributes, 42);
+psa_set_key_identifier(&attributes, 42);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_size(&attributes, 128);
psa_set_key_algorithm(&attributes, PSA_ALG_GCM);
@@ -704,6 +883,19 @@
## Open questions
+### Value representation
+
+#### Integers
+
+It would be better if there was a uniform requirement on integer values. Do they have to be JSON integers? C preprocessor integers (which could be e.g. a macro defined in some header file)? C compile-time constants (allowing `sizeof`)?
+
+This choice is partly driven by the use of the values, so they might not be uniform. Note that if the value can be zero and it's plausible that the core would want to statically allocate an array of the given size, the core needs to know whether the value is 0 so that it could use code like
+```
+#if ACME_FOO_SIZE != 0
+ uint8_t foo[ACME_FOO_SIZE];
+#endif
+```
+
### Driver declarations
#### Declaring driver entry points
@@ -779,6 +971,26 @@
`psa_crypto_driver_get_persistent_state` does not identify the calling driver, so the driver needs to remember which driver it's calling. This may require a thread-local variable in a multithreaded core. Is this ok?
+### Randomness
+
+#### Input to `"add_entropy"`
+
+Should the input to the [`"add_entropy"` entry point](#entropy-injection) be a full-entropy buffer (with data from all entropy sources already mixed), raw entropy direct from the entropy sources, or give the core a choice?
+
+* Raw data: drivers must implement entropy mixing. `"add_entropy"` needs an extra parameter to indicate the amount of entropy in the data. The core must not do any conditioning.
+* Choice: drivers must implement entropy mixing. `"add_entropy"` needs an extra parameter to indicate the amount of entropy in the data. The core may do conditioning if it wants, but doesn't have to.
+* Full entropy: drivers don't need to do entropy mixing.
+
+#### Flags for `"get_entropy"`
+
+Are the [entropy collection flags](#entropy-collection-flags) well-chosen?
+
+#### Random generator instantiations
+
+May the core instantiate a random generation context more than once? In other words, can there be multiple objects of type `acme_random_context_t`?
+
+Functionally, one RNG is as good as any. If the core wants some parts of the system to use a deterministic generator for reproducibility, it can't use this interface anyway, since the RNG is not necessarily deterministic. However, for performance on multiprocessor systems, a multithreaded core could prefer to use one RNG instance per thread.
+
<!--
Local Variables:
time-stamp-line-limit: 40
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index c13b279..5b51bd5 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -22,7 +22,7 @@
*/
/**
- * @mainpage mbed TLS v2.24.0 source code documentation
+ * @mainpage mbed TLS v2.25.0 source code 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 bf33dab..dd4237a 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.
-PROJECT_NAME = "mbed TLS v2.24.0"
+PROJECT_NAME = "mbed TLS v2.25.0"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 1ebb706..7f403c1 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -572,10 +572,11 @@
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
#endif
-#if defined(MBEDTLS_PSA_CRYPTO_C) && \
- !( defined(MBEDTLS_CTR_DRBG_C) && \
- defined(MBEDTLS_ENTROPY_C) )
-#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites"
+#if defined(MBEDTLS_PSA_CRYPTO_C) && \
+ !( ( ( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) ) && \
+ defined(MBEDTLS_ENTROPY_C) ) || \
+ defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) )
+#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)"
#endif
#if defined(MBEDTLS_PSA_CRYPTO_SPM) && !defined(MBEDTLS_PSA_CRYPTO_C)
@@ -604,6 +605,11 @@
#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources"
#endif
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+ defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG"
+#endif
+
#if defined(MBEDTLS_PSA_ITS_FILE_C) && \
!defined(MBEDTLS_FS_IO)
#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"
@@ -880,6 +886,10 @@
#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) && ( !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) )
+#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites"
+#endif
+
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 8827e0b..1cafa6e 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -857,30 +857,52 @@
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_WARNING */
/**
- * \brief The generic autenticated encryption (AEAD) function.
+ * \brief The generic authenticated encryption (AEAD) function.
+ *
+ * \deprecated Superseded by mbedtls_cipher_auth_encrypt_ext().
+ *
+ * \note This function only supports AEAD algorithms, not key
+ * wrapping algorithms such as NIST_KW; for this, see
+ * mbedtls_cipher_auth_encrypt_ext().
*
* \param ctx The generic cipher context. This must be initialized and
- * bound to a key.
- * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
- * This must be a readable buffer of at least \p iv_len
- * Bytes.
- * \param iv_len The IV length for ciphers with variable-size IV.
- * This parameter is discarded by ciphers with fixed-size IV.
+ * bound to a key associated with an AEAD algorithm.
+ * \param iv The nonce to use. This must be a readable buffer of
+ * at least \p iv_len Bytes and must not be \c NULL.
+ * \param iv_len The length of the nonce. This must satisfy the
+ * constraints imposed by the AEAD cipher used.
* \param ad The additional data to authenticate. This must be a
- * readable buffer of at least \p ad_len Bytes.
+ * readable buffer of at least \p ad_len Bytes, and may
+ * be \c NULL is \p ad_len is \c 0.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
- * readable buffer of at least \p ilen Bytes.
+ * readable buffer of at least \p ilen Bytes, and may be
+ * \c NULL if \p ilen is \c 0.
* \param ilen The length of the input data.
- * \param output The buffer for the output data. This must be able to
- * hold at least \p ilen Bytes.
- * \param olen The length of the output data, to be updated with the
- * actual number of Bytes written. This must not be
- * \c NULL.
+ * \param output The buffer for the output data. This must be a
+ * writable buffer of at least \p ilen Bytes, and must
+ * not be \c NULL.
+ * \param olen This will be filled with the actual number of Bytes
+ * written to the \p output buffer. This must point to a
+ * writable object of type \c size_t.
* \param tag The buffer for the authentication tag. This must be a
- * writable buffer of at least \p tag_len Bytes.
- * \param tag_len The desired length of the authentication tag.
+ * writable buffer of at least \p tag_len Bytes. See note
+ * below regarding restrictions with PSA-based contexts.
+ * \param tag_len The desired length of the authentication tag. This
+ * must match the constraints imposed by the AEAD cipher
+ * used, and in particular must not be \c 0.
+ *
+ * \note If the context is based on PSA (that is, it was set up
+ * with mbedtls_cipher_setup_psa()), then it is required
+ * that \c tag == output + ilen. That is, the tag must be
+ * appended to the ciphertext as recommended by RFC 5116.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -892,36 +914,53 @@
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
- unsigned char *tag, size_t tag_len );
+ unsigned char *tag, size_t tag_len )
+ MBEDTLS_DEPRECATED;
/**
- * \brief The generic autenticated decryption (AEAD) function.
+ * \brief The generic authenticated decryption (AEAD) function.
+ *
+ * \deprecated Superseded by mbedtls_cipher_auth_decrypt_ext().
+ *
+ * \note This function only supports AEAD algorithms, not key
+ * wrapping algorithms such as NIST_KW; for this, see
+ * mbedtls_cipher_auth_decrypt_ext().
*
* \note If the data is not authentic, then the output buffer
* is zeroed out to prevent the unauthentic plaintext being
* used, making this interface safer.
*
* \param ctx The generic cipher context. This must be initialized and
- * and bound to a key.
- * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
- * This must be a readable buffer of at least \p iv_len
- * Bytes.
- * \param iv_len The IV length for ciphers with variable-size IV.
- * This parameter is discarded by ciphers with fixed-size IV.
- * \param ad The additional data to be authenticated. This must be a
- * readable buffer of at least \p ad_len Bytes.
+ * bound to a key associated with an AEAD algorithm.
+ * \param iv The nonce to use. This must be a readable buffer of
+ * at least \p iv_len Bytes and must not be \c NULL.
+ * \param iv_len The length of the nonce. This must satisfy the
+ * constraints imposed by the AEAD cipher used.
+ * \param ad The additional data to authenticate. This must be a
+ * readable buffer of at least \p ad_len Bytes, and may
+ * be \c NULL is \p ad_len is \c 0.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
- * readable buffer of at least \p ilen Bytes.
+ * readable buffer of at least \p ilen Bytes, and may be
+ * \c NULL if \p ilen is \c 0.
* \param ilen The length of the input data.
- * \param output The buffer for the output data.
- * This must be able to hold at least \p ilen Bytes.
- * \param olen The length of the output data, to be updated with the
- * actual number of Bytes written. This must not be
- * \c NULL.
- * \param tag The buffer holding the authentication tag. This must be
- * a readable buffer of at least \p tag_len Bytes.
- * \param tag_len The length of the authentication tag.
+ * \param output The buffer for the output data. This must be a
+ * writable buffer of at least \p ilen Bytes, and must
+ * not be \c NULL.
+ * \param olen This will be filled with the actual number of Bytes
+ * written to the \p output buffer. This must point to a
+ * writable object of type \c size_t.
+ * \param tag The buffer for the authentication tag. This must be a
+ * readable buffer of at least \p tag_len Bytes. See note
+ * below regarding restrictions with PSA-based contexts.
+ * \param tag_len The length of the authentication tag. This must match
+ * the constraints imposed by the AEAD cipher used, and in
+ * particular must not be \c 0.
+ *
+ * \note If the context is based on PSA (that is, it was set up
+ * with mbedtls_cipher_setup_psa()), then it is required
+ * that \c tag == input + len. That is, the tag must be
+ * appended to the ciphertext as recommended by RFC 5116.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -934,9 +973,120 @@
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
- const unsigned char *tag, size_t tag_len );
+ const unsigned char *tag, size_t tag_len )
+ MBEDTLS_DEPRECATED;
+#undef MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
+/**
+ * \brief The authenticated encryption (AEAD/NIST_KW) function.
+ *
+ * \note For AEAD modes, the tag will be appended to the
+ * ciphertext, as recommended by RFC 5116.
+ * (NIST_KW doesn't have a separate tag.)
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a key, with an AEAD algorithm or NIST_KW.
+ * \param iv The nonce to use. This must be a readable buffer of
+ * at least \p iv_len Bytes and may be \c NULL if \p
+ * iv_len is \c 0.
+ * \param iv_len The length of the nonce. For AEAD ciphers, this must
+ * satisfy the constraints imposed by the cipher used.
+ * For NIST_KW, this must be \c 0.
+ * \param ad The additional data to authenticate. This must be a
+ * readable buffer of at least \p ad_len Bytes, and may
+ * be \c NULL is \p ad_len is \c 0.
+ * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0.
+ * \param input The buffer holding the input data. This must be a
+ * readable buffer of at least \p ilen Bytes, and may be
+ * \c NULL if \p ilen is \c 0.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data. This must be a
+ * writable buffer of at least \p output_len Bytes, and
+ * must not be \c NULL.
+ * \param output_len The length of the \p output buffer in Bytes. For AEAD
+ * ciphers, this must be at least \p ilen + \p tag_len.
+ * For NIST_KW, this must be at least \p ilen + 8
+ * (rounded up to a multiple of 8 if KWP is used);
+ * \p ilen + 15 is always a safe value.
+ * \param olen This will be filled with the actual number of Bytes
+ * written to the \p output buffer. This must point to a
+ * writable object of type \c size_t.
+ * \param tag_len The desired length of the authentication tag. For AEAD
+ * ciphers, this must match the constraints imposed by
+ * the cipher used, and in particular must not be \c 0.
+ * For NIST_KW, this must be \c 0.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len );
+
+/**
+ * \brief The authenticated encryption (AEAD/NIST_KW) function.
+ *
+ * \note If the data is not authentic, then the output buffer
+ * is zeroed out to prevent the unauthentic plaintext being
+ * used, making this interface safer.
+ *
+ * \note For AEAD modes, the tag must be appended to the
+ * ciphertext, as recommended by RFC 5116.
+ * (NIST_KW doesn't have a separate tag.)
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a key, with an AEAD algorithm or NIST_KW.
+ * \param iv The nonce to use. This must be a readable buffer of
+ * at least \p iv_len Bytes and may be \c NULL if \p
+ * iv_len is \c 0.
+ * \param iv_len The length of the nonce. For AEAD ciphers, this must
+ * satisfy the constraints imposed by the cipher used.
+ * For NIST_KW, this must be \c 0.
+ * \param ad The additional data to authenticate. This must be a
+ * readable buffer of at least \p ad_len Bytes, and may
+ * be \c NULL is \p ad_len is \c 0.
+ * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0.
+ * \param input The buffer holding the input data. This must be a
+ * readable buffer of at least \p ilen Bytes, and may be
+ * \c NULL if \p ilen is \c 0.
+ * \param ilen The length of the input data. For AEAD ciphers this
+ * must be at least \p tag_len. For NIST_KW this must be
+ * at least \c 8.
+ * \param output The buffer for the output data. This must be a
+ * writable buffer of at least \p output_len Bytes, and
+ * may be \c NULL if \p output_len is \c 0.
+ * \param output_len The length of the \p output buffer in Bytes. For AEAD
+ * ciphers, this must be at least \p ilen - \p tag_len.
+ * For NIST_KW, this must be at least \p ilen - 8.
+ * \param olen This will be filled with the actual number of Bytes
+ * written to the \p output buffer. This must point to a
+ * writable object of type \c size_t.
+ * \param tag_len The actual length of the authentication tag. For AEAD
+ * ciphers, this must match the constraints imposed by
+ * the cipher used, and in particular must not be \c 0.
+ * For NIST_KW, this must be \c 0.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
#ifdef __cplusplus
}
#endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 464b61e..b563a96 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1337,6 +1337,44 @@
*/
//#define MBEDTLS_PSA_CRYPTO_DRIVERS
+/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+ *
+ * Make the PSA Crypto module use an external random generator provided
+ * by a driver, instead of Mbed TLS's entropy and DRBG modules.
+ *
+ * \note This random generator must deliver random numbers with cryptographic
+ * quality and high performance. It must supply unpredictable numbers
+ * with a uniform distribution. The implementation of this function
+ * is responsible for ensuring that the random generator is seeded
+ * with sufficient entropy. If you have a hardware TRNG which is slow
+ * or delivers non-uniform output, declare it as an entropy source
+ * with mbedtls_entropy_add_source() instead of enabling this option.
+ *
+ * If you enable this option, you must configure the type
+ * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h
+ * and define a function called mbedtls_psa_external_get_random()
+ * with the following prototype:
+ * ```
+ * psa_status_t mbedtls_psa_external_get_random(
+ * mbedtls_psa_external_random_context_t *context,
+ * uint8_t *output, size_t output_size, size_t *output_length);
+ * );
+ * ```
+ * The \c context value is initialized to 0 before the first call.
+ * The function must fill the \c output buffer with \p output_size bytes
+ * of random data and set \c *output_length to \p output_size.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C
+ *
+ * \warning If you enable this option, code that uses the PSA cryptography
+ * interface will not use any of the entropy sources set up for
+ * the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED
+ * enables.
+ *
+ * \note This option is experimental and may be removed without notice.
+ */
+//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+
/**
* \def MBEDTLS_PSA_CRYPTO_SPM
*
@@ -1941,7 +1979,10 @@
/**
* \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
*
- * Enable modifying the maximum I/O buffer size.
+ * When this option is enabled, the SSL buffer will be resized automatically
+ * based on the negotiated maximum fragment length in each direction.
+ *
+ * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
*/
//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
@@ -3115,7 +3156,9 @@
*
* Module: library/psa_crypto.c
*
- * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
+ * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
+ * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C,
+ * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
*
*/
#define MBEDTLS_PSA_CRYPTO_C
@@ -3603,6 +3646,19 @@
*/
//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
+/* PSA options */
+/**
+ * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the
+ * PSA crypto subsystem.
+ *
+ * If this option is unset:
+ * - If CTR_DRBG is available, the PSA subsystem uses it rather than HMAC_DRBG.
+ * - Otherwise, the PSA subsystem uses HMAC_DRBG with either
+ * #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and
+ * on unspecified heuristics.
+ */
+//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
+
/* SSL Cache options */
//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 577c959..2097a6d 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -275,26 +275,26 @@
#endif
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
-static inline uint32_t mbedtls_ssl_get_output_buflen( const mbedtls_ssl_context *ctx )
+static inline size_t mbedtls_ssl_get_output_buflen( const mbedtls_ssl_context *ctx )
{
#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID)
- return (uint32_t) mbedtls_ssl_get_output_max_frag_len( ctx )
+ return mbedtls_ssl_get_output_max_frag_len( ctx )
+ MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD
+ MBEDTLS_SSL_CID_OUT_LEN_MAX;
#else
- return (uint32_t) mbedtls_ssl_get_output_max_frag_len( ctx )
+ return mbedtls_ssl_get_output_max_frag_len( ctx )
+ MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD;
#endif
}
-static inline uint32_t mbedtls_ssl_get_input_buflen( const mbedtls_ssl_context *ctx )
+static inline size_t mbedtls_ssl_get_input_buflen( const mbedtls_ssl_context *ctx )
{
#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID)
- return (uint32_t) mbedtls_ssl_get_input_max_frag_len( ctx )
+ return mbedtls_ssl_get_input_max_frag_len( ctx )
+ MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD
+ MBEDTLS_SSL_CID_IN_LEN_MAX;
#else
- return (uint32_t) mbedtls_ssl_get_input_max_frag_len( ctx )
+ return mbedtls_ssl_get_input_max_frag_len( ctx )
+ MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD;
#endif
}
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index 665a283..10c4316 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -37,7 +37,7 @@
* Major, Minor, Patchlevel
*/
#define MBEDTLS_VERSION_MAJOR 2
-#define MBEDTLS_VERSION_MINOR 24
+#define MBEDTLS_VERSION_MINOR 25
#define MBEDTLS_VERSION_PATCH 0
/**
@@ -45,9 +45,9 @@
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x02180000
-#define MBEDTLS_VERSION_STRING "2.24.0"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.24.0"
+#define MBEDTLS_VERSION_NUMBER 0x02190000
+#define MBEDTLS_VERSION_STRING "2.25.0"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.25.0"
#if defined(MBEDTLS_VERSION_C)
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index b41a20b..1adeda6 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -713,7 +713,7 @@
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p data buffer is too small. You can determine a
* sufficient buffer size by calling
- * #PSA_KEY_EXPORT_MAX_SIZE(\c type, \c bits)
+ * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits)
* where \c type is the key type
* and \c bits is the key size in bits.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
@@ -783,7 +783,7 @@
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p data buffer is too small. You can determine a
* sufficient buffer size by calling
- * #PSA_KEY_EXPORT_MAX_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits)
+ * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits)
* where \c type is the key type
* and \c bits is the key size in bits.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
@@ -822,7 +822,7 @@
* \param hash_size Size of the \p hash buffer in bytes.
* \param[out] hash_length On success, the number of bytes
* that make up the hash value. This is always
- * #PSA_HASH_SIZE(\p alg).
+ * #PSA_HASH_LENGTH(\p alg).
*
* \retval #PSA_SUCCESS
* Success.
@@ -1032,7 +1032,7 @@
* \param hash_size Size of the \p hash buffer in bytes.
* \param[out] hash_length On success, the number of bytes
* that make up the hash value. This is always
- * #PSA_HASH_SIZE(\c alg) where \c alg is the
+ * #PSA_HASH_LENGTH(\c alg) where \c alg is the
* hash algorithm that is calculated.
*
* \retval #PSA_SUCCESS
@@ -1041,7 +1041,7 @@
* The operation state is not valid (it must be active).
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p hash buffer is too small. You can determine a
- * sufficient buffer size by calling #PSA_HASH_SIZE(\c alg)
+ * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg)
* where \c alg is the hash algorithm that is calculated.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
@@ -1479,7 +1479,7 @@
* \param mac_size Size of the \p mac buffer in bytes.
* \param[out] mac_length On success, the number of bytes
* that make up the MAC value. This is always
- * #PSA_MAC_FINAL_SIZE(\c key_type, \c key_bits, \c alg)
+ * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg)
* where \c key_type and \c key_bits are the type and
* bit-size respectively of the key and \c alg is the
* MAC algorithm that is calculated.
@@ -1491,7 +1491,7 @@
* operation).
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p mac buffer is too small. You can determine a
- * sufficient buffer size by calling PSA_MAC_FINAL_SIZE().
+ * sufficient buffer size by calling PSA_MAC_LENGTH().
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
diff --git a/include/psa/crypto_accel_driver.h b/include/psa/crypto_accel_driver.h
deleted file mode 100644
index 4488ea8..0000000
--- a/include/psa/crypto_accel_driver.h
+++ /dev/null
@@ -1,823 +0,0 @@
-/**
- * \file psa/crypto_accel_driver.h
- * \brief PSA cryptography accelerator driver module
- *
- * This header declares types and function signatures for cryptography
- * drivers that access key material directly. This is meant for
- * on-chip cryptography accelerators.
- *
- * This file is part of the PSA Crypto Driver Model, containing functions for
- * driver developers to implement to enable hardware to be called in a
- * standardized way by a PSA Cryptographic API implementation. The functions
- * comprising the driver model, which driver authors implement, are not
- * intended to be called by application developers.
- */
-
-/*
- * Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef PSA_CRYPTO_ACCEL_DRIVER_H
-#define PSA_CRYPTO_ACCEL_DRIVER_H
-
-#include "crypto_driver_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** \defgroup driver_digest Hardware-Accelerated Message Digests
- *
- * Generation and authentication of Message Digests (aka hashes) must be done
- * in parts using the following sequence:
- * - `psa_drv_hash_setup_t`
- * - `psa_drv_hash_update_t`
- * - `psa_drv_hash_update_t`
- * - ...
- * - `psa_drv_hash_finish_t`
- *
- * If a previously started Message Digest operation needs to be terminated
- * before the `psa_drv_hash_finish_t` operation is complete, it should be aborted
- * by the `psa_drv_hash_abort_t`. Failure to do so may result in allocated
- * resources not being freed or in other undefined behavior.
- */
-/**@{*/
-
-/** \brief The hardware-specific hash context structure
- *
- * The contents of this structure are implementation dependent and are
- * therefore not described here
- */
-typedef struct psa_drv_hash_context_s psa_drv_hash_context_t;
-
-/** \brief The function prototype for the start operation of a hash (message
- * digest) operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_hash_<ALGO>_setup
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying hash function
- *
- * \param[in,out] p_context A structure that will contain the
- * hardware-specific hash context
- *
- * \retval #PSA_SUCCESS Success.
- */
-typedef psa_status_t (*psa_drv_hash_setup_t)(psa_drv_hash_context_t *p_context);
-
-/** \brief The function prototype for the update operation of a hash (message
- * digest) operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_hash_<ALGO>_update
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously-established hash operation to be
- * continued
- * \param[in] p_input A buffer containing the message to be appended
- * to the hash operation
- * \param[in] input_length The size in bytes of the input message buffer
- */
-typedef psa_status_t (*psa_drv_hash_update_t)(psa_drv_hash_context_t *p_context,
- const uint8_t *p_input,
- size_t input_length);
-
-/** \brief The function prototype for the finish operation of a hash (message
- * digest) operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_hash_<ALGO>_finish
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously started hash operation to be
- * fiinished
- * \param[out] p_output A buffer where the generated digest will be
- * placed
- * \param[in] output_size The size in bytes of the buffer that has been
- * allocated for the `p_output` buffer
- * \param[out] p_output_length The number of bytes placed in `p_output` after
- * success
- *
- * \retval #PSA_SUCCESS
- * Success.
- */
-typedef psa_status_t (*psa_drv_hash_finish_t)(psa_drv_hash_context_t *p_context,
- uint8_t *p_output,
- size_t output_size,
- size_t *p_output_length);
-
-/** \brief The function prototype for the abort operation of a hash (message
- * digest) operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_hash_<ALGO>_abort
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm
- *
- * \param[in,out] p_context A hardware-specific structure for the previously
- * started hash operation to be aborted
- */
-typedef void (*psa_drv_hash_abort_t)(psa_drv_hash_context_t *p_context);
-
-/**@}*/
-
-/** \defgroup accel_mac Hardware-Accelerated Message Authentication Code
- * Generation and authentication of Message Authentication Codes (MACs) using
- * cryptographic accelerators can be done either as a single function call (via the
- * `psa_drv_accel_mac_generate_t` or `psa_drv_accel_mac_verify_t`
- * functions), or in parts using the following sequence:
- * - `psa_drv_accel_mac_setup_t`
- * - `psa_drv_accel_mac_update_t`
- * - `psa_drv_accel_mac_update_t`
- * - ...
- * - `psa_drv_accel_mac_finish_t` or `psa_drv_accel_mac_finish_verify_t`
- *
- * If a previously started MAC operation needs to be terminated, it
- * should be done so by the `psa_drv_accel_mac_abort_t`. Failure to do so may
- * result in allocated resources not being freed or in other undefined
- * behavior.
- *
- */
-/**@{*/
-
-/** \brief The hardware-accelerator-specific MAC context structure
- *
- * The contents of this structure are implementation dependent and are
- * therefore not described here.
- */
-typedef struct psa_drv_accel_mac_context_s psa_drv_accel_mac_context_t;
-
-/** \brief The function prototype for the setup operation of a
- * hardware-accelerated MAC operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_mac_<ALGO>_<MAC_VARIANT>_setup
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying primitive, and `MAC_VARIANT`
- * is the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context A structure that will contain the
- * hardware-specific MAC context
- * \param[in] p_key A buffer containing the cleartext key material
- * to be used in the operation
- * \param[in] key_length The size in bytes of the key material
- *
- * \retval #PSA_SUCCESS
- * Success.
- */
-typedef psa_status_t (*psa_drv_accel_mac_setup_t)(psa_drv_accel_mac_context_t *p_context,
- const uint8_t *p_key,
- size_t key_length);
-
-/** \brief The function prototype for the update operation of a
- * hardware-accelerated MAC operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_mac_<ALGO>_<MAC_VARIANT>_update
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT`
- * is the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously-established MAC operation to be
- * continued
- * \param[in] p_input A buffer containing the message to be appended
- * to the MAC operation
- * \param[in] input_length The size in bytes of the input message buffer
- */
-typedef psa_status_t (*psa_drv_accel_mac_update_t)(psa_drv_accel_mac_context_t *p_context,
- const uint8_t *p_input,
- size_t input_length);
-
-/** \brief The function prototype for the finish operation of a
- * hardware-accelerated MAC operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_mac_<ALGO>_<MAC_VARIANT>_finish
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously started MAC operation to be
- * finished
- * \param[out] p_mac A buffer where the generated MAC will be placed
- * \param[in] mac_length The size in bytes of the buffer that has been
- * allocated for the `p_mac` buffer
- *
- * \retval #PSA_SUCCESS
- * Success.
- */
-typedef psa_status_t (*psa_drv_accel_mac_finish_t)(psa_drv_accel_mac_context_t *p_context,
- uint8_t *p_mac,
- size_t mac_length);
-
-/** \brief The function prototype for the finish and verify operation of a
- * hardware-accelerated MAC operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_mac_<ALGO>_<MAC_VARIANT>_finish_verify
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously started MAC operation to be
- * verified and finished
- * \param[in] p_mac A buffer containing the MAC that will be used
- * for verification
- * \param[in] mac_length The size in bytes of the data in the `p_mac`
- * buffer
- *
- * \retval #PSA_SUCCESS
- * The operation completed successfully and the comparison matched
- */
-typedef psa_status_t (*psa_drv_accel_mac_finish_verify_t)(psa_drv_accel_mac_context_t *p_context,
- const uint8_t *p_mac,
- size_t mac_length);
-
-/** \brief The function prototype for the abort operation for a previously
- * started hardware-accelerated MAC operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_mac_<ALGO>_<MAC_VARIANT>_abort
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously started MAC operation to be
- * aborted
- *
- */
-typedef psa_status_t (*psa_drv_accel_mac_abort_t)(psa_drv_accel_mac_context_t *p_context);
-
-/** \brief The function prototype for the one-shot operation of a
- * hardware-accelerated MAC operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_mac_<ALGO>_<MAC_VARIANT>
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in] p_input A buffer containing the data to be MACed
- * \param[in] input_length The length in bytes of the `p_input` data
- * \param[in] p_key A buffer containing the key material to be used
- * for the MAC operation
- * \param[in] key_length The length in bytes of the `p_key` data
- * \param[in] alg The algorithm to be performed
- * \param[out] p_mac The buffer where the resulting MAC will be placed
- * upon success
- * \param[in] mac_length The length in bytes of the `p_mac` buffer
- */
-typedef psa_status_t (*psa_drv_accel_mac_t)(const uint8_t *p_input,
- size_t input_length,
- const uint8_t *p_key,
- size_t key_length,
- psa_algorithm_t alg,
- uint8_t *p_mac,
- size_t mac_length);
-
-/** \brief The function prototype for the one-shot hardware-accelerated MAC
- * Verify operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_mac_<ALGO>_<MAC_VARIANT>_verify
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in] p_input A buffer containing the data to be MACed
- * \param[in] input_length The length in bytes of the `p_input` data
- * \param[in] p_key A buffer containing the key material to be used
- * for the MAC operation
- * \param[in] key_length The length in bytes of the `p_key` data
- * \param[in] alg The algorithm to be performed
- * \param[in] p_mac The MAC data to be compared
- * \param[in] mac_length The length in bytes of the `p_mac` buffer
- *
- * \retval #PSA_SUCCESS
- * The operation completed successfully and the comparison matched
- */
-typedef psa_status_t (*psa_drv_accel_mac_verify_t)(const uint8_t *p_input,
- size_t input_length,
- const uint8_t *p_key,
- size_t key_length,
- psa_algorithm_t alg,
- const uint8_t *p_mac,
- size_t mac_length);
-/**@}*/
-
-/** \defgroup accel_cipher Hardware-Accelerated Block Ciphers
- * Encryption and Decryption using hardware-acceleration in block modes other
- * than ECB must be done in multiple parts, using the following flow:
- * - `psa_drv_accel_ciphersetup_t`
- * - `psa_drv_accel_cipher_set_iv_t` (optional depending upon block mode)
- * - `psa_drv_accel_cipher_update_t`
- * - `psa_drv_accel_cipher_update_t`
- * - ...
- * - `psa_drv_accel_cipher_finish_t`
- *
- * If a previously started hardware-accelerated Cipher operation needs to be
- * terminated, it should be done so by the `psa_drv_accel_cipher_abort_t`.
- * Failure to do so may result in allocated resources not being freed or in
- * other undefined behavior.
- */
-/**@{*/
-
-/** \brief The hardware-accelerator-specific cipher context structure
- *
- * The contents of this structure are implementation dependent and are
- * therefore not described here.
- */
-typedef struct psa_drv_accel_cipher_context_s psa_drv_accel_cipher_context_t;
-
-/** \brief The function prototype for the setup operation of
- * hardware-accelerated block cipher operations.
- * Functions that implement this prototype should be named in the following
- * conventions:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_cipher_setup_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * For stream ciphers:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_cipher_setup_<CIPHER_NAME>
- * ~~~~~~~~~~~~~
- * Where `CIPHER_NAME` is the name of a stream cipher (i.e. RC4)
- *
- * \param[in,out] p_context A structure that will contain the
- * hardware-specific cipher context
- * \param[in] direction Indicates if the operation is an encrypt or a
- * decrypt
- * \param[in] p_key_data A buffer containing the cleartext key material
- * to be used in the operation
- * \param[in] key_data_size The size in bytes of the key material
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_accel_cipher_setup_t)(psa_drv_accel_cipher_context_t *p_context,
- psa_encrypt_or_decrypt_t direction,
- const uint8_t *p_key_data,
- size_t key_data_size);
-
-/** \brief The function prototype for the set initialization vector operation
- * of hardware-accelerated block cipher operations
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_cipher_set_iv_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * \param[in,out] p_context A structure that contains the previously setup
- * hardware-specific cipher context
- * \param[in] p_iv A buffer containing the initialization vecotr
- * \param[in] iv_length The size in bytes of the contents of `p_iv`
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_accel_cipher_set_iv_t)(psa_drv_accel_cipher_context_t *p_context,
- const uint8_t *p_iv,
- size_t iv_length);
-
-/** \brief The function prototype for the update operation of
- * hardware-accelerated block cipher operations.
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_cipher_update_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously started cipher operation
- * \param[in] p_input A buffer containing the data to be
- * encrypted or decrypted
- * \param[in] input_size The size in bytes of the `p_input` buffer
- * \param[out] p_output A caller-allocated buffer where the
- * generated output will be placed
- * \param[in] output_size The size in bytes of the `p_output` buffer
- * \param[out] p_output_length After completion, will contain the number
- * of bytes placed in the `p_output` buffer
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_accel_cipher_update_t)(psa_drv_accel_cipher_context_t *p_context,
- const uint8_t *p_input,
- size_t input_size,
- uint8_t *p_output,
- size_t output_size,
- size_t *p_output_length);
-
-/** \brief The function prototype for the finish operation of
- * hardware-accelerated block cipher operations.
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_cipher_finish_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously started cipher operation
- * \param[out] p_output A caller-allocated buffer where the generated
- * output will be placed
- * \param[in] output_size The size in bytes of the `p_output` buffer
- * \param[out] p_output_length After completion, will contain the number of
- * bytes placed in the `p_output` buffer
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_accel_cipher_finish_t)(psa_drv_accel_cipher_context_t *p_context,
- uint8_t *p_output,
- size_t output_size,
- size_t *p_output_length);
-
-/** \brief The function prototype for the abort operation of
- * hardware-accelerated block cipher operations.
- *
- * Functions that implement the following prototype should be named in the
- * following convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_cipher_abort_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * \param[in,out] p_context A hardware-specific structure for the
- * previously started cipher operation
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_accel_cipher_abort_t)(psa_drv_accel_cipher_context_t *p_context);
-
-/**@}*/
-
-/** \defgroup accel_aead Hardware-Accelerated Authenticated Encryption with Additional Data
- *
- * Hardware-accelerated Authenticated Encryption with Additional Data (AEAD)
- * operations must be done in one function call. While this creates a burden
- * for implementers as there must be sufficient space in memory for the entire
- * message, it prevents decrypted data from being made available before the
- * authentication operation is complete and the data is known to be authentic.
- */
-/**@{*/
-
-/** \brief The function prototype for the hardware-accelerated authenticated
- * encryption operation.
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_aead_<ALGO>_encrypt
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the AEAD algorithm
- *
- * \param[in] p_key A pointer to the key material
- * \param[in] key_length The size in bytes of the key material
- * \param[in] alg The AEAD algorithm to compute
- * (\c PSA_ALG_XXX value such that
- * #PSA_ALG_IS_AEAD(`alg`) is true)
- * \param[in] nonce Nonce or IV to use
- * \param[in] nonce_length Size of the `nonce` buffer in bytes
- * \param[in] additional_data Additional data that will be MACed
- * but not encrypted.
- * \param[in] additional_data_length Size of `additional_data` in bytes
- * \param[in] plaintext Data that will be MACed and
- * encrypted.
- * \param[in] plaintext_length Size of `plaintext` in bytes
- * \param[out] ciphertext Output buffer for the authenticated and
- * encrypted data. The additional data is
- * not part of this output. For algorithms
- * where the encrypted data and the
- * authentication tag are defined as
- * separate outputs, the authentication
- * tag is appended to the encrypted data.
- * \param[in] ciphertext_size Size of the `ciphertext` buffer in
- * bytes
- * This must be at least
- * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(`alg`,
- * `plaintext_length`).
- * \param[out] ciphertext_length On success, the size of the output in
- * the `ciphertext` buffer
- *
- * \retval #PSA_SUCCESS
- *
- */
-typedef psa_status_t (*psa_drv_accel_aead_encrypt_t)(const uint8_t *p_key,
- size_t key_length,
- psa_algorithm_t alg,
- const uint8_t *nonce,
- size_t nonce_length,
- const uint8_t *additional_data,
- size_t additional_data_length,
- const uint8_t *plaintext,
- size_t plaintext_length,
- uint8_t *ciphertext,
- size_t ciphertext_size,
- size_t *ciphertext_length);
-
-/** \brief The function prototype for the hardware-accelerated authenticated
- * decryption operation.
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_aead_<ALGO>_decrypt
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the AEAD algorithm
- * \param[in] p_key A pointer to the key material
- * \param[in] key_length The size in bytes of the key material
- * \param[in] alg The AEAD algorithm to compute
- * (\c PSA_ALG_XXX value such that
- * #PSA_ALG_IS_AEAD(`alg`) is true)
- * \param[in] nonce Nonce or IV to use
- * \param[in] nonce_length Size of the `nonce` buffer in bytes
- * \param[in] additional_data Additional data that has been MACed
- * but not encrypted
- * \param[in] additional_data_length Size of `additional_data` in bytes
- * \param[in] ciphertext Data that has been MACed and
- * encrypted
- * For algorithms where the encrypted data
- * and the authentication tag are defined
- * as separate inputs, the buffer must
- * contain the encrypted data followed by
- * the authentication tag.
- * \param[in] ciphertext_length Size of `ciphertext` in bytes
- * \param[out] plaintext Output buffer for the decrypted data
- * \param[in] plaintext_size Size of the `plaintext` buffer in
- * bytes
- * This must be at least
- * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(`alg`,
- * `ciphertext_length`).
- * \param[out] plaintext_length On success, the size of the output
- * in the \b plaintext buffer
- *
- * \retval #PSA_SUCCESS
- * Success.
- */
-typedef psa_status_t (*psa_drv_accel_aead_decrypt_t)(const uint8_t *p_key,
- size_t key_length,
- psa_algorithm_t alg,
- const uint8_t *nonce,
- size_t nonce_length,
- const uint8_t *additional_data,
- size_t additional_data_length,
- const uint8_t *ciphertext,
- size_t ciphertext_length,
- uint8_t *plaintext,
- size_t plaintext_size,
- size_t *plaintext_length);
-
-/**@}*/
-
-/** \defgroup accel_asymmetric Hardware-Accelerated Asymmetric Cryptography
- *
- * Since the amount of data that can (or should) be encrypted or signed using
- * asymmetric keys is limited by the key size, hardware-accelerated asymmetric
- * key operations must be done in single function calls.
- */
-/**@{*/
-
-
-/**
- * \brief The function prototype for the hardware-accelerated asymmetric sign
- * operation.
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_asymmetric_<ALGO>_sign
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the signing algorithm
- *
- * This function supports any asymmetric-key output from psa_export_key() as
- * the buffer in \p p_key. Refer to the documentation of \ref
- * psa_export_key() for the formats.
- *
- * \param[in] p_key A buffer containing the private key
- * material
- * \param[in] key_size The size in bytes of the `p_key` data
- * \param[in] alg A signature algorithm that is compatible
- * with the type of `p_key`
- * \param[in] p_hash The hash or message to sign
- * \param[in] hash_length Size of the `p_hash` buffer in bytes
- * \param[out] p_signature Buffer where the signature is to be written
- * \param[in] signature_size Size of the `p_signature` buffer in bytes
- * \param[out] p_signature_length On success, the number of bytes
- * that make up the returned signature value
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_accel_asymmetric_sign_t)(const uint8_t *p_key,
- size_t key_size,
- psa_algorithm_t alg,
- psa_key_type_t key_type,
- const uint8_t *p_hash,
- size_t hash_length,
- uint8_t *p_signature,
- size_t signature_size,
- size_t *p_signature_length);
-
-/**
- * \brief The function prototype for the hardware-accelerated signature verify
- * operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_asymmetric_<ALGO>_verify
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the signing algorithm
- *
- * This function supports any output from \ref psa_export_public_key() as the
- * buffer in \p p_key. Refer to the documentation of \ref
- * psa_export_public_key() for the format of public keys and to the
- * documentation of \ref psa_export_key() for the format for other key types.
- *
- * \param[in] p_key A buffer containing the public key material
- * \param[in] key_size The size in bytes of the `p_key` data
- * \param[in] alg A signature algorithm that is compatible with
- * the type of `key`
- * \param[in] p_hash The hash or message whose signature is to be
- * verified
- * \param[in] hash_length Size of the `p_hash` buffer in bytes
- * \param[in] p_signature Buffer containing the signature to verify
- * \param[in] signature_length Size of the `p_signature` buffer in bytes
- *
- * \retval #PSA_SUCCESS
- * The signature is valid.
- */
-typedef psa_status_t (*psa_drv_accel_asymmetric_verify_t)(const uint8_t *p_key,
- size_t key_size,
- psa_algorithm_t alg,
- psa_key_type_t key_type,
- const uint8_t *p_hash,
- size_t hash_length,
- const uint8_t *p_signature,
- size_t signature_length);
-
-/**
- * \brief The function prototype for the hardware-accelerated asymmetric
- * encrypt operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_asymmetric_<ALGO>_encrypt
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the encryption algorithm
- *
- * This function supports any output from \ref psa_export_public_key() as the
- * buffer in \p p_key. Refer to the documentation of \ref
- * psa_export_public_key() for the format of public keys and to the
- * documentation of \ref psa_export_key() for the format for other key types.
- *
- * \param[in] p_key A buffer containing the public key material
- * \param[in] key_size The size in bytes of the `p_key` data
- * \param[in] alg An asymmetric encryption algorithm that is
- * compatible with the type of `key`
- * \param[in] p_input The message to encrypt
- * \param[in] input_length Size of the `p_input` buffer in bytes
- * \param[in] p_salt A salt or label, if supported by the
- * encryption algorithm
- * If the algorithm does not support a
- * salt, pass `NULL`
- * If the algorithm supports an optional
- * salt and you do not want to pass a salt,
- * pass `NULL`.
- * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
- * supported.
- * \param[in] salt_length Size of the `p_salt` buffer in bytes
- * If `p_salt` is `NULL`, pass 0.
- * \param[out] p_output Buffer where the encrypted message is to
- * be written
- * \param[in] output_size Size of the `p_output` buffer in bytes
- * \param[out] p_output_length On success, the number of bytes
- * that make up the returned output
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_accel_asymmetric_encrypt_t)(const uint8_t *p_key,
- size_t key_size,
- psa_algorithm_t alg,
- psa_key_type_t key_type,
- const uint8_t *p_input,
- size_t input_length,
- const uint8_t *p_salt,
- size_t salt_length,
- uint8_t *p_output,
- size_t output_size,
- size_t *p_output_length);
-
-/**
- * \brief The function prototype for the hardware=acce;erated asymmetric
- * decrypt operation
- *
- * Functions that implement this prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_accel_asymmetric_<ALGO>_decrypt
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the encryption algorithm
- *
- * This function supports any asymmetric-key output from psa_export_key() as
- * the buffer in \p p_key. Refer to the documentation of \ref
- * psa_export_key() for the formats.
- *
- * \param[in] p_key A buffer containing the private key material
- * \param[in] key_size The size in bytes of the `p_key` data
- * \param[in] alg An asymmetric encryption algorithm that is
- * compatible with the type of `key`
- * \param[in] p_input The message to decrypt
- * \param[in] input_length Size of the `p_input` buffer in bytes
- * \param[in] p_salt A salt or label, if supported by the
- * encryption algorithm
- * If the algorithm does not support a
- * salt, pass `NULL`.
- * If the algorithm supports an optional
- * salt and you do not want to pass a salt,
- * pass `NULL`.
- * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
- * supported
- * \param[in] salt_length Size of the `p_salt` buffer in bytes
- * If `p_salt` is `NULL`, pass 0
- * \param[out] p_output Buffer where the decrypted message is to
- * be written
- * \param[in] output_size Size of the `p_output` buffer in bytes
- * \param[out] p_output_length On success, the number of bytes
- * that make up the returned output
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_accel_asymmetric_decrypt_t)(const uint8_t *p_key,
- size_t key_size,
- psa_algorithm_t alg,
- psa_key_type_t key_type,
- const uint8_t *p_input,
- size_t input_length,
- const uint8_t *p_salt,
- size_t salt_length,
- uint8_t *p_output,
- size_t output_size,
- size_t *p_output_length);
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PSA_CRYPTO_ACCEL_DRIVER_H */
diff --git a/include/psa/crypto_compat.h b/include/psa/crypto_compat.h
index 5bb5669..728d283 100644
--- a/include/psa/crypto_compat.h
+++ b/include/psa/crypto_compat.h
@@ -110,6 +110,18 @@
MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGNATURE_MAX_SIZE )
#define PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) \
MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) )
+#define PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits ) \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ) )
+#define PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ) )
+#define PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE )
+#define PSA_HASH_SIZE( alg ) \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_HASH_LENGTH( alg ) )
+#define PSA_MAC_FINAL_SIZE( key_type, key_bits, alg ) \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_MAC_LENGTH( key_type, key_bits, alg ) )
+#define PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE )
/*
* Deprecated PSA Crypto function names (PSA Crypto API <= 1.0 beta3)
diff --git a/include/psa/crypto_driver_common.h b/include/psa/crypto_driver_common.h
index 2ce75d2..1b6f322 100644
--- a/include/psa/crypto_driver_common.h
+++ b/include/psa/crypto_driver_common.h
@@ -5,9 +5,8 @@
* This file contains common definitions shared by all PSA crypto drivers.
* Do not include it directly: instead, include the header file(s) for
* the type(s) of driver that you are implementing. For example, if
- * you are writing a driver for a chip that provides both a hardware
- * random generator and an accelerator for some cryptographic algorithms,
- * include `psa/crypto_entropy_driver.h` and `psa/crypto_accel_driver.h`.
+ * you are writing a dynamically registered driver for a secure element,
+ * include `psa/crypto_se_driver.h`.
*
* This file is part of the PSA Crypto Driver Model, containing functions for
* driver developers to implement to enable hardware to be called in a
diff --git a/include/psa/crypto_entropy_driver.h b/include/psa/crypto_entropy_driver.h
deleted file mode 100644
index 9b6546e..0000000
--- a/include/psa/crypto_entropy_driver.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * \file psa/crypto_entropy_driver.h
- * \brief PSA entropy source driver module
- *
- * This header declares types and function signatures for entropy sources.
- *
- * This file is part of the PSA Crypto Driver Model, containing functions for
- * driver developers to implement to enable hardware to be called in a
- * standardized way by a PSA Cryptographic API implementation. The functions
- * comprising the driver model, which driver authors implement, are not
- * intended to be called by application developers.
- */
-
-/*
- * Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef PSA_CRYPTO_ENTROPY_DRIVER_H
-#define PSA_CRYPTO_ENTROPY_DRIVER_H
-
-#include "crypto_driver_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** \defgroup driver_rng Entropy Generation
- */
-/**@{*/
-
-/** \brief Initialize an entropy driver
- *
- *
- * \param[in,out] p_context A hardware-specific structure
- * containing any context information for
- * the implementation
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_entropy_init_t)(void *p_context);
-
-/** \brief Get a specified number of bits from the entropy source
- *
- * It retrives `buffer_size` bytes of data from the entropy source. The entropy
- * source will always fill the provided buffer to its full size, however, most
- * entropy sources have biases, and the actual amount of entropy contained in
- * the buffer will be less than the number of bytes.
- * The driver will return the actual number of bytes of entropy placed in the
- * buffer in `p_received_entropy_bytes`.
- * A PSA Crypto API implementation will likely feed the output of this function
- * into a Digital Random Bit Generator (DRBG), and typically has a minimum
- * amount of entropy that it needs.
- * To accomplish this, the PSA Crypto implementation should be designed to call
- * this function multiple times until it has received the required amount of
- * entropy from the entropy source.
- *
- * \param[in,out] p_context A hardware-specific structure
- * containing any context information
- * for the implementation
- * \param[out] p_buffer A caller-allocated buffer for the
- * retrieved entropy to be placed in
- * \param[in] buffer_size The allocated size of `p_buffer`
- * \param[out] p_received_entropy_bits The amount of entropy (in bits)
- * actually provided in `p_buffer`
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_entropy_get_bits_t)(void *p_context,
- uint8_t *p_buffer,
- uint32_t buffer_size,
- uint32_t *p_received_entropy_bits);
-
-/**
- * \brief A struct containing all of the function pointers needed to interface
- * to an entropy source
- *
- * PSA Crypto API implementations should populate instances of the table as
- * appropriate upon startup.
- *
- * If one of the functions is not implemented, it should be set to NULL.
- */
-typedef struct {
- /** The driver-specific size of the entropy context */
- const size_t context_size;
- /** Function that performs initialization for the entropy source */
- psa_drv_entropy_init_t p_init;
- /** Function that performs the get_bits operation for the entropy source */
- psa_drv_entropy_get_bits_t p_get_bits;
-} psa_drv_entropy_t;
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PSA_CRYPTO_ENTROPY_DRIVER_H */
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index f793a6c..9abce33 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -649,6 +649,57 @@
/**@}*/
+/** \defgroup psa_external_rng External random generator
+ * @{
+ */
+
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+/** External random generator function, implemented by the platform.
+ *
+ * When the compile-time option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled,
+ * this function replaces Mbed TLS's entropy and DRBG modules for all
+ * random generation triggered via PSA crypto interfaces.
+ *
+ * \note This random generator must deliver random numbers with cryptographic
+ * quality and high performance. It must supply unpredictable numbers
+ * with a uniform distribution. The implementation of this function
+ * is responsible for ensuring that the random generator is seeded
+ * with sufficient entropy. If you have a hardware TRNG which is slow
+ * or delivers non-uniform output, declare it as an entropy source
+ * with mbedtls_entropy_add_source() instead of enabling this option.
+ *
+ * \param[in,out] context Pointer to the random generator context.
+ * This is all-bits-zero on the first call
+ * and preserved between successive calls.
+ * \param[out] output Output buffer. On success, this buffer
+ * contains random data with a uniform
+ * distribution.
+ * \param output_size The size of the \p output buffer in bytes.
+ * \param[out] output_length On success, set this value to \p output_size.
+ *
+ * \retval #PSA_SUCCESS
+ * Success. The output buffer contains \p output_size bytes of
+ * cryptographic-quality random data, and \c *output_length is
+ * set to \p output_size.
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ * The random generator requires extra entropy and there is no
+ * way to obtain entropy under current environment conditions.
+ * This error should not happen under normal circumstances since
+ * this function is responsible for obtaining as much entropy as
+ * it needs. However implementations of this function may return
+ * #PSA_ERROR_INSUFFICIENT_ENTROPY if there is no way to obtain
+ * entropy without blocking indefinitely.
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * A failure of the random generator hardware that isn't covered
+ * by #PSA_ERROR_INSUFFICIENT_ENTROPY.
+ */
+psa_status_t mbedtls_psa_external_get_random(
+ mbedtls_psa_external_random_context_t *context,
+ uint8_t *output, size_t output_size, size_t *output_length );
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
+/**@}*/
+
#ifdef __cplusplus
}
#endif
diff --git a/include/psa/crypto_platform.h b/include/psa/crypto_platform.h
index 567398d..8acf22c 100644
--- a/include/psa/crypto_platform.h
+++ b/include/psa/crypto_platform.h
@@ -81,4 +81,19 @@
#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+/** The type of the context passed to mbedtls_psa_external_get_random().
+ *
+ * Mbed TLS initializes the context to all-bits-zero before calling
+ * mbedtls_psa_external_get_random() for the first time.
+ *
+ * The definition of this type in the Mbed TLS source code is for
+ * demonstration purposes. Implementers of mbedtls_psa_external_get_random()
+ * are expected to replace it with a custom definition.
+ */
+typedef struct {
+ uintptr_t opaque[2];
+} mbedtls_psa_external_random_context_t;
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
#endif /* PSA_CRYPTO_PLATFORM_H */
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index 3df01b2..34e69be 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -68,8 +68,8 @@
* An implementation may return either 0 or the correct size
* for a hash algorithm that it recognizes, but does not support.
*/
-#define PSA_HASH_SIZE(alg) \
- ( \
+#define PSA_HASH_LENGTH(alg) \
+ ( \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 : \
@@ -188,10 +188,11 @@
#define PSA_VENDOR_ECC_MAX_CURVE_BITS 0
#endif
-/** \def PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN
+/** This macro returns the maximum supported length of the PSK for the
+ * TLS-1.2 PSK-to-MS key derivation
+ * (#PSA_ALG_TLS12_PSK_TO_MS(\p hash_alg)).
*
- * This macro returns the maximum length of the PSK supported
- * by the TLS-1.2 PSK-to-MS key derivation.
+ * The maximum supported length does not depend on the chosen hash algorithm.
*
* Quoting RFC 4279, Sect 5.3:
* TLS implementations supporting these ciphersuites MUST support
@@ -200,17 +201,21 @@
* keys is RECOMMENDED.
*
* Therefore, no implementation should define a value smaller than 64
- * for #PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN.
+ * for #PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE.
*/
-#define PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN 128
+#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE 128
/** The maximum size of a block cipher supported by the implementation. */
-#define PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE 16
+#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE 16
/** The size of the output of psa_mac_sign_finish(), in bytes.
*
* This is also the MAC size that psa_mac_verify_finish() expects.
*
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
* \param key_type The type of the MAC key.
* \param key_bits The size of the MAC key in bits.
* \param alg A MAC algorithm (\c PSA_ALG_XXX value such that
@@ -224,10 +229,10 @@
* \return Unspecified if the key parameters are not consistent
* with the algorithm.
*/
-#define PSA_MAC_FINAL_SIZE(key_type, key_bits, alg) \
- ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \
- PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_GET_HASH(alg)) : \
- PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
+#define PSA_MAC_LENGTH(key_type, key_bits, alg) \
+ ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \
+ PSA_ALG_IS_HMAC(alg) ? PSA_HASH_LENGTH(PSA_ALG_HMAC_GET_HASH(alg)) : \
+ PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
((void)(key_type), (void)(key_bits), 0))
/** The maximum size of the output of psa_aead_encrypt(), in bytes.
@@ -303,7 +308,7 @@
* implementation to delay the output until it has a full block. */
#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
- PSA_ROUND_UP_TO_MULTIPLE(PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE, (input_length)) : \
+ PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length)) : \
(input_length))
/** A sufficient ciphertext buffer size for psa_aead_finish().
@@ -326,7 +331,7 @@
*/
#define PSA_AEAD_FINISH_OUTPUT_SIZE(alg) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
- PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
+ PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE : \
0)
/** A sufficient plaintext buffer size for psa_aead_verify().
@@ -349,12 +354,12 @@
*/
#define PSA_AEAD_VERIFY_OUTPUT_SIZE(alg) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
- PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
+ PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE : \
0)
#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
(PSA_ALG_IS_RSA_OAEP(alg) ? \
- 2 * PSA_HASH_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
+ 2 * PSA_HASH_LENGTH(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
11 /*PKCS#1v1.5*/)
/**
@@ -587,12 +592,13 @@
#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \
(PSA_BITS_TO_BYTES(key_bits))
-/** Sufficient output buffer size for psa_export_key() or psa_export_public_key().
+/** Sufficient output buffer size for psa_export_key() or
+ * psa_export_public_key().
*
* This macro returns a compile-time constant if its arguments are
* compile-time constants.
*
- * \warning This function may call its arguments multiple times or
+ * \warning This macro may evaluate its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
@@ -605,7 +611,7 @@
* if (status != PSA_SUCCESS) handle_error(...);
* psa_key_type_t key_type = psa_get_key_type(&attributes);
* size_t key_bits = psa_get_key_bits(&attributes);
- * size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits);
+ * size_t buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits);
* psa_reset_key_attributes(&attributes);
* uint8_t *buffer = malloc(buffer_size);
* if (buffer == NULL) handle_error(...);
@@ -614,32 +620,12 @@
* if (status != PSA_SUCCESS) handle_error(...);
* \endcode
*
- * For psa_export_public_key(), calculate the buffer size from the
- * public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR
- * to convert a key pair type to the corresponding public key type.
- * \code{c}
- * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- * psa_status_t status;
- * status = psa_get_key_attributes(key, &attributes);
- * if (status != PSA_SUCCESS) handle_error(...);
- * psa_key_type_t key_type = psa_get_key_type(&attributes);
- * psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
- * size_t key_bits = psa_get_key_bits(&attributes);
- * size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(public_key_type, key_bits);
- * psa_reset_key_attributes(&attributes);
- * uint8_t *buffer = malloc(buffer_size);
- * if (buffer == NULL) handle_error(...);
- * size_t buffer_length;
- * status = psa_export_public_key(key, buffer, buffer_size, &buffer_length);
- * if (status != PSA_SUCCESS) handle_error(...);
- * \endcode
- *
* \param key_type A supported key type.
* \param key_bits The size of the key in bits.
*
* \return If the parameters are valid and supported, return
* a buffer size in bytes that guarantees that
- * psa_sign_hash() will not fail with
+ * psa_export_key() or psa_export_public_key() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro shall return either a
@@ -647,14 +633,14 @@
* If the parameters are not valid, the
* return value is unspecified.
*/
-#define PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) \
- (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
- (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
+#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \
+ (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
- (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
- PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
- PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
0)
/** The default nonce size for an AEAD algorithm, in bytes.
@@ -683,7 +669,7 @@
* and AEAD algorithm that it recognizes, but does not support.
*/
#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \
- (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) == 16 && \
+ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) == 16 && \
(PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CCM || \
PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_GCM) ? 12 : \
(key_type) == PSA_KEY_TYPE_CHACHA20 && \
@@ -727,13 +713,13 @@
* and cipher algorithm that it recognizes, but does not support.
*/
#define PSA_CIPHER_IV_LENGTH(key_type, alg) \
- (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) > 1 && \
+ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \
((alg) == PSA_ALG_CTR || \
(alg) == PSA_ALG_CFB || \
(alg) == PSA_ALG_OFB || \
(alg) == PSA_ALG_XTS || \
(alg) == PSA_ALG_CBC_NO_PADDING || \
- (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
+ (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
(key_type) == PSA_KEY_TYPE_CHACHA20 && \
(alg) == PSA_ALG_STREAM_CIPHER ? 12 : \
0)
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index 0a2ae54..9804881 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -115,14 +115,14 @@
* whether the key is _volatile_ or _persistent_.
* See ::psa_key_persistence_t for more information.
* - Bits 8-31 (#PSA_KEY_LIFETIME_GET_LOCATION(\c lifetime)):
- * location indicator. This value indicates where the key is stored
- * and where operations on the key are performed.
+ * location indicator. This value indicates which part of the system
+ * has access to the key material and can perform operations using the key.
* See ::psa_key_location_t for more information.
*
* Volatile keys are automatically destroyed when the application instance
* terminates or on a power reset of the device. Persistent keys are
* preserved until the application explicitly destroys them or until an
- * implementation-specific device management event occurs (for example,
+ * integration-specific device management event occurs (for example,
* a factory reset).
*
* Persistent keys have a key identifier of type #mbedtls_svc_key_id_t.
@@ -131,12 +131,10 @@
* The application can call psa_open_key() to open a persistent key that
* it created previously.
*
- * This specification defines two basic lifetime values:
- * - Keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE are volatile.
- * All implementations should support this lifetime.
- * - Keys with the lifetime #PSA_KEY_LIFETIME_PERSISTENT are persistent.
- * All implementations that have access to persistent storage with
- * appropriate security guarantees should support this lifetime.
+ * The default lifetime of a key is #PSA_KEY_LIFETIME_VOLATILE. The lifetime
+ * #PSA_KEY_LIFETIME_PERSISTENT is supported if persistent storage is
+ * available. Other lifetime values may be supported depending on the
+ * library configuration.
*/
typedef uint32_t psa_key_lifetime_t;
@@ -149,35 +147,21 @@
* actually affect persistent keys at different levels is outside the
* scope of the PSA Cryptography specification.
*
- * This specification defines the following values of persistence levels:
+ * The PSA Cryptography specification defines the following values of
+ * persistence levels:
* - \c 0 = #PSA_KEY_PERSISTENCE_VOLATILE: volatile key.
* A volatile key is automatically destroyed by the implementation when
* the application instance terminates. In particular, a volatile key
* is automatically destroyed on a power reset of the device.
* - \c 1 = #PSA_KEY_PERSISTENCE_DEFAULT:
* persistent key with a default lifetime.
- * Implementations should support this value if they support persistent
- * keys at all.
- * Applications should use this value if they have no specific needs that
- * are only met by implementation-specific features.
- * - \c 2-127: persistent key with a PSA-specified lifetime.
- * The PSA Cryptography specification does not define the meaning of these
- * values, but other PSA specifications may do so.
- * - \c 128-254: persistent key with a vendor-specified lifetime.
- * No PSA specification will define the meaning of these values, so
- * implementations may choose the meaning freely.
- * As a guideline, higher persistence levels should cause a key to survive
- * more management events than lower levels.
+ * - \c 2-254: currently not supported by Mbed TLS.
* - \c 255 = #PSA_KEY_PERSISTENCE_READ_ONLY:
* read-only or write-once key.
* A key with this persistence level cannot be destroyed.
- * Implementations that support such keys may either allow their creation
- * through the PSA Cryptography API, preferably only to applications with
- * the appropriate privilege, or only expose keys created through
- * implementation-specific means such as a factory ROM engraving process.
- * Note that keys that are read-only due to policy restrictions
- * rather than due to physical limitations should not have this
- * persistence levels.
+ * Mbed TLS does not currently offer a way to create such keys, but
+ * integrations of Mbed TLS can use it for built-in keys that the
+ * application cannot modify (for example, a hardware unique key (HUK)).
*
* \note Key persistence levels are 8-bit values. Key management
* interfaces operate on lifetimes (type ::psa_key_lifetime_t) which
@@ -187,28 +171,30 @@
/** Encoding of key location indicators.
*
- * If an implementation of this API can make calls to external
+ * If an integration of Mbed TLS can make calls to external
* cryptoprocessors such as secure elements, the location of a key
* indicates which secure element performs the operations on the key.
- * If an implementation offers multiple physical locations for persistent
- * storage, the location indicator reflects at which physical location
- * the key is stored.
+ * Depending on the design of the secure element, the key
+ * material may be stored either in the secure element, or
+ * in wrapped (encrypted) form alongside the key metadata in the
+ * primary local storage.
*
- * This specification defines the following values of location indicators:
+ * The PSA Cryptography API specification defines the following values of
+ * location indicators:
* - \c 0: primary local storage.
- * All implementations should support this value.
+ * This location is always available.
* The primary local storage is typically the same storage area that
* contains the key metadata.
* - \c 1: primary secure element.
- * Implementations should support this value if there is a secure element
- * attached to the operating environment.
+ * Integrations of Mbed TLS should support this value if there is a secure
+ * element attached to the operating environment.
* As a guideline, secure elements may provide higher resistance against
* side channel and physical attacks than the primary local storage, but may
* have restrictions on supported key types, sizes, policies and operations
* and may have different performance characteristics.
* - \c 2-0x7fffff: other locations defined by a PSA specification.
* The PSA Cryptography API does not currently assign any meaning to these
- * locations, but future versions of this specification or other PSA
+ * locations, but future versions of that specification or other PSA
* specifications may do so.
* - \c 0x800000-0xffffff: vendor-defined locations.
* No PSA specification will assign a meaning to locations in this range.
@@ -223,7 +209,7 @@
*
* - Applications may freely choose key identifiers in the range
* #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX.
- * - Implementations may define additional key identifiers in the range
+ * - The implementation may define additional key identifiers in the range
* #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX.
* - 0 is reserved as an invalid key identifier.
* - Key identifiers outside these ranges are reserved for future use.
@@ -271,23 +257,18 @@
* - The key's policy, comprising usage flags and a specification of
* the permitted algorithm(s).
* - Information about the key itself: the key type and its size.
- * - Implementations may define additional attributes.
+ * - Additional implementation-defined attributes.
*
* The actual key material is not considered an attribute of a key.
* Key attributes do not contain information that is generally considered
* highly confidential.
*
- * An attribute structure can be a simple data structure where each function
+ * An attribute structure works like a simple data structure where each function
* `psa_set_key_xxx` sets a field and the corresponding function
* `psa_get_key_xxx` retrieves the value of the corresponding field.
- * However, implementations may report values that are equivalent to the
- * original one, but have a different encoding. For example, an
- * implementation may use a more compact representation for types where
- * many bit-patterns are invalid or not supported, and store all values
- * that it does not support as a special marker value. In such an
- * implementation, after setting an invalid value, the corresponding
- * get function returns an invalid value which may not be the one that
- * was originally stored.
+ * However, a future version of the library may report values that are
+ * equivalent to the original one, but have a different encoding. Invalid
+ * values may be mapped to different, also invalid values.
*
* An attribute structure may contain references to auxiliary resources,
* for example pointers to allocated memory or indirect references to
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index f1b5c53..81a8575 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -363,7 +363,7 @@
* used for.
*
* HMAC keys should generally have the same size as the underlying hash.
- * This size can be calculated with #PSA_HASH_SIZE(\c alg) where
+ * This size can be calculated with #PSA_HASH_LENGTH(\c alg) where
* \c alg is the HMAC algorithm or the underlying hash algorithm. */
#define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x1100)
@@ -594,9 +594,9 @@
*
* \warning This macro may evaluate its argument multiple times.
*/
-#define PSA_BLOCK_CIPHER_BLOCK_SIZE(type) \
+#define PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) \
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \
- 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \
+ 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \
0u)
/** Vendor-defined algorithm flag.
@@ -1568,13 +1568,12 @@
*
* A persistent key remains in storage until it is explicitly destroyed or
* until the corresponding storage area is wiped. This specification does
- * not define any mechanism to wipe a storage area, but implementations may
+ * not define any mechanism to wipe a storage area, but integrations may
* provide their own mechanism (for example to perform a factory reset,
* to prepare for device refurbishment, or to uninstall an application).
*
* This lifetime value is the default storage area for the calling
- * application. Implementations may offer other storage areas designated
- * by other lifetime values as implementation-specific extensions.
+ * application. Integrations of Mbed TLS may support other persistent lifetimes.
* See ::psa_key_lifetime_t for more information.
*/
#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001)
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 8962555..b309b6e 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -193,15 +193,15 @@
if(USE_SHARED_MBEDTLS_LIBRARY)
add_library(${mbedcrypto_target} SHARED ${src_crypto})
- set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.24.0 SOVERSION 5)
+ set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.25.0 SOVERSION 6)
target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
add_library(${mbedx509_target} SHARED ${src_x509})
- set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.24.0 SOVERSION 1)
+ set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.25.0 SOVERSION 1)
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
add_library(${mbedtls_target} SHARED ${src_tls})
- set_target_properties(${mbedtls_target} PROPERTIES VERSION 2.24.0 SOVERSION 13)
+ set_target_properties(${mbedtls_target} PROPERTIES VERSION 2.25.0 SOVERSION 13)
target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
endif(USE_SHARED_MBEDTLS_LIBRARY)
diff --git a/library/Makefile b/library/Makefile
index a6db9b3..ae33bf2 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -41,7 +41,7 @@
SOEXT_TLS=so.13
SOEXT_X509=so.1
-SOEXT_CRYPTO=so.5
+SOEXT_CRYPTO=so.6
# Set AR_DASH= (empty string) to use an ar implementation that does not accept
# the - prefix for command line options (e.g. llvm-ar)
diff --git a/library/bignum.c b/library/bignum.c
index b11239e..9cc5d66 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -2118,6 +2118,10 @@
if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ if( mbedtls_mpi_bitlen( E ) > MBEDTLS_MPI_MAX_BITS ||
+ mbedtls_mpi_bitlen( N ) > MBEDTLS_MPI_MAX_BITS )
+ return ( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
/*
* Init temps and window size
*/
@@ -2394,7 +2398,7 @@
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
Xp = (unsigned char*) X->p;
- f_rng( p_rng, Xp + overhead, size );
+ MBEDTLS_MPI_CHK( f_rng( p_rng, Xp + overhead, size ) );
mpi_bigendian_to_host( X->p, limbs );
diff --git a/library/cipher.c b/library/cipher.c
index 853eeec..457f8f6 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1288,23 +1288,16 @@
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
/*
- * Packet-oriented encryption for AEAD modes
+ * Packet-oriented encryption for AEAD modes: internal function shared by
+ * mbedtls_cipher_auth_encrypt() and mbedtls_cipher_auth_encrypt_ext().
*/
-int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+static int mbedtls_cipher_aead_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len )
{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
-
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ctx->psa_enabled == 1 )
{
@@ -1320,7 +1313,7 @@
/* PSA Crypto API always writes the authentication tag
* at the end of the encrypted message. */
- if( tag != output + ilen )
+ if( output == NULL || tag != output + ilen )
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
status = psa_aead_encrypt( cipher_psa->slot,
@@ -1370,44 +1363,21 @@
ilen, iv, ad, ad_len, input, output, tag ) );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
-#if defined(MBEDTLS_NIST_KW_C)
- if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
- MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
- {
- mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
- MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
-
- /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
- if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
- {
- return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
-
- return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
- }
-#endif /* MBEDTLS_NIST_KW_C */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
/*
- * Packet-oriented decryption for AEAD modes
+ * Packet-oriented encryption for AEAD modes: internal function shared by
+ * mbedtls_cipher_auth_encrypt() and mbedtls_cipher_auth_encrypt_ext().
*/
-int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+static int mbedtls_cipher_aead_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len )
{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
-
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ctx->psa_enabled == 1 )
{
@@ -1423,7 +1393,7 @@
/* PSA Crypto API always writes the authentication tag
* at the end of the encrypted message. */
- if( tag != input + ilen )
+ if( input == NULL || tag != input + ilen )
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
status = psa_aead_decrypt( cipher_psa->slot,
@@ -1495,25 +1465,169 @@
return( ret );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
+
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+/*
+ * Packet-oriented encryption for AEAD modes: public legacy function.
+ */
+int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+ return( mbedtls_cipher_aead_encrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ tag, tag_len ) );
+}
+
+/*
+ * Packet-oriented decryption for AEAD modes: public legacy function.
+ */
+int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ const unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+ return( mbedtls_cipher_aead_decrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ tag, tag_len ) );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
+/*
+ * Packet-oriented encryption for AEAD/NIST_KW: public function.
+ */
+int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+
#if defined(MBEDTLS_NIST_KW_C)
- if( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
- MBEDTLS_MODE_KWP == ctx->cipher_info->mode )
+ if(
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ctx->psa_enabled == 0 &&
+#endif
+ ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) )
{
mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
- /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */
+ /* There is no iv, tag or ad associated with KW and KWP,
+ * so these length should be 0 as documented. */
if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
- {
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- }
- return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) );
+ (void) iv;
+ (void) ad;
+
+ return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen,
+ output, olen, output_len ) );
}
#endif /* MBEDTLS_NIST_KW_C */
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+ /* AEAD case: check length before passing on to shared function */
+ if( output_len < ilen + tag_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ int ret = mbedtls_cipher_aead_encrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ output + ilen, tag_len );
+ *olen += tag_len;
+ return( ret );
+#else
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
-}
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+}
+
+/*
+ * Packet-oriented decryption for AEAD/NIST_KW: public function.
+ */
+int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output_len == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+
+#if defined(MBEDTLS_NIST_KW_C)
+ if(
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ctx->psa_enabled == 0 &&
+#endif
+ ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) )
+ {
+ mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
+ MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
+
+ /* There is no iv, tag or ad associated with KW and KWP,
+ * so these length should be 0 as documented. */
+ if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ (void) iv;
+ (void) ad;
+
+ return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen,
+ output, olen, output_len ) );
+ }
+#endif /* MBEDTLS_NIST_KW_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+ /* AEAD case: check length before passing on to shared function */
+ if( ilen < tag_len || output_len < ilen - tag_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ return( mbedtls_cipher_aead_decrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen - tag_len, output, olen,
+ input + ilen - tag_len, tag_len ) );
+#else
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+}
+#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
#endif /* MBEDTLS_CIPHER_C */
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 023aac5..3815dc7 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -394,7 +394,7 @@
/* Gather entropy for a nonce if requested. */
if( nonce_len != 0 )
{
- if( 0 != ctx->f_entropy( ctx->p_entropy, seed, nonce_len ) )
+ if( 0 != ctx->f_entropy( ctx->p_entropy, seed + seedlen, nonce_len ) )
{
return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
}
@@ -684,54 +684,134 @@
#if defined(MBEDTLS_SELF_TEST)
-static const unsigned char entropy_source_pr[96] =
- { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
- 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
- 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
- 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
- 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
- 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
- 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
- 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
- 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
- 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
- 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
- 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
-
-static const unsigned char entropy_source_nopr[64] =
- { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
- 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
- 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
- 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
- 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
- 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
- 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
- 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
-
-static const unsigned char nonce_pers_pr[16] =
- { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
- 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
-
-static const unsigned char nonce_pers_nopr[16] =
- { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
- 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
+/* The CTR_DRBG NIST test vectors used here are available at
+ * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip
+ *
+ * The parameters used to derive the test data are:
+ *
+ * [AES-128 use df]
+ * [PredictionResistance = True/False]
+ * [EntropyInputLen = 128]
+ * [NonceLen = 64]
+ * [PersonalizationStringLen = 128]
+ * [AdditionalInputLen = 0]
+ * [ReturnedBitsLen = 512]
+ *
+ * [AES-256 use df]
+ * [PredictionResistance = True/False]
+ * [EntropyInputLen = 256]
+ * [NonceLen = 128]
+ * [PersonalizationStringLen = 256]
+ * [AdditionalInputLen = 0]
+ * [ReturnedBitsLen = 512]
+ *
+ */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
-static const unsigned char result_pr[16] =
- { 0x95, 0x3c, 0xa5, 0xbd, 0x44, 0x1, 0x34, 0xb7,
- 0x13, 0x58, 0x3e, 0x6a, 0x6c, 0x7e, 0x88, 0x8a };
+static const unsigned char entropy_source_pr[] =
+ { 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb,
+ 0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92,
+ 0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8,
+ 0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20,
+ 0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0,
+ 0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad,
+ 0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 };
-static const unsigned char result_nopr[16] =
- { 0x6c, 0x25, 0x27, 0x95, 0xa3, 0x62, 0xd6, 0xdb,
- 0x90, 0xfd, 0x69, 0xb5, 0x42, 0x9, 0x4b, 0x84 };
+static const unsigned char entropy_source_nopr[] =
+ { 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45,
+ 0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9,
+ 0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20,
+ 0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f,
+ 0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c };
+
+static const unsigned char pers_pr[] =
+ { 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
+ 0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };
+
+static const unsigned char pers_nopr[] =
+ { 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
+ 0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };
+
+static const unsigned char result_pr[] =
+ { 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66,
+ 0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff,
+ 0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10,
+ 0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30,
+ 0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4,
+ 0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc,
+ 0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06,
+ 0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf };
+
+static const unsigned char result_nopr[] =
+ { 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13,
+ 0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0,
+ 0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf,
+ 0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2,
+ 0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7,
+ 0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2,
+ 0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02,
+ 0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 };
#else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
-static const unsigned char result_pr[16] =
- { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
- 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
-static const unsigned char result_nopr[16] =
- { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
- 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
+static const unsigned char entropy_source_pr[] =
+ { 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49,
+ 0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a,
+ 0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85,
+ 0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e,
+ 0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15,
+ 0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45,
+ 0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8,
+ 0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c,
+ 0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3,
+ 0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce,
+ 0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e,
+ 0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76,
+ 0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77,
+ 0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe };
+
+static const unsigned char entropy_source_nopr[] =
+ { 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d,
+ 0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0,
+ 0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73,
+ 0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c,
+ 0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2,
+ 0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1,
+ 0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a,
+ 0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb,
+ 0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a,
+ 0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 };
+
+static const unsigned char pers_pr[] =
+ { 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33,
+ 0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e,
+ 0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0,
+ 0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 };
+
+static const unsigned char pers_nopr[] =
+ { 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29,
+ 0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf,
+ 0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb,
+ 0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b };
+
+static const unsigned char result_pr[] =
+ { 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85,
+ 0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d,
+ 0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62,
+ 0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d,
+ 0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb,
+ 0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39,
+ 0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40,
+ 0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 };
+
+static const unsigned char result_nopr[] =
+ { 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad,
+ 0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3,
+ 0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b,
+ 0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14,
+ 0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54,
+ 0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30,
+ 0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a,
+ 0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 };
#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
static size_t test_offset;
@@ -751,13 +831,15 @@
return( 1 ); \
}
+#define SELF_TEST_OUPUT_DISCARD_LENGTH 64
+
/*
* Checkup routine
*/
int mbedtls_ctr_drbg_self_test( int verbose )
{
mbedtls_ctr_drbg_context ctx;
- unsigned char buf[16];
+ unsigned char buf[ sizeof( result_pr ) ];
mbedtls_ctr_drbg_init( &ctx );
@@ -768,16 +850,16 @@
mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
test_offset = 0;
- mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
- mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE );
+ mbedtls_ctr_drbg_set_nonce_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2 );
CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_pr,
- nonce_pers_pr, 16 ) );
+ pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) );
+ CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) );
mbedtls_ctr_drbg_free( &ctx );
@@ -793,16 +875,16 @@
mbedtls_ctr_drbg_init( &ctx );
test_offset = 0;
- mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
- mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
+ mbedtls_ctr_drbg_set_nonce_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2 );
CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_nopr,
- nonce_pers_nopr, 16 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
+ pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
- CHK( memcmp( buf, result_nopr, 16 ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) );
+ CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) );
mbedtls_ctr_drbg_free( &ctx );
diff --git a/library/ecjpake.c b/library/ecjpake.c
index 315da4a..bd47169 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -820,6 +820,8 @@
0x65, 0x73, 0x74
};
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+
static const unsigned char ecjpake_test_x1[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
@@ -964,6 +966,8 @@
return( ret );
}
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
+
/* For tests we don't need a secure RNG;
* use the LGC from Numerical Recipes for simplicity */
static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
@@ -1059,6 +1063,12 @@
if( verbose != 0 )
mbedtls_printf( "passed\n" );
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+ /* 'reference handshake' tests can only be run against implementations
+ * for which we have 100% control over how the random ephemeral keys
+ * are generated. This is only the case for the internal mbed TLS
+ * implementation, so these tests are skipped in case the internal
+ * implementation is swapped out for an alternative one. */
if( verbose != 0 )
mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
@@ -1107,6 +1117,7 @@
if( verbose != 0 )
mbedtls_printf( "passed\n" );
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
cleanup:
mbedtls_ecjpake_free( &cli );
diff --git a/library/md2.c b/library/md2.c
index b4f7cc6..7264e30 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -147,6 +147,9 @@
t = ctx->cksum[i];
}
+ /* Zeroise variables to clear sensitive data from memory. */
+ mbedtls_platform_zeroize( &t, sizeof( t ) );
+
return( 0 );
}
diff --git a/library/md4.c b/library/md4.c
index 1cac0a4..4fd6bc3 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -113,31 +113,34 @@
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] )
{
- uint32_t X[16], A, B, C, D;
+ struct
+ {
+ uint32_t X[16], A, B, C, D;
+ } local;
- GET_UINT32_LE( X[ 0], data, 0 );
- GET_UINT32_LE( X[ 1], data, 4 );
- GET_UINT32_LE( X[ 2], data, 8 );
- GET_UINT32_LE( X[ 3], data, 12 );
- GET_UINT32_LE( X[ 4], data, 16 );
- GET_UINT32_LE( X[ 5], data, 20 );
- GET_UINT32_LE( X[ 6], data, 24 );
- GET_UINT32_LE( X[ 7], data, 28 );
- GET_UINT32_LE( X[ 8], data, 32 );
- GET_UINT32_LE( X[ 9], data, 36 );
- GET_UINT32_LE( X[10], data, 40 );
- GET_UINT32_LE( X[11], data, 44 );
- GET_UINT32_LE( X[12], data, 48 );
- GET_UINT32_LE( X[13], data, 52 );
- GET_UINT32_LE( X[14], data, 56 );
- GET_UINT32_LE( X[15], data, 60 );
+ GET_UINT32_LE( local.X[ 0], data, 0 );
+ GET_UINT32_LE( local.X[ 1], data, 4 );
+ GET_UINT32_LE( local.X[ 2], data, 8 );
+ GET_UINT32_LE( local.X[ 3], data, 12 );
+ GET_UINT32_LE( local.X[ 4], data, 16 );
+ GET_UINT32_LE( local.X[ 5], data, 20 );
+ GET_UINT32_LE( local.X[ 6], data, 24 );
+ GET_UINT32_LE( local.X[ 7], data, 28 );
+ GET_UINT32_LE( local.X[ 8], data, 32 );
+ GET_UINT32_LE( local.X[ 9], data, 36 );
+ GET_UINT32_LE( local.X[10], data, 40 );
+ GET_UINT32_LE( local.X[11], data, 44 );
+ GET_UINT32_LE( local.X[12], data, 48 );
+ GET_UINT32_LE( local.X[13], data, 52 );
+ GET_UINT32_LE( local.X[14], data, 56 );
+ GET_UINT32_LE( local.X[15], data, 60 );
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
+ local.A = ctx->state[0];
+ local.B = ctx->state[1];
+ local.C = ctx->state[2];
+ local.D = ctx->state[3];
#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
#define P(a,b,c,d,x,s) \
@@ -148,22 +151,22 @@
} while( 0 )
- P( A, B, C, D, X[ 0], 3 );
- P( D, A, B, C, X[ 1], 7 );
- P( C, D, A, B, X[ 2], 11 );
- P( B, C, D, A, X[ 3], 19 );
- P( A, B, C, D, X[ 4], 3 );
- P( D, A, B, C, X[ 5], 7 );
- P( C, D, A, B, X[ 6], 11 );
- P( B, C, D, A, X[ 7], 19 );
- P( A, B, C, D, X[ 8], 3 );
- P( D, A, B, C, X[ 9], 7 );
- P( C, D, A, B, X[10], 11 );
- P( B, C, D, A, X[11], 19 );
- P( A, B, C, D, X[12], 3 );
- P( D, A, B, C, X[13], 7 );
- P( C, D, A, B, X[14], 11 );
- P( B, C, D, A, X[15], 19 );
+ P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 1], 7 );
+ P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
+ P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
+ P( local.A, local.B, local.C, local.D, local.X[ 4], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 5], 7 );
+ P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
+ P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
+ P( local.A, local.B, local.C, local.D, local.X[ 8], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 9], 7 );
+ P( local.C, local.D, local.A, local.B, local.X[10], 11 );
+ P( local.B, local.C, local.D, local.A, local.X[11], 19 );
+ P( local.A, local.B, local.C, local.D, local.X[12], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[13], 7 );
+ P( local.C, local.D, local.A, local.B, local.X[14], 11 );
+ P( local.B, local.C, local.D, local.A, local.X[15], 19 );
#undef P
#undef F
@@ -176,22 +179,22 @@
(a) = S((a),(s)); \
} while( 0 )
- P( A, B, C, D, X[ 0], 3 );
- P( D, A, B, C, X[ 4], 5 );
- P( C, D, A, B, X[ 8], 9 );
- P( B, C, D, A, X[12], 13 );
- P( A, B, C, D, X[ 1], 3 );
- P( D, A, B, C, X[ 5], 5 );
- P( C, D, A, B, X[ 9], 9 );
- P( B, C, D, A, X[13], 13 );
- P( A, B, C, D, X[ 2], 3 );
- P( D, A, B, C, X[ 6], 5 );
- P( C, D, A, B, X[10], 9 );
- P( B, C, D, A, X[14], 13 );
- P( A, B, C, D, X[ 3], 3 );
- P( D, A, B, C, X[ 7], 5 );
- P( C, D, A, B, X[11], 9 );
- P( B, C, D, A, X[15], 13 );
+ P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 4], 5 );
+ P( local.C, local.D, local.A, local.B, local.X[ 8], 9 );
+ P( local.B, local.C, local.D, local.A, local.X[12], 13 );
+ P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 5], 5 );
+ P( local.C, local.D, local.A, local.B, local.X[ 9], 9 );
+ P( local.B, local.C, local.D, local.A, local.X[13], 13 );
+ P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 6], 5 );
+ P( local.C, local.D, local.A, local.B, local.X[10], 9 );
+ P( local.B, local.C, local.D, local.A, local.X[14], 13 );
+ P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 7], 5 );
+ P( local.C, local.D, local.A, local.B, local.X[11], 9 );
+ P( local.B, local.C, local.D, local.A, local.X[15], 13 );
#undef P
#undef F
@@ -204,30 +207,33 @@
(a) = S((a),(s)); \
} while( 0 )
- P( A, B, C, D, X[ 0], 3 );
- P( D, A, B, C, X[ 8], 9 );
- P( C, D, A, B, X[ 4], 11 );
- P( B, C, D, A, X[12], 15 );
- P( A, B, C, D, X[ 2], 3 );
- P( D, A, B, C, X[10], 9 );
- P( C, D, A, B, X[ 6], 11 );
- P( B, C, D, A, X[14], 15 );
- P( A, B, C, D, X[ 1], 3 );
- P( D, A, B, C, X[ 9], 9 );
- P( C, D, A, B, X[ 5], 11 );
- P( B, C, D, A, X[13], 15 );
- P( A, B, C, D, X[ 3], 3 );
- P( D, A, B, C, X[11], 9 );
- P( C, D, A, B, X[ 7], 11 );
- P( B, C, D, A, X[15], 15 );
+ P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 8], 9 );
+ P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
+ P( local.B, local.C, local.D, local.A, local.X[12], 15 );
+ P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[10], 9 );
+ P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
+ P( local.B, local.C, local.D, local.A, local.X[14], 15 );
+ P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[ 9], 9 );
+ P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
+ P( local.B, local.C, local.D, local.A, local.X[13], 15 );
+ P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
+ P( local.D, local.A, local.B, local.C, local.X[11], 9 );
+ P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
+ P( local.B, local.C, local.D, local.A, local.X[15], 15 );
#undef F
#undef P
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
+ ctx->state[0] += local.A;
+ ctx->state[1] += local.B;
+ ctx->state[2] += local.C;
+ ctx->state[3] += local.D;
+
+ /* Zeroise variables to clear sensitive data from memory. */
+ mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
diff --git a/library/md5.c b/library/md5.c
index 1e702b4..c4f2dbf 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -112,128 +112,134 @@
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] )
{
- uint32_t X[16], A, B, C, D;
+ struct
+ {
+ uint32_t X[16], A, B, C, D;
+ } local;
- GET_UINT32_LE( X[ 0], data, 0 );
- GET_UINT32_LE( X[ 1], data, 4 );
- GET_UINT32_LE( X[ 2], data, 8 );
- GET_UINT32_LE( X[ 3], data, 12 );
- GET_UINT32_LE( X[ 4], data, 16 );
- GET_UINT32_LE( X[ 5], data, 20 );
- GET_UINT32_LE( X[ 6], data, 24 );
- GET_UINT32_LE( X[ 7], data, 28 );
- GET_UINT32_LE( X[ 8], data, 32 );
- GET_UINT32_LE( X[ 9], data, 36 );
- GET_UINT32_LE( X[10], data, 40 );
- GET_UINT32_LE( X[11], data, 44 );
- GET_UINT32_LE( X[12], data, 48 );
- GET_UINT32_LE( X[13], data, 52 );
- GET_UINT32_LE( X[14], data, 56 );
- GET_UINT32_LE( X[15], data, 60 );
+ GET_UINT32_LE( local.X[ 0], data, 0 );
+ GET_UINT32_LE( local.X[ 1], data, 4 );
+ GET_UINT32_LE( local.X[ 2], data, 8 );
+ GET_UINT32_LE( local.X[ 3], data, 12 );
+ GET_UINT32_LE( local.X[ 4], data, 16 );
+ GET_UINT32_LE( local.X[ 5], data, 20 );
+ GET_UINT32_LE( local.X[ 6], data, 24 );
+ GET_UINT32_LE( local.X[ 7], data, 28 );
+ GET_UINT32_LE( local.X[ 8], data, 32 );
+ GET_UINT32_LE( local.X[ 9], data, 36 );
+ GET_UINT32_LE( local.X[10], data, 40 );
+ GET_UINT32_LE( local.X[11], data, 44 );
+ GET_UINT32_LE( local.X[12], data, 48 );
+ GET_UINT32_LE( local.X[13], data, 52 );
+ GET_UINT32_LE( local.X[14], data, 56 );
+ GET_UINT32_LE( local.X[15], data, 60 );
#define S(x,n) \
( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) )
-#define P(a,b,c,d,k,s,t) \
- do \
- { \
- (a) += F((b),(c),(d)) + X[(k)] + (t); \
- (a) = S((a),(s)) + (b); \
+#define P(a,b,c,d,k,s,t) \
+ do \
+ { \
+ (a) += F((b),(c),(d)) + local.X[(k)] + (t); \
+ (a) = S((a),(s)) + (b); \
} while( 0 )
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
+ local.A = ctx->state[0];
+ local.B = ctx->state[1];
+ local.C = ctx->state[2];
+ local.D = ctx->state[3];
#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
- P( A, B, C, D, 0, 7, 0xD76AA478 );
- P( D, A, B, C, 1, 12, 0xE8C7B756 );
- P( C, D, A, B, 2, 17, 0x242070DB );
- P( B, C, D, A, 3, 22, 0xC1BDCEEE );
- P( A, B, C, D, 4, 7, 0xF57C0FAF );
- P( D, A, B, C, 5, 12, 0x4787C62A );
- P( C, D, A, B, 6, 17, 0xA8304613 );
- P( B, C, D, A, 7, 22, 0xFD469501 );
- P( A, B, C, D, 8, 7, 0x698098D8 );
- P( D, A, B, C, 9, 12, 0x8B44F7AF );
- P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
- P( B, C, D, A, 11, 22, 0x895CD7BE );
- P( A, B, C, D, 12, 7, 0x6B901122 );
- P( D, A, B, C, 13, 12, 0xFD987193 );
- P( C, D, A, B, 14, 17, 0xA679438E );
- P( B, C, D, A, 15, 22, 0x49B40821 );
+ P( local.A, local.B, local.C, local.D, 0, 7, 0xD76AA478 );
+ P( local.D, local.A, local.B, local.C, 1, 12, 0xE8C7B756 );
+ P( local.C, local.D, local.A, local.B, 2, 17, 0x242070DB );
+ P( local.B, local.C, local.D, local.A, 3, 22, 0xC1BDCEEE );
+ P( local.A, local.B, local.C, local.D, 4, 7, 0xF57C0FAF );
+ P( local.D, local.A, local.B, local.C, 5, 12, 0x4787C62A );
+ P( local.C, local.D, local.A, local.B, 6, 17, 0xA8304613 );
+ P( local.B, local.C, local.D, local.A, 7, 22, 0xFD469501 );
+ P( local.A, local.B, local.C, local.D, 8, 7, 0x698098D8 );
+ P( local.D, local.A, local.B, local.C, 9, 12, 0x8B44F7AF );
+ P( local.C, local.D, local.A, local.B, 10, 17, 0xFFFF5BB1 );
+ P( local.B, local.C, local.D, local.A, 11, 22, 0x895CD7BE );
+ P( local.A, local.B, local.C, local.D, 12, 7, 0x6B901122 );
+ P( local.D, local.A, local.B, local.C, 13, 12, 0xFD987193 );
+ P( local.C, local.D, local.A, local.B, 14, 17, 0xA679438E );
+ P( local.B, local.C, local.D, local.A, 15, 22, 0x49B40821 );
#undef F
#define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y))))
- P( A, B, C, D, 1, 5, 0xF61E2562 );
- P( D, A, B, C, 6, 9, 0xC040B340 );
- P( C, D, A, B, 11, 14, 0x265E5A51 );
- P( B, C, D, A, 0, 20, 0xE9B6C7AA );
- P( A, B, C, D, 5, 5, 0xD62F105D );
- P( D, A, B, C, 10, 9, 0x02441453 );
- P( C, D, A, B, 15, 14, 0xD8A1E681 );
- P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
- P( A, B, C, D, 9, 5, 0x21E1CDE6 );
- P( D, A, B, C, 14, 9, 0xC33707D6 );
- P( C, D, A, B, 3, 14, 0xF4D50D87 );
- P( B, C, D, A, 8, 20, 0x455A14ED );
- P( A, B, C, D, 13, 5, 0xA9E3E905 );
- P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
- P( C, D, A, B, 7, 14, 0x676F02D9 );
- P( B, C, D, A, 12, 20, 0x8D2A4C8A );
+ P( local.A, local.B, local.C, local.D, 1, 5, 0xF61E2562 );
+ P( local.D, local.A, local.B, local.C, 6, 9, 0xC040B340 );
+ P( local.C, local.D, local.A, local.B, 11, 14, 0x265E5A51 );
+ P( local.B, local.C, local.D, local.A, 0, 20, 0xE9B6C7AA );
+ P( local.A, local.B, local.C, local.D, 5, 5, 0xD62F105D );
+ P( local.D, local.A, local.B, local.C, 10, 9, 0x02441453 );
+ P( local.C, local.D, local.A, local.B, 15, 14, 0xD8A1E681 );
+ P( local.B, local.C, local.D, local.A, 4, 20, 0xE7D3FBC8 );
+ P( local.A, local.B, local.C, local.D, 9, 5, 0x21E1CDE6 );
+ P( local.D, local.A, local.B, local.C, 14, 9, 0xC33707D6 );
+ P( local.C, local.D, local.A, local.B, 3, 14, 0xF4D50D87 );
+ P( local.B, local.C, local.D, local.A, 8, 20, 0x455A14ED );
+ P( local.A, local.B, local.C, local.D, 13, 5, 0xA9E3E905 );
+ P( local.D, local.A, local.B, local.C, 2, 9, 0xFCEFA3F8 );
+ P( local.C, local.D, local.A, local.B, 7, 14, 0x676F02D9 );
+ P( local.B, local.C, local.D, local.A, 12, 20, 0x8D2A4C8A );
#undef F
#define F(x,y,z) ((x) ^ (y) ^ (z))
- P( A, B, C, D, 5, 4, 0xFFFA3942 );
- P( D, A, B, C, 8, 11, 0x8771F681 );
- P( C, D, A, B, 11, 16, 0x6D9D6122 );
- P( B, C, D, A, 14, 23, 0xFDE5380C );
- P( A, B, C, D, 1, 4, 0xA4BEEA44 );
- P( D, A, B, C, 4, 11, 0x4BDECFA9 );
- P( C, D, A, B, 7, 16, 0xF6BB4B60 );
- P( B, C, D, A, 10, 23, 0xBEBFBC70 );
- P( A, B, C, D, 13, 4, 0x289B7EC6 );
- P( D, A, B, C, 0, 11, 0xEAA127FA );
- P( C, D, A, B, 3, 16, 0xD4EF3085 );
- P( B, C, D, A, 6, 23, 0x04881D05 );
- P( A, B, C, D, 9, 4, 0xD9D4D039 );
- P( D, A, B, C, 12, 11, 0xE6DB99E5 );
- P( C, D, A, B, 15, 16, 0x1FA27CF8 );
- P( B, C, D, A, 2, 23, 0xC4AC5665 );
+ P( local.A, local.B, local.C, local.D, 5, 4, 0xFFFA3942 );
+ P( local.D, local.A, local.B, local.C, 8, 11, 0x8771F681 );
+ P( local.C, local.D, local.A, local.B, 11, 16, 0x6D9D6122 );
+ P( local.B, local.C, local.D, local.A, 14, 23, 0xFDE5380C );
+ P( local.A, local.B, local.C, local.D, 1, 4, 0xA4BEEA44 );
+ P( local.D, local.A, local.B, local.C, 4, 11, 0x4BDECFA9 );
+ P( local.C, local.D, local.A, local.B, 7, 16, 0xF6BB4B60 );
+ P( local.B, local.C, local.D, local.A, 10, 23, 0xBEBFBC70 );
+ P( local.A, local.B, local.C, local.D, 13, 4, 0x289B7EC6 );
+ P( local.D, local.A, local.B, local.C, 0, 11, 0xEAA127FA );
+ P( local.C, local.D, local.A, local.B, 3, 16, 0xD4EF3085 );
+ P( local.B, local.C, local.D, local.A, 6, 23, 0x04881D05 );
+ P( local.A, local.B, local.C, local.D, 9, 4, 0xD9D4D039 );
+ P( local.D, local.A, local.B, local.C, 12, 11, 0xE6DB99E5 );
+ P( local.C, local.D, local.A, local.B, 15, 16, 0x1FA27CF8 );
+ P( local.B, local.C, local.D, local.A, 2, 23, 0xC4AC5665 );
#undef F
#define F(x,y,z) ((y) ^ ((x) | ~(z)))
- P( A, B, C, D, 0, 6, 0xF4292244 );
- P( D, A, B, C, 7, 10, 0x432AFF97 );
- P( C, D, A, B, 14, 15, 0xAB9423A7 );
- P( B, C, D, A, 5, 21, 0xFC93A039 );
- P( A, B, C, D, 12, 6, 0x655B59C3 );
- P( D, A, B, C, 3, 10, 0x8F0CCC92 );
- P( C, D, A, B, 10, 15, 0xFFEFF47D );
- P( B, C, D, A, 1, 21, 0x85845DD1 );
- P( A, B, C, D, 8, 6, 0x6FA87E4F );
- P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
- P( C, D, A, B, 6, 15, 0xA3014314 );
- P( B, C, D, A, 13, 21, 0x4E0811A1 );
- P( A, B, C, D, 4, 6, 0xF7537E82 );
- P( D, A, B, C, 11, 10, 0xBD3AF235 );
- P( C, D, A, B, 2, 15, 0x2AD7D2BB );
- P( B, C, D, A, 9, 21, 0xEB86D391 );
+ P( local.A, local.B, local.C, local.D, 0, 6, 0xF4292244 );
+ P( local.D, local.A, local.B, local.C, 7, 10, 0x432AFF97 );
+ P( local.C, local.D, local.A, local.B, 14, 15, 0xAB9423A7 );
+ P( local.B, local.C, local.D, local.A, 5, 21, 0xFC93A039 );
+ P( local.A, local.B, local.C, local.D, 12, 6, 0x655B59C3 );
+ P( local.D, local.A, local.B, local.C, 3, 10, 0x8F0CCC92 );
+ P( local.C, local.D, local.A, local.B, 10, 15, 0xFFEFF47D );
+ P( local.B, local.C, local.D, local.A, 1, 21, 0x85845DD1 );
+ P( local.A, local.B, local.C, local.D, 8, 6, 0x6FA87E4F );
+ P( local.D, local.A, local.B, local.C, 15, 10, 0xFE2CE6E0 );
+ P( local.C, local.D, local.A, local.B, 6, 15, 0xA3014314 );
+ P( local.B, local.C, local.D, local.A, 13, 21, 0x4E0811A1 );
+ P( local.A, local.B, local.C, local.D, 4, 6, 0xF7537E82 );
+ P( local.D, local.A, local.B, local.C, 11, 10, 0xBD3AF235 );
+ P( local.C, local.D, local.A, local.B, 2, 15, 0x2AD7D2BB );
+ P( local.B, local.C, local.D, local.A, 9, 21, 0xEB86D391 );
#undef F
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
+ ctx->state[0] += local.A;
+ ctx->state[1] += local.B;
+ ctx->state[2] += local.C;
+ ctx->state[3] += local.D;
+
+ /* Zeroise variables to clear sensitive data from memory. */
+ mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
diff --git a/library/pkcs5.c b/library/pkcs5.c
index f89cc64..e9e743f 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -221,7 +221,8 @@
unsigned int iteration_count,
uint32_t key_length, unsigned char *output )
{
- int ret, j;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ int j;
unsigned int i;
unsigned char md1[MBEDTLS_MD_MAX_SIZE];
unsigned char work[MBEDTLS_MD_MAX_SIZE];
@@ -245,16 +246,16 @@
// U1 ends up in work
//
if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
- return( ret );
+ goto cleanup;
if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 )
- return( ret );
+ goto cleanup;
if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
- return( ret );
+ goto cleanup;
if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 )
- return( ret );
+ goto cleanup;
memcpy( md1, work, md_size );
@@ -263,13 +264,13 @@
// U2 ends up in md1
//
if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
- return( ret );
+ goto cleanup;
if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
- return( ret );
+ goto cleanup;
if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 )
- return( ret );
+ goto cleanup;
// U1 xor U2
//
@@ -288,7 +289,12 @@
break;
}
- return( 0 );
+cleanup:
+ /* Zeroise buffers to clear sensitive data from memory. */
+ mbedtls_platform_zeroize( work, MBEDTLS_MD_MAX_SIZE );
+ mbedtls_platform_zeroize( md1, MBEDTLS_MD_MAX_SIZE );
+
+ return( ret );
}
#if defined(MBEDTLS_SELF_TEST)
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 82b95dc..acb4f8e 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -40,6 +40,8 @@
* stored keys. */
#include "psa_crypto_storage.h"
+#include "psa_crypto_random_impl.h"
+
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -49,6 +51,7 @@
#define mbedtls_free free
#endif
+#include "mbedtls/aes.h"
#include "mbedtls/arc4.h"
#include "mbedtls/asn1.h"
#include "mbedtls/asn1write.h"
@@ -60,7 +63,6 @@
#include "mbedtls/cipher.h"
#include "mbedtls/ccm.h"
#include "mbedtls/cmac.h"
-#include "mbedtls/ctr_drbg.h"
#include "mbedtls/des.h"
#include "mbedtls/ecdh.h"
#include "mbedtls/ecp.h"
@@ -115,25 +117,29 @@
typedef struct
{
- void (* entropy_init )( mbedtls_entropy_context *ctx );
- void (* entropy_free )( mbedtls_entropy_context *ctx );
- mbedtls_entropy_context entropy;
- mbedtls_ctr_drbg_context ctr_drbg;
+ mbedtls_psa_random_context_t rng;
unsigned initialized : 1;
unsigned rng_state : 2;
} psa_global_data_t;
static psa_global_data_t global_data;
+#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
+ &global_data.rng.drbg;
+#endif
+
#define GUARD_MODULE_INITIALIZED \
if( global_data.initialized == 0 ) \
return( PSA_ERROR_BAD_STATE );
psa_status_t mbedtls_to_psa_error( int ret )
{
- /* If there's both a high-level code and low-level code, dispatch on
- * the high-level code. */
- switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
+ /* Mbed TLS error codes can combine a high-level error code and a
+ * low-level error code. The low-level error usually reflects the
+ * root cause better, so dispatch on that preferably. */
+ int low_level_ret = - ( -ret & 0x007f );
+ switch( low_level_ret != 0 ? low_level_ret : ret )
{
case 0:
return( PSA_SUCCESS );
@@ -214,6 +220,10 @@
case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
return( PSA_ERROR_HARDWARE_FAILURE );
+#if !( defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \
+ defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE) )
+ /* Only check CTR_DRBG error codes if underlying mbedtls_xxx
+ * functions are passed a CTR_DRBG instance. */
case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
return( PSA_ERROR_INSUFFICIENT_ENTROPY );
case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
@@ -221,6 +231,7 @@
return( PSA_ERROR_NOT_SUPPORTED );
case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
return( PSA_ERROR_INSUFFICIENT_ENTROPY );
+#endif
case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
return( PSA_ERROR_NOT_SUPPORTED );
@@ -239,6 +250,19 @@
case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
return( PSA_ERROR_HARDWARE_FAILURE );
+#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \
+ defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
+ /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx
+ * functions are passed a HMAC_DRBG instance. */
+ case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED:
+ return( PSA_ERROR_INSUFFICIENT_ENTROPY );
+ case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG:
+ case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG:
+ return( PSA_ERROR_NOT_SUPPORTED );
+ case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR:
+ return( PSA_ERROR_INSUFFICIENT_ENTROPY );
+#endif
+
case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
@@ -322,7 +346,7 @@
case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
return( PSA_ERROR_BUFFER_TOO_SMALL );
case MBEDTLS_ERR_RSA_RNG_FAILED:
- return( PSA_ERROR_INSUFFICIENT_MEMORY );
+ return( PSA_ERROR_INSUFFICIENT_ENTROPY );
case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
return( PSA_ERROR_NOT_SUPPORTED );
case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
@@ -350,8 +374,11 @@
return( PSA_ERROR_INVALID_SIGNATURE );
case MBEDTLS_ERR_ECP_ALLOC_FAILED:
return( PSA_ERROR_INSUFFICIENT_MEMORY );
+ case MBEDTLS_ERR_ECP_RANDOM_FAILED:
+ return( PSA_ERROR_INSUFFICIENT_ENTROPY );
case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
return( PSA_ERROR_HARDWARE_FAILURE );
+
case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
return( PSA_ERROR_CORRUPTION_DETECTED );
@@ -867,7 +894,7 @@
/* Calculate the public key */
status = mbedtls_to_psa_error(
mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
- mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
+ mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
if( status != PSA_SUCCESS )
return( status );
}
@@ -1316,7 +1343,8 @@
static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
{
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
- if( psa_key_slot_is_external( slot ) )
+ if( psa_get_se_driver( slot->attr.lifetime, NULL, NULL ) &&
+ psa_key_slot_is_external( slot ) )
{
/* No key material to clean. */
}
@@ -2736,7 +2764,7 @@
{
psa_status_t status;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
+ size_t actual_hash_length = PSA_HASH_LENGTH( operation->alg );
/* Fill the output buffer with something that isn't a valid hash
* (barring an attack on the hash and deliberately-crafted input),
@@ -3213,7 +3241,7 @@
{
uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
size_t i;
- size_t hash_size = PSA_HASH_SIZE( hash_alg );
+ size_t hash_size = PSA_HASH_LENGTH( hash_alg );
size_t block_size = psa_get_hash_block_size( hash_alg );
psa_status_t status;
@@ -3329,7 +3357,7 @@
goto exit;
}
- operation->mac_size = PSA_HASH_SIZE( hash_alg );
+ operation->mac_size = PSA_HASH_LENGTH( hash_alg );
/* Sanity check. This shouldn't fail on a valid configuration. */
if( operation->mac_size == 0 ||
operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
@@ -3499,7 +3527,7 @@
#if defined(MBEDTLS_CMAC_C)
if( operation->alg == PSA_ALG_CMAC )
{
- uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
+ uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE];
int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
if( ret == 0 )
memcpy( mac, tmp, operation->mac_size );
@@ -3681,8 +3709,8 @@
mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
MBEDTLS_MD_NONE );
ret = mbedtls_rsa_pkcs1_sign( rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
MBEDTLS_RSA_PRIVATE,
md_alg,
(unsigned int) hash_length,
@@ -3696,8 +3724,8 @@
{
mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
ret = mbedtls_rsa_rsassa_pss_sign( rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
MBEDTLS_RSA_PRIVATE,
MBEDTLS_MD_NONE,
(unsigned int) hash_length,
@@ -3739,8 +3767,8 @@
mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
MBEDTLS_MD_NONE );
ret = mbedtls_rsa_pkcs1_verify( rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
MBEDTLS_RSA_PUBLIC,
md_alg,
(unsigned int) hash_length,
@@ -3754,8 +3782,8 @@
{
mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
ret = mbedtls_rsa_rsassa_pss_verify( rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
MBEDTLS_RSA_PUBLIC,
MBEDTLS_MD_NONE,
(unsigned int) hash_length,
@@ -3812,8 +3840,8 @@
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det_ext( &ecp->grp, &r, &s,
&ecp->d, hash,
hash_length, md_alg,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg ) );
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE ) );
}
else
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
@@ -3821,8 +3849,8 @@
(void) alg;
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
hash, hash_length,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg ) );
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE ) );
}
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
@@ -3867,7 +3895,7 @@
{
MBEDTLS_MPI_CHK(
mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
- mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
+ mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
}
ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
@@ -4167,8 +4195,8 @@
{
status = mbedtls_to_psa_error(
mbedtls_rsa_pkcs1_encrypt( rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
MBEDTLS_RSA_PUBLIC,
input_length,
input,
@@ -4182,8 +4210,8 @@
psa_rsa_oaep_set_padding_mode( alg, rsa );
status = mbedtls_to_psa_error(
mbedtls_rsa_rsaes_oaep_encrypt( rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
MBEDTLS_RSA_PUBLIC,
salt, salt_length,
input_length,
@@ -4274,8 +4302,8 @@
{
status = mbedtls_to_psa_error(
mbedtls_rsa_pkcs1_decrypt( rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
MBEDTLS_RSA_PRIVATE,
output_length,
input,
@@ -4290,8 +4318,8 @@
psa_rsa_oaep_set_padding_mode( alg, rsa );
status = mbedtls_to_psa_error(
mbedtls_rsa_rsaes_oaep_decrypt( rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
MBEDTLS_RSA_PRIVATE,
salt, salt_length,
output_length,
@@ -4455,11 +4483,11 @@
#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
- PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type ) );
if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
alg != PSA_ALG_ECB_NO_PADDING )
{
- operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type );
+ operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type );
}
#if defined(MBEDTLS_CHACHA20_C)
else
@@ -4525,8 +4553,8 @@
status = PSA_ERROR_BUFFER_TOO_SMALL;
goto exit;
}
- ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
- iv, operation->iv_size );
+ ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
+ iv, operation->iv_size );
if( ret != 0 )
{
status = mbedtls_to_psa_error( ret );
@@ -4919,7 +4947,7 @@
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
* The call to mbedtls_ccm_encrypt_and_tag or
* mbedtls_ccm_auth_decrypt will validate the tag length. */
- if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
+ if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 )
{
status = PSA_ERROR_INVALID_ARGUMENT;
goto cleanup;
@@ -4941,7 +4969,7 @@
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
* The call to mbedtls_gcm_crypt_and_tag or
* mbedtls_gcm_auth_decrypt will validate the tag length. */
- if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 )
+ if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 )
{
status = PSA_ERROR_INVALID_ARGUMENT;
goto cleanup;
@@ -5310,7 +5338,7 @@
uint8_t *output,
size_t output_length )
{
- uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
+ uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
psa_status_t status;
if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set )
@@ -5380,7 +5408,7 @@
psa_algorithm_t alg )
{
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
- uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
+ uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
psa_hash_operation_t backup = PSA_HASH_OPERATION_INIT;
psa_status_t status, cleanup_status;
@@ -5490,7 +5518,7 @@
size_t output_length )
{
psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
- uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
+ uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
psa_status_t status;
uint8_t offset, length;
@@ -5720,7 +5748,7 @@
if( is_kdf_alg_supported )
{
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
- size_t hash_size = PSA_HASH_SIZE( hash_alg );
+ size_t hash_size = PSA_HASH_LENGTH( hash_alg );
if( hash_size == 0 )
return( PSA_ERROR_NOT_SUPPORTED );
if( ( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
@@ -5808,7 +5836,7 @@
sizeof( hkdf->prk ) );
if( status != PSA_SUCCESS )
return( status );
- hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
+ hkdf->offset_in_block = PSA_HASH_LENGTH( hash_alg );
hkdf->block_number = 0;
hkdf->state = HKDF_STATE_KEYED;
return( PSA_SUCCESS );
@@ -5926,10 +5954,10 @@
size_t data_length )
{
psa_status_t status;
- uint8_t pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
+ uint8_t pms[ 4 + 2 * PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE ];
uint8_t *cur = pms;
- if( data_length > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
+ if( data_length > PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE )
return( PSA_ERROR_INVALID_ARGUMENT );
/* Quoting RFC 4279, Section 2:
@@ -6141,8 +6169,8 @@
mbedtls_ecdh_calc_secret( &ecdh,
shared_secret_length,
shared_secret, shared_secret_size,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg ) );
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE ) );
if( status != PSA_SUCCESS )
goto exit;
if( PSA_BITS_TO_BYTES( bits ) != *shared_secret_length )
@@ -6320,31 +6348,139 @@
}
+
/****************************************************************/
/* Random generation */
/****************************************************************/
+/** Initialize the PSA random generator.
+ */
+static void mbedtls_psa_random_init( mbedtls_psa_random_context_t *rng )
+{
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ memset( rng, 0, sizeof( *rng ) );
+#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
+ /* Set default configuration if
+ * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
+ if( rng->entropy_init == NULL )
+ rng->entropy_init = mbedtls_entropy_init;
+ if( rng->entropy_free == NULL )
+ rng->entropy_free = mbedtls_entropy_free;
+
+ rng->entropy_init( &rng->entropy );
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+ defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
+ /* The PSA entropy injection feature depends on using NV seed as an entropy
+ * source. Add NV seed as an entropy source for PSA entropy injection. */
+ mbedtls_entropy_add_source( &rng->entropy,
+ mbedtls_nv_seed_poll, NULL,
+ MBEDTLS_ENTROPY_BLOCK_SIZE,
+ MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
+
+ mbedtls_psa_drbg_init( MBEDTLS_PSA_RANDOM_STATE );
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+}
+
+/** Deinitialize the PSA random generator.
+ */
+static void mbedtls_psa_random_free( mbedtls_psa_random_context_t *rng )
+{
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ memset( rng, 0, sizeof( *rng ) );
+#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+ mbedtls_psa_drbg_free( MBEDTLS_PSA_RANDOM_STATE );
+ rng->entropy_free( &rng->entropy );
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+}
+
+/** Seed the PSA random generator.
+ */
+static psa_status_t mbedtls_psa_random_seed( mbedtls_psa_random_context_t *rng )
+{
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ /* Do nothing: the external RNG seeds itself. */
+ (void) rng;
+ return( PSA_SUCCESS );
+#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+ const unsigned char drbg_seed[] = "PSA";
+ int ret = mbedtls_psa_drbg_seed( &rng->entropy,
+ drbg_seed, sizeof( drbg_seed ) - 1 );
+ return mbedtls_to_psa_error( ret );
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+}
+
psa_status_t psa_generate_random( uint8_t *output,
size_t output_size )
{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
GUARD_MODULE_INITIALIZED;
- while( output_size > MBEDTLS_CTR_DRBG_MAX_REQUEST )
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+
+ size_t output_length = 0;
+ psa_status_t status = mbedtls_psa_external_get_random( &global_data.rng,
+ output, output_size,
+ &output_length );
+ if( status != PSA_SUCCESS )
+ return( status );
+ /* Breaking up a request into smaller chunks is currently not supported
+ * for the extrernal RNG interface. */
+ if( output_length != output_size )
+ return( PSA_ERROR_INSUFFICIENT_ENTROPY );
+ return( PSA_SUCCESS );
+
+#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
+ while( output_size > 0 )
{
- ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
- output,
- MBEDTLS_CTR_DRBG_MAX_REQUEST );
+ size_t request_size =
+ ( output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
+ MBEDTLS_PSA_RANDOM_MAX_REQUEST :
+ output_size );
+ int ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
+ output, request_size );
if( ret != 0 )
return( mbedtls_to_psa_error( ret ) );
- output += MBEDTLS_CTR_DRBG_MAX_REQUEST;
- output_size -= MBEDTLS_CTR_DRBG_MAX_REQUEST;
+ output_size -= request_size;
+ output += request_size;
}
-
- ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
- return( mbedtls_to_psa_error( ret ) );
+ return( PSA_SUCCESS );
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
+/* Wrapper function allowing the classic API to use the PSA RNG.
+ *
+ * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
+ * `psa_generate_random(...)`. The state parameter is ignored since the
+ * PSA API doesn't support passing an explicit state.
+ *
+ * In the non-external case, psa_generate_random() calls an
+ * `mbedtls_xxx_drbg_random` function which has exactly the same signature
+ * and semantics as mbedtls_psa_get_random(). As an optimization,
+ * instead of doing this back-and-forth between the PSA API and the
+ * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
+ * as a constant function pointer to `mbedtls_xxx_drbg_random`.
+ */
+#if defined (MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+int mbedtls_psa_get_random( void *p_rng,
+ unsigned char *output,
+ size_t output_size )
+{
+ /* This function takes a pointer to the RNG state because that's what
+ * classic mbedtls functions using an RNG expect. The PSA RNG manages
+ * its own state internally and doesn't let the caller access that state.
+ * So we just ignore the state parameter, and in practice we'll pass
+ * NULL. */
+ (void) p_rng;
+ psa_status_t status = psa_generate_random( output, output_size );
+ if( status == PSA_SUCCESS )
+ return( 0 );
+ else
+ return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+}
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
#include "mbedtls/entropy_poll.h"
@@ -6447,8 +6583,8 @@
return( status );
mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
ret = mbedtls_rsa_gen_key( &rsa,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE,
(unsigned int) bits,
exponent );
if( ret != 0 )
@@ -6493,8 +6629,8 @@
return( PSA_ERROR_NOT_SUPPORTED );
mbedtls_ecp_keypair_init( &ecp );
ret = mbedtls_ecp_gen_key( grp_id, &ecp,
- mbedtls_ctr_drbg_random,
- &global_data.ctr_drbg );
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE );
if( ret != 0 )
{
mbedtls_ecp_keypair_free( &ecp );
@@ -6574,24 +6710,25 @@
/* Module setup */
/****************************************************************/
+#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
void (* entropy_init )( mbedtls_entropy_context *ctx ),
void (* entropy_free )( mbedtls_entropy_context *ctx ) )
{
if( global_data.rng_state != RNG_NOT_INITIALIZED )
return( PSA_ERROR_BAD_STATE );
- global_data.entropy_init = entropy_init;
- global_data.entropy_free = entropy_free;
+ global_data.rng.entropy_init = entropy_init;
+ global_data.rng.entropy_free = entropy_free;
return( PSA_SUCCESS );
}
+#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
void mbedtls_psa_crypto_free( void )
{
psa_wipe_all_key_slots( );
if( global_data.rng_state != RNG_NOT_INITIALIZED )
{
- mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
- global_data.entropy_free( &global_data.entropy );
+ mbedtls_psa_random_free( &global_data.rng );
}
/* Wipe all remaining data, including configuration.
* In particular, this sets all state indicator to the value
@@ -6633,37 +6770,15 @@
psa_status_t psa_crypto_init( void )
{
psa_status_t status;
- const unsigned char drbg_seed[] = "PSA";
/* Double initialization is explicitly allowed. */
if( global_data.initialized != 0 )
return( PSA_SUCCESS );
- /* Set default configuration if
- * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
- if( global_data.entropy_init == NULL )
- global_data.entropy_init = mbedtls_entropy_init;
- if( global_data.entropy_free == NULL )
- global_data.entropy_free = mbedtls_entropy_free;
-
- /* Initialize the random generator. */
- global_data.entropy_init( &global_data.entropy );
-#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
- defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
- /* The PSA entropy injection feature depends on using NV seed as an entropy
- * source. Add NV seed as an entropy source for PSA entropy injection. */
- mbedtls_entropy_add_source( &global_data.entropy,
- mbedtls_nv_seed_poll, NULL,
- MBEDTLS_ENTROPY_BLOCK_SIZE,
- MBEDTLS_ENTROPY_SOURCE_STRONG );
-#endif
- mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
+ /* Initialize and seed the random generator. */
+ mbedtls_psa_random_init( &global_data.rng );
global_data.rng_state = RNG_INITIALIZED;
- status = mbedtls_to_psa_error(
- mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
- mbedtls_entropy_func,
- &global_data.entropy,
- drbg_seed, sizeof( drbg_seed ) - 1 ) );
+ status = mbedtls_psa_random_seed( &global_data.rng );
if( status != PSA_SUCCESS )
goto exit;
global_data.rng_state = RNG_SEEDED;
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index c3ea6f1..1243bd3 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -263,7 +263,7 @@
switch( location )
{
case PSA_KEY_LOCATION_LOCAL_STORAGE:
- buffer_size = PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits );
+ buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits );
if( buffer_size == 0 )
return( PSA_ERROR_NOT_SUPPORTED );
@@ -280,7 +280,7 @@
if( PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) )
{
int public_key_overhead = ( ( TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY == 1 ) ?
- PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits ) : 0 );
+ PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ) : 0 );
*expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
+ TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE
+ public_key_overhead;
diff --git a/library/psa_crypto_invasive.h b/library/psa_crypto_invasive.h
index 2b4ee1f..be127d9 100644
--- a/library/psa_crypto_invasive.h
+++ b/library/psa_crypto_invasive.h
@@ -38,6 +38,7 @@
#include "mbedtls/entropy.h"
+#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
/** \brief Configure entropy sources.
*
* This function may only be called before a call to psa_crypto_init(),
@@ -73,5 +74,6 @@
psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
void (* entropy_init )( mbedtls_entropy_context *ctx ),
void (* entropy_free )( mbedtls_entropy_context *ctx ) );
+#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
#endif /* PSA_CRYPTO_INVASIVE_H */
diff --git a/library/psa_crypto_random_impl.h b/library/psa_crypto_random_impl.h
new file mode 100644
index 0000000..1232186
--- /dev/null
+++ b/library/psa_crypto_random_impl.h
@@ -0,0 +1,215 @@
+/** \file psa_crypto_random_impl.h
+ *
+ * \brief PSA crypto random generator implementation abstraction.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PSA_CRYPTO_RANDOM_IMPL_H
+#define PSA_CRYPTO_RANDOM_IMPL_H
+
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+
+#include <string.h>
+#include <mbedtls/entropy.h> // only for error codes
+#include <psa/crypto.h>
+
+typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
+
+/* Trivial wrapper around psa_generate_random(). */
+int mbedtls_psa_get_random( void *p_rng,
+ unsigned char *output,
+ size_t output_size );
+
+/* The PSA RNG API doesn't need any externally maintained state. */
+#define MBEDTLS_PSA_RANDOM_STATE NULL
+
+#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
+/* Choose a DRBG based on configuration and availability */
+#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
+
+#include "mbedtls/hmac_drbg.h"
+
+#elif defined(MBEDTLS_CTR_DRBG_C)
+
+#include "mbedtls/ctr_drbg.h"
+
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+
+#include "mbedtls/hmac_drbg.h"
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA256_C)
+#include <limits.h>
+#if SIZE_MAX > 0xffffffff
+/* Looks like a 64-bit system, so prefer SHA-512. */
+#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
+#else
+/* Looks like a 32-bit system, so prefer SHA-256. */
+#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
+#endif
+#elif defined(MBEDTLS_SHA512_C)
+#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
+#elif defined(MBEDTLS_SHA256_C)
+#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
+#else
+#error "No hash algorithm available for HMAC_DBRG."
+#endif
+
+#else
+#error "No DRBG module available for the psa_crypto module."
+#endif
+
+#include "mbedtls/entropy.h"
+
+/** The type of the PSA DRBG context.
+ */
+#if defined(MBEDTLS_CTR_DRBG_C)
+typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
+#endif
+
+/** Initialize the PSA DRBG.
+ *
+ * \param p_rng Pointer to the Mbed TLS DRBG state.
+ */
+static inline void mbedtls_psa_drbg_init( mbedtls_psa_drbg_context_t *p_rng )
+{
+#if defined(MBEDTLS_CTR_DRBG_C)
+ mbedtls_ctr_drbg_init( p_rng );
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ mbedtls_hmac_drbg_init( p_rng );
+#endif
+}
+
+/** Deinitialize the PSA DRBG.
+ *
+ * \param p_rng Pointer to the Mbed TLS DRBG state.
+ */
+static inline void mbedtls_psa_drbg_free( mbedtls_psa_drbg_context_t *p_rng )
+{
+#if defined(MBEDTLS_CTR_DRBG_C)
+ mbedtls_ctr_drbg_free( p_rng );
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ mbedtls_hmac_drbg_free( p_rng );
+#endif
+}
+
+/** The type of the PSA random generator context.
+ *
+ * The random generator context is composed of an entropy context and
+ * a DRBG context.
+ */
+typedef struct
+{
+ void (* entropy_init )( mbedtls_entropy_context *ctx );
+ void (* entropy_free )( mbedtls_entropy_context *ctx );
+ mbedtls_entropy_context entropy;
+ mbedtls_psa_drbg_context_t drbg;
+} mbedtls_psa_random_context_t;
+
+/* The type of an Mbed TLS random generator function. This should be
+ * part of the public API instead of repeating the type everywhere.
+ * For the time being, declare it here. Declaring a type is necessary
+ * to define mbedtls_psa_get_random as a variable of a function pointer
+ * type without incurring the wrath of check-names.sh. */
+typedef int mbedtls_f_rng_t( void *p_rng, unsigned char *output, size_t output_size );
+
+/** Return random data.
+ *
+ * This function is suitable as the \p f_rng parameter to Mbed TLS functions
+ * that require a random generator. Use #MBEDTLS_PSA_RANDOM_STATE to
+ * obtain the \p p_rng parameter.
+ *
+ * \param p_rng The DRBG context. This must be
+ * #MBEDTLS_PSA_RANDOM_STATE.
+ * \param output The buffer to fill.
+ * \param output_len The length of the buffer in bytes.
+ * It must be at most #MBEDTLS_PSA_RANDOM_MAX_REQUEST.
+ *
+ * \retval \c 0 on success.
+ * \return \c MBEDTLS_ERR_xxx_DRBG_xxx or
+ * \c MBEDTLS_ERR_PLATFORM_xxx on failure.
+ */
+#if defined(MBEDTLS_CTR_DRBG_C)
+static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_ctr_drbg_random;
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_hmac_drbg_random;
+#endif
+
+/** The maximum number of bytes that mbedtls_psa_get_random() is expected to
+ * return.
+ */
+#if defined(MBEDTLS_CTR_DRBG_C)
+#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
+#endif
+
+/** A pointer to the PSA DRBG state.
+ *
+ * This variable is only intended to be used through the macro
+ * #MBEDTLS_PSA_RANDOM_STATE.
+ */
+/* psa_crypto.c sets this variable to a pointer to the DRBG state in the
+ * global PSA crypto state. */
+extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
+
+/** A pointer to the PSA DRBG state.
+ *
+ * This macro expands to an expression that is suitable as the \c p_rng
+ * parameter to pass to mbedtls_psa_get_random().
+ *
+ * This macro exists in all configurations where the psa_crypto module is
+ * enabled. Its expansion depends on the configuration.
+ */
+#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
+
+/** Seed the PSA DRBG.
+ *
+ * \param entropy An entropy context to read the seed from.
+ * \param custom The personalization string.
+ * This can be \c NULL, in which case the personalization
+ * string is empty regardless of the value of \p len.
+ * \param len The length of the personalization string.
+ *
+ * \return \c 0 on success.
+ * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
+ */
+static inline int mbedtls_psa_drbg_seed(
+ mbedtls_entropy_context *entropy,
+ const unsigned char *custom, size_t len )
+{
+#if defined(MBEDTLS_CTR_DRBG_C)
+ return( mbedtls_ctr_drbg_seed( MBEDTLS_PSA_RANDOM_STATE,
+ mbedtls_entropy_func,
+ entropy,
+ custom, len ) );
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ const mbedtls_md_info_t *md_info =
+ mbedtls_md_info_from_type( MBEDTLS_PSA_HMAC_DRBG_MD_TYPE );
+ return( mbedtls_hmac_drbg_seed( MBEDTLS_PSA_RANDOM_STATE,
+ md_info,
+ mbedtls_entropy_func,
+ entropy,
+ custom, len ) );
+#endif
+}
+
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
+#endif /* PSA_CRYPTO_RANDOM_IMPL_H */
diff --git a/library/ripemd160.c b/library/ripemd160.c
index 603b6ba..ae4dee4 100644
--- a/library/ripemd160.c
+++ b/library/ripemd160.c
@@ -117,30 +117,33 @@
int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
const unsigned char data[64] )
{
- uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
+ struct
+ {
+ uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
+ } local;
- GET_UINT32_LE( X[ 0], data, 0 );
- GET_UINT32_LE( X[ 1], data, 4 );
- GET_UINT32_LE( X[ 2], data, 8 );
- GET_UINT32_LE( X[ 3], data, 12 );
- GET_UINT32_LE( X[ 4], data, 16 );
- GET_UINT32_LE( X[ 5], data, 20 );
- GET_UINT32_LE( X[ 6], data, 24 );
- GET_UINT32_LE( X[ 7], data, 28 );
- GET_UINT32_LE( X[ 8], data, 32 );
- GET_UINT32_LE( X[ 9], data, 36 );
- GET_UINT32_LE( X[10], data, 40 );
- GET_UINT32_LE( X[11], data, 44 );
- GET_UINT32_LE( X[12], data, 48 );
- GET_UINT32_LE( X[13], data, 52 );
- GET_UINT32_LE( X[14], data, 56 );
- GET_UINT32_LE( X[15], data, 60 );
+ GET_UINT32_LE( local.X[ 0], data, 0 );
+ GET_UINT32_LE( local.X[ 1], data, 4 );
+ GET_UINT32_LE( local.X[ 2], data, 8 );
+ GET_UINT32_LE( local.X[ 3], data, 12 );
+ GET_UINT32_LE( local.X[ 4], data, 16 );
+ GET_UINT32_LE( local.X[ 5], data, 20 );
+ GET_UINT32_LE( local.X[ 6], data, 24 );
+ GET_UINT32_LE( local.X[ 7], data, 28 );
+ GET_UINT32_LE( local.X[ 8], data, 32 );
+ GET_UINT32_LE( local.X[ 9], data, 36 );
+ GET_UINT32_LE( local.X[10], data, 40 );
+ GET_UINT32_LE( local.X[11], data, 44 );
+ GET_UINT32_LE( local.X[12], data, 48 );
+ GET_UINT32_LE( local.X[13], data, 52 );
+ GET_UINT32_LE( local.X[14], data, 56 );
+ GET_UINT32_LE( local.X[15], data, 60 );
- A = Ap = ctx->state[0];
- B = Bp = ctx->state[1];
- C = Cp = ctx->state[2];
- D = Dp = ctx->state[3];
- E = Ep = ctx->state[4];
+ local.A = local.Ap = ctx->state[0];
+ local.B = local.Bp = ctx->state[1];
+ local.C = local.Cp = ctx->state[2];
+ local.D = local.Dp = ctx->state[3];
+ local.E = local.Ep = ctx->state[4];
#define F1( x, y, z ) ( (x) ^ (y) ^ (z) )
#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) )
@@ -150,12 +153,12 @@
#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
-#define P( a, b, c, d, e, r, s, f, k ) \
- do \
- { \
- (a) += f( (b), (c), (d) ) + X[r] + (k); \
- (a) = S( (a), (s) ) + (e); \
- (c) = S( (c), 10 ); \
+#define P( a, b, c, d, e, r, s, f, k ) \
+ do \
+ { \
+ (a) += f( (b), (c), (d) ) + local.X[r] + (k); \
+ (a) = S( (a), (s) ) + (e); \
+ (c) = S( (c), 10 ); \
} while( 0 )
#define P2( a, b, c, d, e, r, s, rp, sp ) \
@@ -170,22 +173,22 @@
#define K 0x00000000
#define Fp F5
#define Kp 0x50A28BE6
- P2( A, B, C, D, E, 0, 11, 5, 8 );
- P2( E, A, B, C, D, 1, 14, 14, 9 );
- P2( D, E, A, B, C, 2, 15, 7, 9 );
- P2( C, D, E, A, B, 3, 12, 0, 11 );
- P2( B, C, D, E, A, 4, 5, 9, 13 );
- P2( A, B, C, D, E, 5, 8, 2, 15 );
- P2( E, A, B, C, D, 6, 7, 11, 15 );
- P2( D, E, A, B, C, 7, 9, 4, 5 );
- P2( C, D, E, A, B, 8, 11, 13, 7 );
- P2( B, C, D, E, A, 9, 13, 6, 7 );
- P2( A, B, C, D, E, 10, 14, 15, 8 );
- P2( E, A, B, C, D, 11, 15, 8, 11 );
- P2( D, E, A, B, C, 12, 6, 1, 14 );
- P2( C, D, E, A, B, 13, 7, 10, 14 );
- P2( B, C, D, E, A, 14, 9, 3, 12 );
- P2( A, B, C, D, E, 15, 8, 12, 6 );
+ P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 );
+ P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 );
+ P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 );
+ P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 );
+ P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 );
+ P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 );
+ P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 );
+ P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 );
+ P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 );
+ P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 );
+ P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 );
+ P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 );
+ P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 );
+ P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 );
+ P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 );
+ P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 );
#undef F
#undef K
#undef Fp
@@ -195,22 +198,22 @@
#define K 0x5A827999
#define Fp F4
#define Kp 0x5C4DD124
- P2( E, A, B, C, D, 7, 7, 6, 9 );
- P2( D, E, A, B, C, 4, 6, 11, 13 );
- P2( C, D, E, A, B, 13, 8, 3, 15 );
- P2( B, C, D, E, A, 1, 13, 7, 7 );
- P2( A, B, C, D, E, 10, 11, 0, 12 );
- P2( E, A, B, C, D, 6, 9, 13, 8 );
- P2( D, E, A, B, C, 15, 7, 5, 9 );
- P2( C, D, E, A, B, 3, 15, 10, 11 );
- P2( B, C, D, E, A, 12, 7, 14, 7 );
- P2( A, B, C, D, E, 0, 12, 15, 7 );
- P2( E, A, B, C, D, 9, 15, 8, 12 );
- P2( D, E, A, B, C, 5, 9, 12, 7 );
- P2( C, D, E, A, B, 2, 11, 4, 6 );
- P2( B, C, D, E, A, 14, 7, 9, 15 );
- P2( A, B, C, D, E, 11, 13, 1, 13 );
- P2( E, A, B, C, D, 8, 12, 2, 11 );
+ P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 );
+ P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 );
+ P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 );
+ P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 );
+ P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 );
+ P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 );
+ P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 );
+ P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 );
+ P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 );
+ P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 );
+ P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 );
+ P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 );
+ P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 );
+ P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 );
+ P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 );
+ P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 );
#undef F
#undef K
#undef Fp
@@ -220,22 +223,22 @@
#define K 0x6ED9EBA1
#define Fp F3
#define Kp 0x6D703EF3
- P2( D, E, A, B, C, 3, 11, 15, 9 );
- P2( C, D, E, A, B, 10, 13, 5, 7 );
- P2( B, C, D, E, A, 14, 6, 1, 15 );
- P2( A, B, C, D, E, 4, 7, 3, 11 );
- P2( E, A, B, C, D, 9, 14, 7, 8 );
- P2( D, E, A, B, C, 15, 9, 14, 6 );
- P2( C, D, E, A, B, 8, 13, 6, 6 );
- P2( B, C, D, E, A, 1, 15, 9, 14 );
- P2( A, B, C, D, E, 2, 14, 11, 12 );
- P2( E, A, B, C, D, 7, 8, 8, 13 );
- P2( D, E, A, B, C, 0, 13, 12, 5 );
- P2( C, D, E, A, B, 6, 6, 2, 14 );
- P2( B, C, D, E, A, 13, 5, 10, 13 );
- P2( A, B, C, D, E, 11, 12, 0, 13 );
- P2( E, A, B, C, D, 5, 7, 4, 7 );
- P2( D, E, A, B, C, 12, 5, 13, 5 );
+ P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 );
+ P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 );
+ P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 );
+ P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 );
+ P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 );
+ P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 );
+ P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 );
+ P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 );
+ P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 );
+ P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 );
+ P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 );
+ P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 );
+ P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 );
+ P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 );
+ P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 );
+ P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 );
#undef F
#undef K
#undef Fp
@@ -245,22 +248,22 @@
#define K 0x8F1BBCDC
#define Fp F2
#define Kp 0x7A6D76E9
- P2( C, D, E, A, B, 1, 11, 8, 15 );
- P2( B, C, D, E, A, 9, 12, 6, 5 );
- P2( A, B, C, D, E, 11, 14, 4, 8 );
- P2( E, A, B, C, D, 10, 15, 1, 11 );
- P2( D, E, A, B, C, 0, 14, 3, 14 );
- P2( C, D, E, A, B, 8, 15, 11, 14 );
- P2( B, C, D, E, A, 12, 9, 15, 6 );
- P2( A, B, C, D, E, 4, 8, 0, 14 );
- P2( E, A, B, C, D, 13, 9, 5, 6 );
- P2( D, E, A, B, C, 3, 14, 12, 9 );
- P2( C, D, E, A, B, 7, 5, 2, 12 );
- P2( B, C, D, E, A, 15, 6, 13, 9 );
- P2( A, B, C, D, E, 14, 8, 9, 12 );
- P2( E, A, B, C, D, 5, 6, 7, 5 );
- P2( D, E, A, B, C, 6, 5, 10, 15 );
- P2( C, D, E, A, B, 2, 12, 14, 8 );
+ P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 );
+ P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 );
+ P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 );
+ P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 );
+ P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 );
+ P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 );
+ P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 );
+ P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 );
+ P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 );
+ P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 );
+ P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 );
+ P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 );
+ P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 );
+ P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 );
+ P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 );
+ P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 );
#undef F
#undef K
#undef Fp
@@ -270,33 +273,36 @@
#define K 0xA953FD4E
#define Fp F1
#define Kp 0x00000000
- P2( B, C, D, E, A, 4, 9, 12, 8 );
- P2( A, B, C, D, E, 0, 15, 15, 5 );
- P2( E, A, B, C, D, 5, 5, 10, 12 );
- P2( D, E, A, B, C, 9, 11, 4, 9 );
- P2( C, D, E, A, B, 7, 6, 1, 12 );
- P2( B, C, D, E, A, 12, 8, 5, 5 );
- P2( A, B, C, D, E, 2, 13, 8, 14 );
- P2( E, A, B, C, D, 10, 12, 7, 6 );
- P2( D, E, A, B, C, 14, 5, 6, 8 );
- P2( C, D, E, A, B, 1, 12, 2, 13 );
- P2( B, C, D, E, A, 3, 13, 13, 6 );
- P2( A, B, C, D, E, 8, 14, 14, 5 );
- P2( E, A, B, C, D, 11, 11, 0, 15 );
- P2( D, E, A, B, C, 6, 8, 3, 13 );
- P2( C, D, E, A, B, 15, 5, 9, 11 );
- P2( B, C, D, E, A, 13, 6, 11, 11 );
+ P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 );
+ P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 );
+ P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 );
+ P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 );
+ P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 );
+ P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 );
+ P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 );
+ P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 );
+ P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 );
+ P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 );
+ P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 );
+ P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 );
+ P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 );
+ P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 );
+ P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 );
+ P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 );
#undef F
#undef K
#undef Fp
#undef Kp
- C = ctx->state[1] + C + Dp;
- ctx->state[1] = ctx->state[2] + D + Ep;
- ctx->state[2] = ctx->state[3] + E + Ap;
- ctx->state[3] = ctx->state[4] + A + Bp;
- ctx->state[4] = ctx->state[0] + B + Cp;
- ctx->state[0] = C;
+ local.C = ctx->state[1] + local.C + local.Dp;
+ ctx->state[1] = ctx->state[2] + local.D + local.Ep;
+ ctx->state[2] = ctx->state[3] + local.E + local.Ap;
+ ctx->state[3] = ctx->state[4] + local.A + local.Bp;
+ ctx->state[4] = ctx->state[0] + local.B + local.Cp;
+ ctx->state[0] = local.C;
+
+ /* Zeroise variables to clear sensitive data from memory. */
+ mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
diff --git a/library/rsa.c b/library/rsa.c
index d6abd65..9fe551d 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -1076,10 +1076,10 @@
mbedtls_mpi_free( &C );
mbedtls_mpi_free( &I );
- if( ret != 0 )
+ if( ret != 0 && ret >= -0x007f )
return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
- return( 0 );
+ return( ret );
}
#if defined(MBEDTLS_PKCS1_V21)
diff --git a/library/sha1.c b/library/sha1.c
index 593f795..6b0f58e 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -125,35 +125,40 @@
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
const unsigned char data[64] )
{
- uint32_t temp, W[16], A, B, C, D, E;
+ struct
+ {
+ uint32_t temp, W[16], A, B, C, D, E;
+ } local;
SHA1_VALIDATE_RET( ctx != NULL );
SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
- GET_UINT32_BE( W[ 0], data, 0 );
- GET_UINT32_BE( W[ 1], data, 4 );
- GET_UINT32_BE( W[ 2], data, 8 );
- GET_UINT32_BE( W[ 3], data, 12 );
- GET_UINT32_BE( W[ 4], data, 16 );
- GET_UINT32_BE( W[ 5], data, 20 );
- GET_UINT32_BE( W[ 6], data, 24 );
- GET_UINT32_BE( W[ 7], data, 28 );
- GET_UINT32_BE( W[ 8], data, 32 );
- GET_UINT32_BE( W[ 9], data, 36 );
- GET_UINT32_BE( W[10], data, 40 );
- GET_UINT32_BE( W[11], data, 44 );
- GET_UINT32_BE( W[12], data, 48 );
- GET_UINT32_BE( W[13], data, 52 );
- GET_UINT32_BE( W[14], data, 56 );
- GET_UINT32_BE( W[15], data, 60 );
+ GET_UINT32_BE( local.W[ 0], data, 0 );
+ GET_UINT32_BE( local.W[ 1], data, 4 );
+ GET_UINT32_BE( local.W[ 2], data, 8 );
+ GET_UINT32_BE( local.W[ 3], data, 12 );
+ GET_UINT32_BE( local.W[ 4], data, 16 );
+ GET_UINT32_BE( local.W[ 5], data, 20 );
+ GET_UINT32_BE( local.W[ 6], data, 24 );
+ GET_UINT32_BE( local.W[ 7], data, 28 );
+ GET_UINT32_BE( local.W[ 8], data, 32 );
+ GET_UINT32_BE( local.W[ 9], data, 36 );
+ GET_UINT32_BE( local.W[10], data, 40 );
+ GET_UINT32_BE( local.W[11], data, 44 );
+ GET_UINT32_BE( local.W[12], data, 48 );
+ GET_UINT32_BE( local.W[13], data, 52 );
+ GET_UINT32_BE( local.W[14], data, 56 );
+ GET_UINT32_BE( local.W[15], data, 60 );
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
#define R(t) \
( \
- temp = W[( (t) - 3 ) & 0x0F] ^ W[( (t) - 8 ) & 0x0F] ^ \
- W[( (t) - 14 ) & 0x0F] ^ W[ (t) & 0x0F], \
- ( W[(t) & 0x0F] = S(temp,1) ) \
+ local.temp = local.W[( (t) - 3 ) & 0x0F] ^ \
+ local.W[( (t) - 8 ) & 0x0F] ^ \
+ local.W[( (t) - 14 ) & 0x0F] ^ \
+ local.W[ (t) & 0x0F], \
+ ( local.W[(t) & 0x0F] = S(local.temp,1) ) \
)
#define P(a,b,c,d,e,x) \
@@ -163,35 +168,35 @@
(b) = S((b),30); \
} while( 0 )
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
+ local.A = ctx->state[0];
+ local.B = ctx->state[1];
+ local.C = ctx->state[2];
+ local.D = ctx->state[3];
+ local.E = ctx->state[4];
#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define K 0x5A827999
- P( A, B, C, D, E, W[0] );
- P( E, A, B, C, D, W[1] );
- P( D, E, A, B, C, W[2] );
- P( C, D, E, A, B, W[3] );
- P( B, C, D, E, A, W[4] );
- P( A, B, C, D, E, W[5] );
- P( E, A, B, C, D, W[6] );
- P( D, E, A, B, C, W[7] );
- P( C, D, E, A, B, W[8] );
- P( B, C, D, E, A, W[9] );
- P( A, B, C, D, E, W[10] );
- P( E, A, B, C, D, W[11] );
- P( D, E, A, B, C, W[12] );
- P( C, D, E, A, B, W[13] );
- P( B, C, D, E, A, W[14] );
- P( A, B, C, D, E, W[15] );
- P( E, A, B, C, D, R(16) );
- P( D, E, A, B, C, R(17) );
- P( C, D, E, A, B, R(18) );
- P( B, C, D, E, A, R(19) );
+ P( local.A, local.B, local.C, local.D, local.E, local.W[0] );
+ P( local.E, local.A, local.B, local.C, local.D, local.W[1] );
+ P( local.D, local.E, local.A, local.B, local.C, local.W[2] );
+ P( local.C, local.D, local.E, local.A, local.B, local.W[3] );
+ P( local.B, local.C, local.D, local.E, local.A, local.W[4] );
+ P( local.A, local.B, local.C, local.D, local.E, local.W[5] );
+ P( local.E, local.A, local.B, local.C, local.D, local.W[6] );
+ P( local.D, local.E, local.A, local.B, local.C, local.W[7] );
+ P( local.C, local.D, local.E, local.A, local.B, local.W[8] );
+ P( local.B, local.C, local.D, local.E, local.A, local.W[9] );
+ P( local.A, local.B, local.C, local.D, local.E, local.W[10] );
+ P( local.E, local.A, local.B, local.C, local.D, local.W[11] );
+ P( local.D, local.E, local.A, local.B, local.C, local.W[12] );
+ P( local.C, local.D, local.E, local.A, local.B, local.W[13] );
+ P( local.B, local.C, local.D, local.E, local.A, local.W[14] );
+ P( local.A, local.B, local.C, local.D, local.E, local.W[15] );
+ P( local.E, local.A, local.B, local.C, local.D, R(16) );
+ P( local.D, local.E, local.A, local.B, local.C, R(17) );
+ P( local.C, local.D, local.E, local.A, local.B, R(18) );
+ P( local.B, local.C, local.D, local.E, local.A, R(19) );
#undef K
#undef F
@@ -199,26 +204,26 @@
#define F(x,y,z) ((x) ^ (y) ^ (z))
#define K 0x6ED9EBA1
- P( A, B, C, D, E, R(20) );
- P( E, A, B, C, D, R(21) );
- P( D, E, A, B, C, R(22) );
- P( C, D, E, A, B, R(23) );
- P( B, C, D, E, A, R(24) );
- P( A, B, C, D, E, R(25) );
- P( E, A, B, C, D, R(26) );
- P( D, E, A, B, C, R(27) );
- P( C, D, E, A, B, R(28) );
- P( B, C, D, E, A, R(29) );
- P( A, B, C, D, E, R(30) );
- P( E, A, B, C, D, R(31) );
- P( D, E, A, B, C, R(32) );
- P( C, D, E, A, B, R(33) );
- P( B, C, D, E, A, R(34) );
- P( A, B, C, D, E, R(35) );
- P( E, A, B, C, D, R(36) );
- P( D, E, A, B, C, R(37) );
- P( C, D, E, A, B, R(38) );
- P( B, C, D, E, A, R(39) );
+ P( local.A, local.B, local.C, local.D, local.E, R(20) );
+ P( local.E, local.A, local.B, local.C, local.D, R(21) );
+ P( local.D, local.E, local.A, local.B, local.C, R(22) );
+ P( local.C, local.D, local.E, local.A, local.B, R(23) );
+ P( local.B, local.C, local.D, local.E, local.A, R(24) );
+ P( local.A, local.B, local.C, local.D, local.E, R(25) );
+ P( local.E, local.A, local.B, local.C, local.D, R(26) );
+ P( local.D, local.E, local.A, local.B, local.C, R(27) );
+ P( local.C, local.D, local.E, local.A, local.B, R(28) );
+ P( local.B, local.C, local.D, local.E, local.A, R(29) );
+ P( local.A, local.B, local.C, local.D, local.E, R(30) );
+ P( local.E, local.A, local.B, local.C, local.D, R(31) );
+ P( local.D, local.E, local.A, local.B, local.C, R(32) );
+ P( local.C, local.D, local.E, local.A, local.B, R(33) );
+ P( local.B, local.C, local.D, local.E, local.A, R(34) );
+ P( local.A, local.B, local.C, local.D, local.E, R(35) );
+ P( local.E, local.A, local.B, local.C, local.D, R(36) );
+ P( local.D, local.E, local.A, local.B, local.C, R(37) );
+ P( local.C, local.D, local.E, local.A, local.B, R(38) );
+ P( local.B, local.C, local.D, local.E, local.A, R(39) );
#undef K
#undef F
@@ -226,26 +231,26 @@
#define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define K 0x8F1BBCDC
- P( A, B, C, D, E, R(40) );
- P( E, A, B, C, D, R(41) );
- P( D, E, A, B, C, R(42) );
- P( C, D, E, A, B, R(43) );
- P( B, C, D, E, A, R(44) );
- P( A, B, C, D, E, R(45) );
- P( E, A, B, C, D, R(46) );
- P( D, E, A, B, C, R(47) );
- P( C, D, E, A, B, R(48) );
- P( B, C, D, E, A, R(49) );
- P( A, B, C, D, E, R(50) );
- P( E, A, B, C, D, R(51) );
- P( D, E, A, B, C, R(52) );
- P( C, D, E, A, B, R(53) );
- P( B, C, D, E, A, R(54) );
- P( A, B, C, D, E, R(55) );
- P( E, A, B, C, D, R(56) );
- P( D, E, A, B, C, R(57) );
- P( C, D, E, A, B, R(58) );
- P( B, C, D, E, A, R(59) );
+ P( local.A, local.B, local.C, local.D, local.E, R(40) );
+ P( local.E, local.A, local.B, local.C, local.D, R(41) );
+ P( local.D, local.E, local.A, local.B, local.C, R(42) );
+ P( local.C, local.D, local.E, local.A, local.B, R(43) );
+ P( local.B, local.C, local.D, local.E, local.A, R(44) );
+ P( local.A, local.B, local.C, local.D, local.E, R(45) );
+ P( local.E, local.A, local.B, local.C, local.D, R(46) );
+ P( local.D, local.E, local.A, local.B, local.C, R(47) );
+ P( local.C, local.D, local.E, local.A, local.B, R(48) );
+ P( local.B, local.C, local.D, local.E, local.A, R(49) );
+ P( local.A, local.B, local.C, local.D, local.E, R(50) );
+ P( local.E, local.A, local.B, local.C, local.D, R(51) );
+ P( local.D, local.E, local.A, local.B, local.C, R(52) );
+ P( local.C, local.D, local.E, local.A, local.B, R(53) );
+ P( local.B, local.C, local.D, local.E, local.A, R(54) );
+ P( local.A, local.B, local.C, local.D, local.E, R(55) );
+ P( local.E, local.A, local.B, local.C, local.D, R(56) );
+ P( local.D, local.E, local.A, local.B, local.C, R(57) );
+ P( local.C, local.D, local.E, local.A, local.B, R(58) );
+ P( local.B, local.C, local.D, local.E, local.A, R(59) );
#undef K
#undef F
@@ -253,35 +258,38 @@
#define F(x,y,z) ((x) ^ (y) ^ (z))
#define K 0xCA62C1D6
- P( A, B, C, D, E, R(60) );
- P( E, A, B, C, D, R(61) );
- P( D, E, A, B, C, R(62) );
- P( C, D, E, A, B, R(63) );
- P( B, C, D, E, A, R(64) );
- P( A, B, C, D, E, R(65) );
- P( E, A, B, C, D, R(66) );
- P( D, E, A, B, C, R(67) );
- P( C, D, E, A, B, R(68) );
- P( B, C, D, E, A, R(69) );
- P( A, B, C, D, E, R(70) );
- P( E, A, B, C, D, R(71) );
- P( D, E, A, B, C, R(72) );
- P( C, D, E, A, B, R(73) );
- P( B, C, D, E, A, R(74) );
- P( A, B, C, D, E, R(75) );
- P( E, A, B, C, D, R(76) );
- P( D, E, A, B, C, R(77) );
- P( C, D, E, A, B, R(78) );
- P( B, C, D, E, A, R(79) );
+ P( local.A, local.B, local.C, local.D, local.E, R(60) );
+ P( local.E, local.A, local.B, local.C, local.D, R(61) );
+ P( local.D, local.E, local.A, local.B, local.C, R(62) );
+ P( local.C, local.D, local.E, local.A, local.B, R(63) );
+ P( local.B, local.C, local.D, local.E, local.A, R(64) );
+ P( local.A, local.B, local.C, local.D, local.E, R(65) );
+ P( local.E, local.A, local.B, local.C, local.D, R(66) );
+ P( local.D, local.E, local.A, local.B, local.C, R(67) );
+ P( local.C, local.D, local.E, local.A, local.B, R(68) );
+ P( local.B, local.C, local.D, local.E, local.A, R(69) );
+ P( local.A, local.B, local.C, local.D, local.E, R(70) );
+ P( local.E, local.A, local.B, local.C, local.D, R(71) );
+ P( local.D, local.E, local.A, local.B, local.C, R(72) );
+ P( local.C, local.D, local.E, local.A, local.B, R(73) );
+ P( local.B, local.C, local.D, local.E, local.A, R(74) );
+ P( local.A, local.B, local.C, local.D, local.E, R(75) );
+ P( local.E, local.A, local.B, local.C, local.D, R(76) );
+ P( local.D, local.E, local.A, local.B, local.C, R(77) );
+ P( local.C, local.D, local.E, local.A, local.B, R(78) );
+ P( local.B, local.C, local.D, local.E, local.A, R(79) );
#undef K
#undef F
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
+ ctx->state[0] += local.A;
+ ctx->state[1] += local.B;
+ ctx->state[2] += local.C;
+ ctx->state[3] += local.D;
+ ctx->state[4] += local.E;
+
+ /* Zeroise buffers and variables to clear sensitive data from memory. */
+ mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
diff --git a/library/sha256.c b/library/sha256.c
index b4c4b36..be373d9 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -179,77 +179,104 @@
#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
-#define R(t) \
- ( \
- W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \
- S0(W[(t) - 15]) + W[(t) - 16] \
+#define R(t) \
+ ( \
+ local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
+ S0(local.W[(t) - 15]) + local.W[(t) - 16] \
)
-#define P(a,b,c,d,e,f,g,h,x,K) \
- do \
- { \
- temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
- temp2 = S2(a) + F0((a),(b),(c)); \
- (d) += temp1; (h) = temp1 + temp2; \
+#define P(a,b,c,d,e,f,g,h,x,K) \
+ do \
+ { \
+ local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
+ local.temp2 = S2(a) + F0((a),(b),(c)); \
+ (d) += local.temp1; (h) = local.temp1 + local.temp2; \
} while( 0 )
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
const unsigned char data[64] )
{
- uint32_t temp1, temp2, W[64];
- uint32_t A[8];
+ struct
+ {
+ uint32_t temp1, temp2, W[64];
+ uint32_t A[8];
+ } local;
+
unsigned int i;
SHA256_VALIDATE_RET( ctx != NULL );
SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
for( i = 0; i < 8; i++ )
- A[i] = ctx->state[i];
+ local.A[i] = ctx->state[i];
#if defined(MBEDTLS_SHA256_SMALLER)
for( i = 0; i < 64; i++ )
{
if( i < 16 )
- GET_UINT32_BE( W[i], data, 4 * i );
+ GET_UINT32_BE( local.W[i], data, 4 * i );
else
R( i );
- P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
- temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
- A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
+ local.temp1 = local.A[7]; local.A[7] = local.A[6];
+ local.A[6] = local.A[5]; local.A[5] = local.A[4];
+ local.A[4] = local.A[3]; local.A[3] = local.A[2];
+ local.A[2] = local.A[1]; local.A[1] = local.A[0];
+ local.A[0] = local.temp1;
}
#else /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 16; i++ )
- GET_UINT32_BE( W[i], data, 4 * i );
+ GET_UINT32_BE( local.W[i], data, 4 * i );
for( i = 0; i < 16; i += 8 )
{
- P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
- P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
- P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
- P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
- P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
- P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
- P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
- P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
+ P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
+ local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
+ P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
+ local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
+ P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
+ local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
+ P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
+ local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
+ P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
+ local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
+ P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
+ local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
+ P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
+ local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7] );
}
for( i = 16; i < 64; i += 8 )
{
- P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
- P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
- P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
- P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
- P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
- P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
- P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
- P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
+ P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
+ local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
+ P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
+ local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
+ P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
+ local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
+ P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
+ local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
+ P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
+ local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
+ P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
+ local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
+ P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
+ local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
}
#endif /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 8; i++ )
- ctx->state[i] += A[i];
+ ctx->state[i] += local.A[i];
+
+ /* Zeroise buffers and variables to clear sensitive data from memory. */
+ mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
diff --git a/library/sha512.c b/library/sha512.c
index e881198..06a628a 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -232,8 +232,11 @@
const unsigned char data[128] )
{
int i;
- uint64_t temp1, temp2, W[80];
- uint64_t A[8];
+ struct
+ {
+ uint64_t temp1, temp2, W[80];
+ uint64_t A[8];
+ } local;
SHA512_VALIDATE_RET( ctx != NULL );
SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
@@ -250,64 +253,79 @@
#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
-#define P(a,b,c,d,e,f,g,h,x,K) \
- do \
- { \
- temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
- temp2 = S2(a) + F0((a),(b),(c)); \
- (d) += temp1; (h) = temp1 + temp2; \
+#define P(a,b,c,d,e,f,g,h,x,K) \
+ do \
+ { \
+ local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
+ local.temp2 = S2(a) + F0((a),(b),(c)); \
+ (d) += local.temp1; (h) = local.temp1 + local.temp2; \
} while( 0 )
for( i = 0; i < 8; i++ )
- A[i] = ctx->state[i];
+ local.A[i] = ctx->state[i];
#if defined(MBEDTLS_SHA512_SMALLER)
for( i = 0; i < 80; i++ )
{
if( i < 16 )
{
- GET_UINT64_BE( W[i], data, i << 3 );
+ GET_UINT64_BE( local.W[i], data, i << 3 );
}
else
{
- W[i] = S1(W[i - 2]) + W[i - 7] +
- S0(W[i - 15]) + W[i - 16];
+ local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
+ S0(local.W[i - 15]) + local.W[i - 16];
}
- P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
- temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
- A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
+ local.temp1 = local.A[7]; local.A[7] = local.A[6];
+ local.A[6] = local.A[5]; local.A[5] = local.A[4];
+ local.A[4] = local.A[3]; local.A[3] = local.A[2];
+ local.A[2] = local.A[1]; local.A[1] = local.A[0];
+ local.A[0] = local.temp1;
}
#else /* MBEDTLS_SHA512_SMALLER */
for( i = 0; i < 16; i++ )
{
- GET_UINT64_BE( W[i], data, i << 3 );
+ GET_UINT64_BE( local.W[i], data, i << 3 );
}
for( ; i < 80; i++ )
{
- W[i] = S1(W[i - 2]) + W[i - 7] +
- S0(W[i - 15]) + W[i - 16];
+ local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
+ S0(local.W[i - 15]) + local.W[i - 16];
}
i = 0;
do
{
- P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++;
- P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++;
- P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++;
- P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++;
- P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++;
- P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++;
- P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++;
- P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++;
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
+ P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
+ local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
+ P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
+ local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
+ P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
+ local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
+ P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
+ local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
+ P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
+ local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
+ P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
+ local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
+ P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
+ local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
}
while( i < 80 );
#endif /* MBEDTLS_SHA512_SMALLER */
for( i = 0; i < 8; i++ )
- ctx->state[i] += A[i];
+ ctx->state[i] += local.A[i];
+
+ /* Zeroise buffers and variables to clear sensitive data from memory. */
+ mbedtls_platform_zeroize( &local, sizeof( local ) );
return( 0 );
}
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 0718d5a..72f09bb 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -850,20 +850,21 @@
* Encrypt and authenticate
*/
- if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc,
+ if( ( ret = mbedtls_cipher_auth_encrypt_ext( &transform->cipher_ctx_enc,
iv, transform->ivlen,
- add_data, add_data_len, /* add data */
- data, rec->data_len, /* source */
- data, &rec->data_len, /* destination */
- data + rec->data_len, transform->taglen ) ) != 0 )
+ add_data, add_data_len,
+ data, rec->data_len, /* src */
+ data, rec->buf_len - (data - rec->buf), /* dst */
+ &rec->data_len,
+ transform->taglen ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
return( ret );
}
MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag",
- data + rec->data_len, transform->taglen );
+ data + rec->data_len - transform->taglen,
+ transform->taglen );
/* Account for authentication tag. */
- rec->data_len += transform->taglen;
post_avail -= transform->taglen;
/*
@@ -1422,12 +1423,11 @@
/*
* Decrypt and authenticate
*/
- if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx_dec,
+ if( ( ret = mbedtls_cipher_auth_decrypt_ext( &transform->cipher_ctx_dec,
iv, transform->ivlen,
add_data, add_data_len,
- data, rec->data_len,
- data, &olen,
- data + rec->data_len,
+ data, rec->data_len + transform->taglen, /* src */
+ data, rec->buf_len - (data - rec->buf), &olen, /* dst */
transform->taglen ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index e3e8023..626d137 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -209,7 +209,6 @@
unsigned char *iv = start + TICKET_KEY_NAME_BYTES;
unsigned char *state_len_bytes = iv + TICKET_IV_BYTES;
unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES;
- unsigned char *tag;
size_t clear_len, ciph_len;
*tlen = 0;
@@ -250,23 +249,23 @@
state_len_bytes[1] = ( clear_len ) & 0xff;
/* Encrypt and authenticate */
- tag = state + clear_len;
- if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx,
+ if( ( ret = mbedtls_cipher_auth_encrypt_ext( &key->ctx,
iv, TICKET_IV_BYTES,
/* Additional data: key name, IV and length */
key_name, TICKET_ADD_DATA_LEN,
- state, clear_len, state, &ciph_len,
- tag, TICKET_AUTH_TAG_BYTES ) ) != 0 )
+ state, clear_len,
+ state, end - state, &ciph_len,
+ TICKET_AUTH_TAG_BYTES ) ) != 0 )
{
goto cleanup;
}
- if( ciph_len != clear_len )
+ if( ciph_len != clear_len + TICKET_AUTH_TAG_BYTES )
{
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto cleanup;
}
- *tlen = TICKET_MIN_LEN + ciph_len;
+ *tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES;
cleanup:
#if defined(MBEDTLS_THREADING_C)
@@ -308,7 +307,6 @@
unsigned char *iv = buf + TICKET_KEY_NAME_BYTES;
unsigned char *enc_len_p = iv + TICKET_IV_BYTES;
unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES;
- unsigned char *tag;
size_t enc_len, clear_len;
if( ctx == NULL || ctx->f_rng == NULL )
@@ -326,7 +324,6 @@
goto cleanup;
enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1];
- tag = ticket + enc_len;
if( len != TICKET_MIN_LEN + enc_len )
{
@@ -344,13 +341,13 @@
}
/* Decrypt and authenticate */
- if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx,
+ if( ( ret = mbedtls_cipher_auth_decrypt_ext( &key->ctx,
iv, TICKET_IV_BYTES,
/* Additional data: key name, IV and length */
key_name, TICKET_ADD_DATA_LEN,
- ticket, enc_len,
- ticket, &clear_len,
- tag, TICKET_AUTH_TAG_BYTES ) ) != 0 )
+ ticket, enc_len + TICKET_AUTH_TAG_BYTES,
+ ticket, enc_len, &clear_len,
+ TICKET_AUTH_TAG_BYTES ) ) != 0 )
{
if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
ret = MBEDTLS_ERR_SSL_INVALID_MAC;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index a1a5859..336cbea 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -260,6 +260,70 @@
return 0;
}
+
+static void handle_buffer_resizing( mbedtls_ssl_context *ssl, int downsizing,
+ size_t in_buf_new_len,
+ size_t out_buf_new_len )
+{
+ int modified = 0;
+ size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
+ size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
+ if( ssl->in_buf != NULL )
+ {
+ written_in = ssl->in_msg - ssl->in_buf;
+ iv_offset_in = ssl->in_iv - ssl->in_buf;
+ len_offset_in = ssl->in_len - ssl->in_buf;
+ if( downsizing ?
+ ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len :
+ ssl->in_buf_len < in_buf_new_len )
+ {
+ if( resize_buffer( &ssl->in_buf, in_buf_new_len, &ssl->in_buf_len ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", in_buf_new_len ) );
+ modified = 1;
+ }
+ }
+ }
+
+ if( ssl->out_buf != NULL )
+ {
+ written_out = ssl->out_msg - ssl->out_buf;
+ iv_offset_out = ssl->out_iv - ssl->out_buf;
+ len_offset_out = ssl->out_len - ssl->out_buf;
+ if( downsizing ?
+ ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len :
+ ssl->out_buf_len < out_buf_new_len )
+ {
+ if( resize_buffer( &ssl->out_buf, out_buf_new_len, &ssl->out_buf_len ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", out_buf_new_len ) );
+ modified = 1;
+ }
+ }
+ }
+ if( modified )
+ {
+ /* Update pointers here to avoid doing it twice. */
+ mbedtls_ssl_reset_in_out_pointers( ssl );
+ /* Fields below might not be properly updated with record
+ * splitting or with CID, so they are manually updated here. */
+ ssl->out_msg = ssl->out_buf + written_out;
+ ssl->out_len = ssl->out_buf + len_offset_out;
+ ssl->out_iv = ssl->out_buf + iv_offset_out;
+
+ ssl->in_msg = ssl->in_buf + written_in;
+ ssl->in_len = ssl->in_buf + len_offset_in;
+ ssl->in_iv = ssl->in_buf + iv_offset_in;
+ }
+}
#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
/*
@@ -3686,64 +3750,9 @@
}
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
/* If the buffers are too small - reallocate */
- {
- int modified = 0;
- size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
- size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
- if( ssl->in_buf != NULL )
- {
- written_in = ssl->in_msg - ssl->in_buf;
- iv_offset_in = ssl->in_iv - ssl->in_buf;
- len_offset_in = ssl->in_len - ssl->in_buf;
- if( ssl->in_buf_len < MBEDTLS_SSL_IN_BUFFER_LEN )
- {
- if( resize_buffer( &ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN,
- &ssl->in_buf_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", MBEDTLS_SSL_IN_BUFFER_LEN ) );
- modified = 1;
- }
- }
- }
- if( ssl->out_buf != NULL )
- {
- written_out = ssl->out_msg - ssl->out_buf;
- iv_offset_out = ssl->out_iv - ssl->out_buf;
- len_offset_out = ssl->out_len - ssl->out_buf;
- if( ssl->out_buf_len < MBEDTLS_SSL_OUT_BUFFER_LEN )
- {
- if( resize_buffer( &ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN,
- &ssl->out_buf_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", MBEDTLS_SSL_OUT_BUFFER_LEN ) );
- modified = 1;
- }
- }
- }
- if( modified )
- {
- /* Update pointers here to avoid doing it twice. */
- mbedtls_ssl_reset_in_out_pointers( ssl );
- /* Fields below might not be properly updated with record
- * splitting or with CID, so they are manually updated here. */
- ssl->out_msg = ssl->out_buf + written_out;
- ssl->out_len = ssl->out_buf + len_offset_out;
- ssl->out_iv = ssl->out_buf + iv_offset_out;
-
- ssl->in_msg = ssl->in_buf + written_in;
- ssl->in_len = ssl->in_buf + len_offset_in;
- ssl->in_iv = ssl->in_buf + iv_offset_in;
- }
- }
+ handle_buffer_resizing( ssl, 0, MBEDTLS_SSL_IN_BUFFER_LEN,
+ MBEDTLS_SSL_OUT_BUFFER_LEN );
#endif
/* All pointers should exist and can be directly freed without issue */
@@ -6068,66 +6077,8 @@
* processes datagrams and the fact that a datagram is allowed to have
* several records in it, it is possible that the I/O buffers are not
* empty at this stage */
- {
- int modified = 0;
- uint32_t buf_len = mbedtls_ssl_get_input_buflen( ssl );
- size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
- size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
- if( ssl->in_buf != NULL )
- {
- written_in = ssl->in_msg - ssl->in_buf;
- iv_offset_in = ssl->in_iv - ssl->in_buf;
- len_offset_in = ssl->in_len - ssl->in_buf;
- if( ssl->in_buf_len > buf_len && ssl->in_left < buf_len )
- {
- if( resize_buffer( &ssl->in_buf, buf_len, &ssl->in_buf_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", buf_len ) );
- modified = 1;
- }
- }
- }
-
-
- buf_len = mbedtls_ssl_get_output_buflen( ssl );
- if(ssl->out_buf != NULL )
- {
- written_out = ssl->out_msg - ssl->out_buf;
- iv_offset_out = ssl->out_iv - ssl->out_buf;
- len_offset_out = ssl->out_len - ssl->out_buf;
- if( ssl->out_buf_len > mbedtls_ssl_get_output_buflen( ssl ) &&
- ssl->out_left < buf_len )
- {
- if( resize_buffer( &ssl->out_buf, buf_len, &ssl->out_buf_len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", buf_len ) );
- modified = 1;
- }
- }
- }
- if( modified )
- {
- /* Update pointers here to avoid doing it twice. */
- mbedtls_ssl_reset_in_out_pointers( ssl );
- /* Fields below might not be properly updated with record
- * splitting or with CID, so they are manually updated here. */
- ssl->out_msg = ssl->out_buf + written_out;
- ssl->out_len = ssl->out_buf + len_offset_out;
- ssl->out_iv = ssl->out_buf + iv_offset_out;
-
- ssl->in_msg = ssl->in_buf + written_in;
- ssl->in_len = ssl->in_buf + len_offset_in;
- ssl->in_iv = ssl->in_buf + iv_offset_in;
- }
- }
+ handle_buffer_resizing( ssl, 1, mbedtls_ssl_get_input_buflen( ssl ),
+ mbedtls_ssl_get_output_buflen( ssl ) );
#endif
}
diff --git a/library/version_features.c b/library/version_features.c
index 42ccaf9..80f121a 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -438,6 +438,9 @@
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
"MBEDTLS_PSA_CRYPTO_DRIVERS",
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ "MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG",
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
"MBEDTLS_PSA_CRYPTO_SPM",
#endif /* MBEDTLS_PSA_CRYPTO_SPM */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 71e9cec..a623c57 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1304,6 +1304,7 @@
if( crt->sig_oid.len != sig_oid2.len ||
memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
+ sig_params1.tag != sig_params2.tag ||
sig_params1.len != sig_params2.len ||
( sig_params1.len != 0 &&
memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 32c6550..498b8b0 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -163,7 +163,7 @@
return(
mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
- 0, buf + sizeof(buf) - len, len ) );
+ is_ca, buf + sizeof(buf) - len, len ) );
}
#if defined(MBEDTLS_SHA1_C)
diff --git a/programs/.gitignore b/programs/.gitignore
index 88fb9d5..33593e0 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -1,7 +1,13 @@
+# Ignore makefiles generated by CMake, but not the makefile that's checked in.
*/Makefile
+!fuzz/Makefile
+
*.sln
*.vcxproj
+*.o
+*.exe
+
aes/aescrypt2
aes/crypt_and_hash
hash/generic_sum
diff --git a/programs/Makefile b/programs/Makefile
index 9cbc471..e0a324f 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -267,21 +267,32 @@
echo " CC ssl/ssl_client1.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client1.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-ssl/ssl_client2$(EXEXT): ssl/ssl_client2.c test/query_config.c $(DEP)
+SSL_TEST_OBJECTS = test/query_config.o ssl/ssl_test_lib.o
+SSL_TEST_DEPS = $(SSL_TEST_OBJECTS) \
+ test/query_config.h \
+ ssl/ssl_test_lib.h \
+ ssl/ssl_test_common_source.c \
+ $(DEP)
+
+ssl/ssl_test_lib.o: ssl/ssl_test_lib.c ssl/ssl_test_lib.h $(DEP)
+ echo " CC ssl/ssl_test_lib.c"
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c ssl/ssl_test_lib.c -o $@
+
+ssl/ssl_client2$(EXEXT): ssl/ssl_client2.c $(SSL_TEST_DEPS)
echo " CC ssl/ssl_client2.c"
- $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client2.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client2.c $(SSL_TEST_OBJECTS) $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
ssl/ssl_server$(EXEXT): ssl/ssl_server.c $(DEP)
echo " CC ssl/ssl_server.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-ssl/ssl_server2$(EXEXT): ssl/ssl_server2.c test/query_config.c $(DEP)
+ssl/ssl_server2$(EXEXT): ssl/ssl_server2.c $(SSL_TEST_DEPS)
echo " CC ssl/ssl_server2.c"
- $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server2.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server2.c $(SSL_TEST_OBJECTS) $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-ssl/ssl_context_info$(EXEXT): ssl/ssl_context_info.c test/query_config.c $(DEP)
+ssl/ssl_context_info$(EXEXT): ssl/ssl_context_info.c test/query_config.o test/query_config.h $(DEP)
echo " CC ssl/ssl_context_info.c"
- $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_context_info.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_context_info.c test/query_config.o $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
ssl/ssl_fork_server$(EXEXT): ssl/ssl_fork_server.c $(DEP)
echo " CC ssl/ssl_fork_server.c"
@@ -307,6 +318,10 @@
echo " CXX test/cpp_dummy_build.cpp"
$(CXX) $(LOCAL_CXXFLAGS) $(CXXFLAGS) test/cpp_dummy_build.cpp $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+test/query_config.o: test/query_config.c test/query_config.h $(DEP)
+ echo " CC test/query_config.c"
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c test/query_config.c -o $@
+
test/selftest$(EXEXT): test/selftest.c $(DEP)
echo " CC test/selftest.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/selftest.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
@@ -319,9 +334,9 @@
echo " CC test/zeroize.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/zeroize.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-test/query_compile_time_config$(EXEXT): test/query_compile_time_config.c test/query_config.c $(DEP)
+test/query_compile_time_config$(EXEXT): test/query_compile_time_config.c test/query_config.o test/query_config.h $(DEP)
echo " CC test/query_compile_time_config.c"
- $(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/query_compile_time_config.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/query_compile_time_config.c test/query_config.o $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
util/pem2der$(EXEXT): util/pem2der.c $(DEP)
echo " CC util/pem2der.c"
diff --git a/programs/fuzz/.gitignore b/programs/fuzz/.gitignore
index 6fcc004..5dc0960 100644
--- a/programs/fuzz/.gitignore
+++ b/programs/fuzz/.gitignore
@@ -1,4 +1,3 @@
-*.o
fuzz_client
fuzz_dtlsclient
fuzz_dtlsserver
diff --git a/programs/fuzz/CMakeLists.txt b/programs/fuzz/CMakeLists.txt
index f0e5705..fd55e31 100644
--- a/programs/fuzz/CMakeLists.txt
+++ b/programs/fuzz/CMakeLists.txt
@@ -32,20 +32,24 @@
foreach(exe IN LISTS executables_no_common_c executables_with_common_c)
- add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
-
- if (NOT FUZZINGENGINE_LIB)
- target_link_libraries(${exe} ${libs})
- set_property(TARGET ${exe} APPEND PROPERTY SOURCES onefile.c)
- else()
- target_link_libraries(${exe} ${libs} FuzzingEngine)
- SET_TARGET_PROPERTIES(${exe} PROPERTIES LINKER_LANGUAGE CXX)
+ set(exe_sources ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
+ if(NOT FUZZINGENGINE_LIB)
+ list(APPEND exe_sources onefile.c)
endif()
# This emulates "if ( ... IN_LIST ... )" which becomes available in CMake 3.3
list(FIND executables_with_common_c ${exe} exe_index)
- if (${exe_index} GREATER -1)
- set_property(TARGET ${exe} APPEND PROPERTY SOURCES common.c)
+ if(${exe_index} GREATER -1)
+ list(APPEND exe_sources common.c)
+ endif()
+
+ add_executable(${exe} ${exe_sources})
+
+ if (NOT FUZZINGENGINE_LIB)
+ target_link_libraries(${exe} ${libs})
+ else()
+ target_link_libraries(${exe} ${libs} FuzzingEngine)
+ SET_TARGET_PROPERTIES(${exe} PROPERTIES LINKER_LANGUAGE CXX)
endif()
endforeach()
diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c
index d165d2e..935d657 100644
--- a/programs/psa/crypto_examples.c
+++ b/programs/psa/crypto_examples.c
@@ -159,7 +159,7 @@
cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
{
enum {
- block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
+ block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( PSA_KEY_TYPE_AES ),
key_bits = 256,
part_size = block_size,
};
@@ -207,7 +207,7 @@
static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void )
{
enum {
- block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
+ block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( PSA_KEY_TYPE_AES ),
key_bits = 256,
input_size = 100,
part_size = 10,
@@ -255,7 +255,7 @@
static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void )
{
enum {
- block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ),
+ block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( PSA_KEY_TYPE_AES ),
key_bits = 256,
input_size = 100,
part_size = 10,
diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt
index 149aa30..dfc16a5 100644
--- a/programs/ssl/CMakeLists.txt
+++ b/programs/ssl/CMakeLists.txt
@@ -27,13 +27,21 @@
)
foreach(exe IN LISTS executables)
- add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
+ set(extra_sources "")
+ if(exe STREQUAL "ssl_client2" OR exe STREQUAL "ssl_server2")
+ list(APPEND extra_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c)
+ endif()
+ add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>
+ ${extra_sources})
target_link_libraries(${exe} ${libs})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
-set_property(TARGET ssl_client2 APPEND PROPERTY SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c)
-set_property(TARGET ssl_server2 APPEND PROPERTY SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c)
+set_property(TARGET ssl_client2 APPEND PROPERTY SOURCES
+ ssl_test_lib.c ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c)
+set_property(TARGET ssl_server2 APPEND PROPERTY SOURCES
+ ssl_test_lib.c ${CMAKE_CURRENT_SOURCE_DIR}/../test/query_config.c)
if(THREADS_FOUND)
add_executable(ssl_pthread_server ssl_pthread_server.c $<TARGET_OBJECTS:mbedtls_test>)
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index fc69061..876555d 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -17,68 +17,21 @@
* limitations under the License.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "ssl_test_lib.h"
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#define mbedtls_time time
-#define mbedtls_time_t time_t
-#define mbedtls_printf printf
-#define mbedtls_fprintf fprintf
-#define mbedtls_snprintf snprintf
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#define mbedtls_exit exit
-#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
-#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
-#endif
-
-#if !defined(MBEDTLS_ENTROPY_C) || \
- !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
- !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
- defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+#if defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
int main( void )
{
- mbedtls_printf( "MBEDTLS_ENTROPY_C and/or "
- "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
- "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined "
- " and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined.\n" );
+ mbedtls_printf( MBEDTLS_SSL_TEST_IMPOSSIBLE );
mbedtls_exit( 0 );
}
-#else
-
-#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#include "mbedtls/memory_buffer_alloc.h"
-#endif
-
-#include "mbedtls/net_sockets.h"
-#include "mbedtls/ssl.h"
-#include "mbedtls/entropy.h"
-#include "mbedtls/ctr_drbg.h"
-#include "mbedtls/certs.h"
-#include "mbedtls/x509.h"
-#include "mbedtls/error.h"
-#include "mbedtls/debug.h"
-#include "mbedtls/timing.h"
-#include "mbedtls/base64.h"
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-#include "psa/crypto.h"
-#include "mbedtls/psa_util.h"
-#endif
-
-#include <test/helpers.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#elif !defined(MBEDTLS_SSL_CLI_C)
+int main( void )
+{
+ mbedtls_printf( "MBEDTLS_SSL_CLI_C not defined.\n" );
+ mbedtls_exit( 0 );
+}
+#else /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_CLI_C */
/* Size of memory to be allocated for the heap, when using the library's memory
* management and MBEDTLS_MEMORY_BUFFER_ALLOC_C is enabled. */
@@ -568,425 +521,7 @@
const char *mki; /* The dtls mki value to use */
} opt;
-int query_config( const char *config );
-
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
-typedef struct eap_tls_keys
-{
- unsigned char master_secret[48];
- unsigned char randbytes[64];
- mbedtls_tls_prf_types tls_prf_type;
-} eap_tls_keys;
-
-static int eap_tls_key_derivation ( void *p_expkey,
- const unsigned char *ms,
- const unsigned char *kb,
- size_t maclen,
- size_t keylen,
- size_t ivlen,
- const unsigned char client_random[32],
- const unsigned char server_random[32],
- mbedtls_tls_prf_types tls_prf_type )
-{
- eap_tls_keys *keys = (eap_tls_keys *)p_expkey;
-
- ( ( void ) kb );
- memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
- memcpy( keys->randbytes, client_random, 32 );
- memcpy( keys->randbytes + 32, server_random, 32 );
- keys->tls_prf_type = tls_prf_type;
-
- if( opt.debug_level > 2 )
- {
- mbedtls_printf("exported maclen is %u\n", (unsigned)maclen);
- mbedtls_printf("exported keylen is %u\n", (unsigned)keylen);
- mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen);
- }
- return( 0 );
-}
-
-static int nss_keylog_export( void *p_expkey,
- const unsigned char *ms,
- const unsigned char *kb,
- size_t maclen,
- size_t keylen,
- size_t ivlen,
- const unsigned char client_random[32],
- const unsigned char server_random[32],
- mbedtls_tls_prf_types tls_prf_type )
-{
- char nss_keylog_line[ 200 ];
- size_t const client_random_len = 32;
- size_t const master_secret_len = 48;
- size_t len = 0;
- size_t j;
- int ret = 0;
-
- ((void) p_expkey);
- ((void) kb);
- ((void) maclen);
- ((void) keylen);
- ((void) ivlen);
- ((void) server_random);
- ((void) tls_prf_type);
-
- len += sprintf( nss_keylog_line + len,
- "%s", "CLIENT_RANDOM " );
-
- for( j = 0; j < client_random_len; j++ )
- {
- len += sprintf( nss_keylog_line + len,
- "%02x", client_random[j] );
- }
-
- len += sprintf( nss_keylog_line + len, " " );
-
- for( j = 0; j < master_secret_len; j++ )
- {
- len += sprintf( nss_keylog_line + len,
- "%02x", ms[j] );
- }
-
- len += sprintf( nss_keylog_line + len, "\n" );
- nss_keylog_line[ len ] = '\0';
-
- mbedtls_printf( "\n" );
- mbedtls_printf( "---------------- NSS KEYLOG -----------------\n" );
- mbedtls_printf( "%s", nss_keylog_line );
- mbedtls_printf( "---------------------------------------------\n" );
-
- if( opt.nss_keylog_file != NULL )
- {
- FILE *f;
-
- if( ( f = fopen( opt.nss_keylog_file, "a" ) ) == NULL )
- {
- ret = -1;
- goto exit;
- }
-
- if( fwrite( nss_keylog_line, 1, len, f ) != len )
- {
- ret = -1;
- fclose( f );
- goto exit;
- }
-
- fclose( f );
- }
-
-exit:
- mbedtls_platform_zeroize( nss_keylog_line,
- sizeof( nss_keylog_line ) );
- return( ret );
-}
-
-#if defined( MBEDTLS_SSL_DTLS_SRTP )
-/* Supported SRTP mode needs a maximum of :
- * - 16 bytes for key (AES-128)
- * - 14 bytes SALT
- * One for sender, one for receiver context
- */
-#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60
-typedef struct dtls_srtp_keys
-{
- unsigned char master_secret[48];
- unsigned char randbytes[64];
- mbedtls_tls_prf_types tls_prf_type;
-} dtls_srtp_keys;
-
-static int dtls_srtp_key_derivation( void *p_expkey,
- const unsigned char *ms,
- const unsigned char *kb,
- size_t maclen,
- size_t keylen,
- size_t ivlen,
- const unsigned char client_random[32],
- const unsigned char server_random[32],
- mbedtls_tls_prf_types tls_prf_type )
-{
- dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey;
-
- ( ( void ) kb );
- memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
- memcpy( keys->randbytes, client_random, 32 );
- memcpy( keys->randbytes + 32, server_random, 32 );
- keys->tls_prf_type = tls_prf_type;
-
- if( opt.debug_level > 2 )
- {
- mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen );
- mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen );
- mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen );
- }
- return( 0 );
-}
-#endif /* MBEDTLS_SSL_DTLS_SRTP */
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
-
-static void my_debug( void *ctx, int level,
- const char *file, int line,
- const char *str )
-{
- const char *p, *basename;
-
- /* Extract basename from file */
- for( p = basename = file; *p != '\0'; p++ )
- if( *p == '/' || *p == '\\' )
- basename = p + 1;
-
- mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s",
- basename, line, level, str );
- fflush( (FILE *) ctx );
-}
-
-
-mbedtls_time_t dummy_constant_time( mbedtls_time_t* time )
-{
- (void) time;
- return 0x5af2a056;
-}
-
-int dummy_entropy( void *data, unsigned char *output, size_t len )
-{
- size_t i;
- int ret;
- (void) data;
-
- ret = mbedtls_entropy_func( data, output, len );
- for ( i = 0; i < len; i++ )
- {
- //replace result with pseudo random
- output[i] = (unsigned char) rand();
- }
- return( ret );
-}
-
-#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
-int ca_callback( void *data, mbedtls_x509_crt const *child,
- mbedtls_x509_crt **candidates )
-{
- int ret = 0;
- mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data;
- mbedtls_x509_crt *first;
-
- /* This is a test-only implementation of the CA callback
- * which always returns the entire list of trusted certificates.
- * Production implementations managing a large number of CAs
- * should use an efficient presentation and lookup for the
- * set of trusted certificates (such as a hashtable) and only
- * return those trusted certificates which satisfy basic
- * parental checks, such as the matching of child `Issuer`
- * and parent `Subject` field or matching key identifiers. */
- ((void) child);
-
- first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
- if( first == NULL )
- {
- ret = -1;
- goto exit;
- }
- mbedtls_x509_crt_init( first );
-
- if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
- {
- ret = -1;
- goto exit;
- }
-
- while( ca->next != NULL )
- {
- ca = ca->next;
- if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
- {
- ret = -1;
- goto exit;
- }
- }
-
-exit:
-
- if( ret != 0 )
- {
- mbedtls_x509_crt_free( first );
- mbedtls_free( first );
- first = NULL;
- }
-
- *candidates = first;
- return( ret );
-}
-#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
-
-/*
- * Test recv/send functions that make sure each try returns
- * WANT_READ/WANT_WRITE at least once before sucesseding
- */
-
-static int delayed_recv( void *ctx, unsigned char *buf, size_t len )
-{
- static int first_try = 1;
- int ret;
-
- if( first_try )
- {
- first_try = 0;
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
-
- ret = mbedtls_net_recv( ctx, buf, len );
- if( ret != MBEDTLS_ERR_SSL_WANT_READ )
- first_try = 1; /* Next call will be a new operation */
- return( ret );
-}
-
-static int delayed_send( void *ctx, const unsigned char *buf, size_t len )
-{
- static int first_try = 1;
- int ret;
-
- if( first_try )
- {
- first_try = 0;
- return( MBEDTLS_ERR_SSL_WANT_WRITE );
- }
-
- ret = mbedtls_net_send( ctx, buf, len );
- if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
- first_try = 1; /* Next call will be a new operation */
- return( ret );
-}
-
-typedef struct
-{
- mbedtls_ssl_context *ssl;
- mbedtls_net_context *net;
-} io_ctx_t;
-
-#if defined(MBEDTLS_SSL_RECORD_CHECKING)
-static int ssl_check_record( mbedtls_ssl_context const *ssl,
- unsigned char const *buf, size_t len )
-{
- int ret;
- unsigned char *tmp_buf;
-
- tmp_buf = mbedtls_calloc( 1, len );
- if( tmp_buf == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- memcpy( tmp_buf, buf, len );
-
- ret = mbedtls_ssl_check_record( ssl, tmp_buf, len );
- if( ret != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE )
- {
- int ret_repeated;
-
- /* Test-only: Make sure that mbedtls_ssl_check_record()
- * doesn't alter state. */
- memcpy( tmp_buf, buf, len ); /* Restore buffer */
- ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len );
- if( ret != ret_repeated )
- {
- mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" );
- return( -1 );
- }
-
- switch( ret )
- {
- case 0:
- break;
-
- case MBEDTLS_ERR_SSL_INVALID_RECORD:
- if( opt.debug_level > 1 )
- mbedtls_printf( "mbedtls_ssl_check_record() detected invalid record.\n" );
- break;
-
- case MBEDTLS_ERR_SSL_INVALID_MAC:
- if( opt.debug_level > 1 )
- mbedtls_printf( "mbedtls_ssl_check_record() detected unauthentic record.\n" );
- break;
-
- case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD:
- if( opt.debug_level > 1 )
- mbedtls_printf( "mbedtls_ssl_check_record() detected unexpected record.\n" );
- break;
-
- default:
- mbedtls_printf( "mbedtls_ssl_check_record() failed fatally with -%#04x.\n", (unsigned int) -ret );
- return( -1 );
- }
-
- /* Regardless of the outcome, forward the record to the stack. */
- }
-
- mbedtls_free( tmp_buf );
-
- return( 0 );
-}
-#endif /* MBEDTLS_SSL_RECORD_CHECKING */
-
-static int recv_cb( void *ctx, unsigned char *buf, size_t len )
-{
- io_ctx_t *io_ctx = (io_ctx_t*) ctx;
- size_t recv_len;
- int ret;
-
- if( opt.nbio == 2 )
- ret = delayed_recv( io_ctx->net, buf, len );
- else
- ret = mbedtls_net_recv( io_ctx->net, buf, len );
- if( ret < 0 )
- return( ret );
- recv_len = (size_t) ret;
-
- if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Here's the place to do any datagram/record checking
- * in between receiving the packet from the underlying
- * transport and passing it on to the TLS stack. */
-#if defined(MBEDTLS_SSL_RECORD_CHECKING)
- if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
- return( -1 );
-#endif /* MBEDTLS_SSL_RECORD_CHECKING */
- }
-
- return( (int) recv_len );
-}
-
-static int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len,
- uint32_t timeout )
-{
- io_ctx_t *io_ctx = (io_ctx_t*) ctx;
- int ret;
- size_t recv_len;
-
- ret = mbedtls_net_recv_timeout( io_ctx->net, buf, len, timeout );
- if( ret < 0 )
- return( ret );
- recv_len = (size_t) ret;
-
- if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Here's the place to do any datagram/record checking
- * in between receiving the packet from the underlying
- * transport and passing it on to the TLS stack. */
-#if defined(MBEDTLS_SSL_RECORD_CHECKING)
- if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
- return( -1 );
-#endif /* MBEDTLS_SSL_RECORD_CHECKING */
- }
-
- return( (int) recv_len );
-}
-
-static int send_cb( void *ctx, unsigned char const *buf, size_t len )
-{
- io_ctx_t *io_ctx = (io_ctx_t*) ctx;
-
- if( opt.nbio == 2 )
- return( delayed_send( io_ctx->net, buf, len ) );
-
- return( mbedtls_net_send( io_ctx->net, buf, len ) );
-}
+#include "ssl_test_common_source.c"
#if defined(MBEDTLS_X509_CRT_PARSE_C)
static unsigned char peer_crt_info[1024];
@@ -1020,75 +555,8 @@
return( 0 );
}
-
-static int ssl_sig_hashes_for_test[] = {
-#if defined(MBEDTLS_SHA512_C)
- MBEDTLS_MD_SHA512,
- MBEDTLS_MD_SHA384,
-#endif
-#if defined(MBEDTLS_SHA256_C)
- MBEDTLS_MD_SHA256,
- MBEDTLS_MD_SHA224,
-#endif
-#if defined(MBEDTLS_SHA1_C)
- /* Allow SHA-1 as we use it extensively in tests. */
- MBEDTLS_MD_SHA1,
-#endif
- MBEDTLS_MD_NONE
-};
#endif /* MBEDTLS_X509_CRT_PARSE_C */
-/*
- * Wait for an event from the underlying transport or the timer
- * (Used in event-driven IO mode).
- */
-#if !defined(MBEDTLS_TIMING_C)
-int idle( mbedtls_net_context *fd,
- int idle_reason )
-#else
-int idle( mbedtls_net_context *fd,
- mbedtls_timing_delay_context *timer,
- int idle_reason )
-#endif
-{
-
- int ret;
- int poll_type = 0;
-
- if( idle_reason == MBEDTLS_ERR_SSL_WANT_WRITE )
- poll_type = MBEDTLS_NET_POLL_WRITE;
- else if( idle_reason == MBEDTLS_ERR_SSL_WANT_READ )
- poll_type = MBEDTLS_NET_POLL_READ;
-#if !defined(MBEDTLS_TIMING_C)
- else
- return( 0 );
-#endif
-
- while( 1 )
- {
- /* Check if timer has expired */
-#if defined(MBEDTLS_TIMING_C)
- if( timer != NULL &&
- mbedtls_timing_get_delay( timer ) == 2 )
- {
- break;
- }
-#endif /* MBEDTLS_TIMING_C */
-
- /* Check if underlying transport became available */
- if( poll_type != 0 )
- {
- ret = mbedtls_net_poll( fd, poll_type, 0 );
- if( ret < 0 )
- return( ret );
- if( ret == poll_type )
- break;
- }
- }
-
- return( 0 );
-}
-
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
int report_cid_usage( mbedtls_ssl_context *ssl,
const char *additional_description )
@@ -1218,8 +686,7 @@
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
#endif
- mbedtls_entropy_context entropy;
- mbedtls_ctr_drbg_context ctr_drbg;
+ rng_context_t rng;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_ssl_session saved_session;
@@ -1274,7 +741,7 @@
mbedtls_ssl_init( &ssl );
mbedtls_ssl_config_init( &conf );
memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) );
- mbedtls_ctr_drbg_init( &ctr_drbg );
+ rng_init( &rng );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_init( &cacert );
mbedtls_x509_crt_init( &clicert );
@@ -1293,7 +760,10 @@
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
-#endif
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ mbedtls_test_enable_insecure_external_rng( );
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( argc == 0 )
{
@@ -2066,31 +1536,8 @@
mbedtls_printf( "\n . Seeding the random number generator..." );
fflush( stdout );
- mbedtls_entropy_init( &entropy );
- if (opt.reproducible)
- {
- srand( 1 );
- if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy,
- &entropy, (const unsigned char *) pers,
- strlen( pers ) ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n",
- (unsigned int) -ret );
- goto exit;
- }
- }
- else
- {
- if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
- &entropy, (const unsigned char *) pers,
- strlen( pers ) ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n",
- (unsigned int) -ret );
- goto exit;
- }
- }
-
+ if( rng_seed( &rng, opt.reproducible, pers ) != 0 )
+ goto exit;
mbedtls_printf( " ok\n" );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -2339,12 +1786,12 @@
#endif
#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ const mbedtls_ssl_srtp_profile forced_profile[] =
+ { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
if( opt.use_srtp == 1 )
{
if( opt.force_srtp_profile != 0 )
{
- const mbedtls_ssl_srtp_profile forced_profile[] =
- { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles ( &conf, forced_profile );
}
else
@@ -2436,7 +1883,7 @@
#endif
#endif
}
- mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+ mbedtls_ssl_conf_rng( &conf, rng_get, &rng );
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
@@ -3556,8 +3003,7 @@
mbedtls_ssl_session_free( &saved_session );
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
- mbedtls_ctr_drbg_free( &ctr_drbg );
- mbedtls_entropy_free( &entropy );
+ rng_free( &rng );
if( session_data != NULL )
mbedtls_platform_zeroize( session_data, session_data_len );
mbedtls_free( session_data );
@@ -3612,6 +3058,4 @@
else
mbedtls_exit( query_config_ret );
}
-#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
- MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
- MBEDTLS_CTR_DRBG_C MBEDTLS_TIMING_C */
+#endif /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_CLI_C */
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index ceeb224..57c053c 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -17,64 +17,22 @@
* limitations under the License.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "ssl_test_lib.h"
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#define mbedtls_time time
-#define mbedtls_time_t time_t
-#define mbedtls_calloc calloc
-#define mbedtls_fprintf fprintf
-#define mbedtls_printf printf
-#define mbedtls_exit exit
-#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
-#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
-#endif
-
-#if !defined(MBEDTLS_ENTROPY_C) || \
- !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \
- !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
- defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+#if defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
int main( void )
{
- mbedtls_printf( "MBEDTLS_ENTROPY_C and/or "
- "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
- "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined "
- " and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined.\n" );
+ mbedtls_printf( MBEDTLS_SSL_TEST_IMPOSSIBLE );
mbedtls_exit( 0 );
}
-#else
+#elif !defined(MBEDTLS_SSL_SRV_C)
+int main( void )
+{
+ mbedtls_printf( "MBEDTLS_SSL_SRV_C not defined.\n" );
+ mbedtls_exit( 0 );
+}
+#else /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_SRV_C */
-#include "mbedtls/net_sockets.h"
-#include "mbedtls/ssl.h"
-#include "mbedtls/entropy.h"
-#include "mbedtls/ctr_drbg.h"
-#include "mbedtls/certs.h"
-#include "mbedtls/x509.h"
-#include "mbedtls/error.h"
-#include "mbedtls/debug.h"
-#include "mbedtls/timing.h"
-#include "mbedtls/base64.h"
-
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-#include "psa/crypto.h"
-#include "mbedtls/psa_util.h"
-#endif
-
-#include <test/helpers.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <stdint.h>
#if !defined(_MSC_VER)
@@ -97,10 +55,6 @@
#include "mbedtls/ssl_cookie.h"
#endif
-#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#include "mbedtls/memory_buffer_alloc.h"
-#endif
-
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && defined(MBEDTLS_FS_IO)
#define SNI_OPTION
#endif
@@ -670,424 +624,7 @@
int support_mki; /* The dtls mki mki support */
} opt;
-int query_config( const char *config );
-
-#if defined(MBEDTLS_SSL_EXPORT_KEYS)
-typedef struct eap_tls_keys
-{
- unsigned char master_secret[48];
- unsigned char randbytes[64];
- mbedtls_tls_prf_types tls_prf_type;
-} eap_tls_keys;
-
-static int eap_tls_key_derivation ( void *p_expkey,
- const unsigned char *ms,
- const unsigned char *kb,
- size_t maclen,
- size_t keylen,
- size_t ivlen,
- const unsigned char client_random[32],
- const unsigned char server_random[32],
- mbedtls_tls_prf_types tls_prf_type )
-{
- eap_tls_keys *keys = (eap_tls_keys *)p_expkey;
-
- ( ( void ) kb );
- memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
- memcpy( keys->randbytes, client_random, 32 );
- memcpy( keys->randbytes + 32, server_random, 32 );
- keys->tls_prf_type = tls_prf_type;
-
- if( opt.debug_level > 2 )
- {
- mbedtls_printf("exported maclen is %u\n", (unsigned)maclen);
- mbedtls_printf("exported keylen is %u\n", (unsigned)keylen);
- mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen);
- }
- return( 0 );
-}
-
-static int nss_keylog_export( void *p_expkey,
- const unsigned char *ms,
- const unsigned char *kb,
- size_t maclen,
- size_t keylen,
- size_t ivlen,
- const unsigned char client_random[32],
- const unsigned char server_random[32],
- mbedtls_tls_prf_types tls_prf_type )
-{
- char nss_keylog_line[ 200 ];
- size_t const client_random_len = 32;
- size_t const master_secret_len = 48;
- size_t len = 0;
- size_t j;
- int ret = 0;
-
- ((void) p_expkey);
- ((void) kb);
- ((void) maclen);
- ((void) keylen);
- ((void) ivlen);
- ((void) server_random);
- ((void) tls_prf_type);
-
- len += sprintf( nss_keylog_line + len,
- "%s", "CLIENT_RANDOM " );
-
- for( j = 0; j < client_random_len; j++ )
- {
- len += sprintf( nss_keylog_line + len,
- "%02x", client_random[j] );
- }
-
- len += sprintf( nss_keylog_line + len, " " );
-
- for( j = 0; j < master_secret_len; j++ )
- {
- len += sprintf( nss_keylog_line + len,
- "%02x", ms[j] );
- }
-
- len += sprintf( nss_keylog_line + len, "\n" );
- nss_keylog_line[ len ] = '\0';
-
- mbedtls_printf( "\n" );
- mbedtls_printf( "---------------- NSS KEYLOG -----------------\n" );
- mbedtls_printf( "%s", nss_keylog_line );
- mbedtls_printf( "---------------------------------------------\n" );
-
- if( opt.nss_keylog_file != NULL )
- {
- FILE *f;
-
- if( ( f = fopen( opt.nss_keylog_file, "a" ) ) == NULL )
- {
- ret = -1;
- goto exit;
- }
-
- if( fwrite( nss_keylog_line, 1, len, f ) != len )
- {
- ret = -1;
- fclose( f );
- goto exit;
- }
-
- fclose( f );
- }
-
-exit:
- mbedtls_platform_zeroize( nss_keylog_line,
- sizeof( nss_keylog_line ) );
- return( ret );
-}
-
-#if defined( MBEDTLS_SSL_DTLS_SRTP )
-/* Supported SRTP mode needs a maximum of :
- * - 16 bytes for key (AES-128)
- * - 14 bytes SALT
- * One for sender, one for receiver context
- */
-#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60
-typedef struct dtls_srtp_keys
-{
- unsigned char master_secret[48];
- unsigned char randbytes[64];
- mbedtls_tls_prf_types tls_prf_type;
-} dtls_srtp_keys;
-
-static int dtls_srtp_key_derivation( void *p_expkey,
- const unsigned char *ms,
- const unsigned char *kb,
- size_t maclen,
- size_t keylen,
- size_t ivlen,
- const unsigned char client_random[32],
- const unsigned char server_random[32],
- mbedtls_tls_prf_types tls_prf_type )
-{
- dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey;
-
- ( ( void ) kb );
- memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
- memcpy( keys->randbytes, client_random, 32 );
- memcpy( keys->randbytes + 32, server_random, 32 );
- keys->tls_prf_type = tls_prf_type;
-
- if( opt.debug_level > 2 )
- {
- mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen );
- mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen );
- mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen );
- }
- return( 0 );
-}
-#endif /* MBEDTLS_SSL_DTLS_SRTP */
-
-#endif /* MBEDTLS_SSL_EXPORT_KEYS */
-
-static void my_debug( void *ctx, int level,
- const char *file, int line,
- const char *str )
-{
- const char *p, *basename;
-
- /* Extract basename from file */
- for( p = basename = file; *p != '\0'; p++ )
- if( *p == '/' || *p == '\\' )
- basename = p + 1;
-
- mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s", basename, line, level, str );
- fflush( (FILE *) ctx );
-}
-
-mbedtls_time_t dummy_constant_time( mbedtls_time_t* time )
-{
- (void) time;
- return 0x5af2a056;
-}
-
-int dummy_entropy( void *data, unsigned char *output, size_t len )
-{
- size_t i;
- int ret;
- (void) data;
-
- ret = mbedtls_entropy_func( data, output, len );
- for (i = 0; i < len; i++ ) {
- //replace result with pseudo random
- output[i] = (unsigned char) rand();
- }
- return( ret );
-}
-
-#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
-int ca_callback( void *data, mbedtls_x509_crt const *child,
- mbedtls_x509_crt **candidates)
-{
- int ret = 0;
- mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data;
- mbedtls_x509_crt *first;
-
- /* This is a test-only implementation of the CA callback
- * which always returns the entire list of trusted certificates.
- * Production implementations managing a large number of CAs
- * should use an efficient presentation and lookup for the
- * set of trusted certificates (such as a hashtable) and only
- * return those trusted certificates which satisfy basic
- * parental checks, such as the matching of child `Issuer`
- * and parent `Subject` field. */
- ((void) child);
-
- first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
- if( first == NULL )
- {
- ret = -1;
- goto exit;
- }
- mbedtls_x509_crt_init( first );
-
- if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
- {
- ret = -1;
- goto exit;
- }
-
- while( ca->next != NULL )
- {
- ca = ca->next;
- if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
- {
- ret = -1;
- goto exit;
- }
- }
-
-exit:
-
- if( ret != 0 )
- {
- mbedtls_x509_crt_free( first );
- mbedtls_free( first );
- first = NULL;
- }
-
- *candidates = first;
- return( ret );
-}
-#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
-
-/*
- * Test recv/send functions that make sure each try returns
- * WANT_READ/WANT_WRITE at least once before sucesseding
- */
-static int delayed_recv( void *ctx, unsigned char *buf, size_t len )
-{
- static int first_try = 1;
- int ret;
-
- if( first_try )
- {
- first_try = 0;
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
-
- ret = mbedtls_net_recv( ctx, buf, len );
- if( ret != MBEDTLS_ERR_SSL_WANT_READ )
- first_try = 1; /* Next call will be a new operation */
- return( ret );
-}
-
-static int delayed_send( void *ctx, const unsigned char *buf, size_t len )
-{
- static int first_try = 1;
- int ret;
-
- if( first_try )
- {
- first_try = 0;
- return( MBEDTLS_ERR_SSL_WANT_WRITE );
- }
-
- ret = mbedtls_net_send( ctx, buf, len );
- if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
- first_try = 1; /* Next call will be a new operation */
- return( ret );
-}
-
-typedef struct
-{
- mbedtls_ssl_context *ssl;
- mbedtls_net_context *net;
-} io_ctx_t;
-
-#if defined(MBEDTLS_SSL_RECORD_CHECKING)
-static int ssl_check_record( mbedtls_ssl_context const *ssl,
- unsigned char const *buf, size_t len )
-{
- int ret;
- unsigned char *tmp_buf;
-
- /* Record checking may modify the input buffer,
- * so make a copy. */
- tmp_buf = mbedtls_calloc( 1, len );
- if( tmp_buf == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- memcpy( tmp_buf, buf, len );
-
- ret = mbedtls_ssl_check_record( ssl, tmp_buf, len );
- if( ret != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE )
- {
- int ret_repeated;
-
- /* Test-only: Make sure that mbedtls_ssl_check_record()
- * doesn't alter state. */
- memcpy( tmp_buf, buf, len ); /* Restore buffer */
- ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len );
- if( ret != ret_repeated )
- {
- mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" );
- return( -1 );
- }
-
- switch( ret )
- {
- case 0:
- break;
-
- case MBEDTLS_ERR_SSL_INVALID_RECORD:
- if( opt.debug_level > 1 )
- mbedtls_printf( "mbedtls_ssl_check_record() detected invalid record.\n" );
- break;
-
- case MBEDTLS_ERR_SSL_INVALID_MAC:
- if( opt.debug_level > 1 )
- mbedtls_printf( "mbedtls_ssl_check_record() detected unauthentic record.\n" );
- break;
-
- case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD:
- if( opt.debug_level > 1 )
- mbedtls_printf( "mbedtls_ssl_check_record() detected unexpected record.\n" );
- break;
-
- default:
- mbedtls_printf( "mbedtls_ssl_check_record() failed fatally with -%#04x.\n", (unsigned int) -ret );
- return( -1 );
- }
-
- /* Regardless of the outcome, forward the record to the stack. */
- }
-
- mbedtls_free( tmp_buf );
-
- return( 0 );
-}
-#endif /* MBEDTLS_SSL_RECORD_CHECKING */
-
-static int recv_cb( void *ctx, unsigned char *buf, size_t len )
-{
- io_ctx_t *io_ctx = (io_ctx_t*) ctx;
- size_t recv_len;
- int ret;
-
- if( opt.nbio == 2 )
- ret = delayed_recv( io_ctx->net, buf, len );
- else
- ret = mbedtls_net_recv( io_ctx->net, buf, len );
- if( ret < 0 )
- return( ret );
- recv_len = (size_t) ret;
-
- if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Here's the place to do any datagram/record checking
- * in between receiving the packet from the underlying
- * transport and passing it on to the TLS stack. */
-#if defined(MBEDTLS_SSL_RECORD_CHECKING)
- if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
- return( -1 );
-#endif /* MBEDTLS_SSL_RECORD_CHECKING */
- }
-
- return( (int) recv_len );
-}
-
-static int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len,
- uint32_t timeout )
-{
- io_ctx_t *io_ctx = (io_ctx_t*) ctx;
- int ret;
- size_t recv_len;
-
- ret = mbedtls_net_recv_timeout( io_ctx->net, buf, len, timeout );
- if( ret < 0 )
- return( ret );
- recv_len = (size_t) ret;
-
- if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Here's the place to do any datagram/record checking
- * in between receiving the packet from the underlying
- * transport and passing it on to the TLS stack. */
-#if defined(MBEDTLS_SSL_RECORD_CHECKING)
- if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
- return( -1 );
-#endif /* MBEDTLS_SSL_RECORD_CHECKING */
- }
-
- return( (int) recv_len );
-}
-
-static int send_cb( void *ctx, unsigned char const *buf, size_t len )
-{
- io_ctx_t *io_ctx = (io_ctx_t*) ctx;
-
- if( opt.nbio == 2 )
- return( delayed_send( io_ctx->net, buf, len ) );
-
- return( mbedtls_net_send( io_ctx->net, buf, len ) );
-}
+#include "ssl_test_common_source.c"
/*
* Return authmode from string, or -1 on error
@@ -1406,24 +943,6 @@
}
#endif
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-static int ssl_sig_hashes_for_test[] = {
-#if defined(MBEDTLS_SHA512_C)
- MBEDTLS_MD_SHA512,
- MBEDTLS_MD_SHA384,
-#endif
-#if defined(MBEDTLS_SHA256_C)
- MBEDTLS_MD_SHA256,
- MBEDTLS_MD_SHA224,
-#endif
-#if defined(MBEDTLS_SHA1_C)
- /* Allow SHA-1 as we use it extensively in tests. */
- MBEDTLS_MD_SHA1,
-#endif
- MBEDTLS_MD_NONE
-};
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
/** Return true if \p ret is a status code indicating that there is an
* operation in progress on an SSL connection, and false if it indicates
* success or a fatal error.
@@ -1662,56 +1181,6 @@
}
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
-/*
- * Wait for an event from the underlying transport or the timer
- * (Used in event-driven IO mode).
- */
-#if !defined(MBEDTLS_TIMING_C)
-int idle( mbedtls_net_context *fd,
- int idle_reason )
-#else
-int idle( mbedtls_net_context *fd,
- mbedtls_timing_delay_context *timer,
- int idle_reason )
-#endif
-{
- int ret;
- int poll_type = 0;
-
- if( idle_reason == MBEDTLS_ERR_SSL_WANT_WRITE )
- poll_type = MBEDTLS_NET_POLL_WRITE;
- else if( idle_reason == MBEDTLS_ERR_SSL_WANT_READ )
- poll_type = MBEDTLS_NET_POLL_READ;
-#if !defined(MBEDTLS_TIMING_C)
- else
- return( 0 );
-#endif
-
- while( 1 )
- {
- /* Check if timer has expired */
-#if defined(MBEDTLS_TIMING_C)
- if( timer != NULL &&
- mbedtls_timing_get_delay( timer ) == 2 )
- {
- break;
- }
-#endif /* MBEDTLS_TIMING_C */
-
- /* Check if underlying transport became available */
- if( poll_type != 0 )
- {
- ret = mbedtls_net_poll( fd, poll_type, 0 );
- if( ret < 0 )
- return( ret );
- if( ret == poll_type )
- break;
- }
- }
-
- return( 0 );
-}
-
#if defined(MBEDTLS_USE_PSA_CRYPTO)
static psa_status_t psa_setup_psk_key_slot( psa_key_id_t *slot,
psa_algorithm_t alg,
@@ -1813,8 +1282,7 @@
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
#endif
- mbedtls_entropy_context entropy;
- mbedtls_ctr_drbg_context ctr_drbg;
+ rng_context_t rng;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
#if defined(MBEDTLS_TIMING_C)
@@ -1908,7 +1376,7 @@
mbedtls_net_init( &listen_fd );
mbedtls_ssl_init( &ssl );
mbedtls_ssl_config_init( &conf );
- mbedtls_ctr_drbg_init( &ctr_drbg );
+ rng_init( &rng );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_init( &cacert );
mbedtls_x509_crt_init( &srvcert );
@@ -1944,7 +1412,10 @@
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
-#endif
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ mbedtls_test_enable_insecure_external_rng( );
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if !defined(_WIN32)
/* Abort cleanly on SIGTERM and SIGINT */
@@ -2824,31 +2295,8 @@
mbedtls_printf( "\n . Seeding the random number generator..." );
fflush( stdout );
- mbedtls_entropy_init( &entropy );
- if (opt.reproducible)
- {
- srand( 1 );
- if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy,
- &entropy, (const unsigned char *) pers,
- strlen( pers ) ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n",
- (unsigned int) -ret );
- goto exit;
- }
- }
- else
- {
- if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
- &entropy, (const unsigned char *) pers,
- strlen( pers ) ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n",
- (unsigned int) -ret );
- goto exit;
- }
- }
-
+ if( rng_seed( &rng, opt.reproducible, pers ) != 0 )
+ goto exit;
mbedtls_printf( " ok\n" );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -3151,11 +2599,11 @@
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
if( opt.use_srtp == 1 )
{
if( opt.force_srtp_profile != 0 )
{
- const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, forced_profile );
}
else
@@ -3237,7 +2685,7 @@
#endif
#endif
}
- mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+ mbedtls_ssl_conf_rng( &conf, rng_get, &rng );
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
#if defined(MBEDTLS_SSL_CACHE_C)
@@ -3256,7 +2704,7 @@
if( opt.tickets == MBEDTLS_SSL_SESSION_TICKETS_ENABLED )
{
if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx,
- mbedtls_ctr_drbg_random, &ctr_drbg,
+ rng_get, &rng,
MBEDTLS_CIPHER_AES_256_GCM,
opt.ticket_timeout ) ) != 0 )
{
@@ -3278,7 +2726,7 @@
if( opt.cookies > 0 )
{
if( ( ret = mbedtls_ssl_cookie_setup( &cookie_ctx,
- mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
+ rng_get, &rng ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret );
goto exit;
@@ -3430,8 +2878,8 @@
ssl_async_keys.inject_error = ( opt.async_private_error < 0 ?
- opt.async_private_error :
opt.async_private_error );
- ssl_async_keys.f_rng = mbedtls_ctr_drbg_random;
- ssl_async_keys.p_rng = &ctr_drbg;
+ ssl_async_keys.f_rng = rng_get;
+ ssl_async_keys.p_rng = &rng;
mbedtls_ssl_conf_async_private_cb( &conf,
sign,
decrypt,
@@ -4529,8 +3977,7 @@
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
- mbedtls_ctr_drbg_free( &ctr_drbg );
- mbedtls_entropy_free( &entropy );
+ rng_free( &rng );
#if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_free( &cache );
@@ -4576,6 +4023,4 @@
else
mbedtls_exit( query_config_ret );
}
-#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
- MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
- MBEDTLS_CTR_DRBG_C */
+#endif /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_SRV_C */
diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c
new file mode 100644
index 0000000..d9e3607
--- /dev/null
+++ b/programs/ssl/ssl_test_common_source.c
@@ -0,0 +1,305 @@
+/*
+ * Common source code for SSL test programs. This file is included by
+ * both ssl_client2.c and ssl_server2.c and is intended for source
+ * code that is textually identical in both programs, but that cannot be
+ * compiled separately because it refers to types or macros that are
+ * different in the two programs, or because it would have an incomplete
+ * type.
+ *
+ * This file is meant to be #include'd and cannot be compiled separately.
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+int eap_tls_key_derivation( void *p_expkey,
+ const unsigned char *ms,
+ const unsigned char *kb,
+ size_t maclen,
+ size_t keylen,
+ size_t ivlen,
+ const unsigned char client_random[32],
+ const unsigned char server_random[32],
+ mbedtls_tls_prf_types tls_prf_type )
+{
+ eap_tls_keys *keys = (eap_tls_keys *)p_expkey;
+
+ ( ( void ) kb );
+ memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
+ memcpy( keys->randbytes, client_random, 32 );
+ memcpy( keys->randbytes + 32, server_random, 32 );
+ keys->tls_prf_type = tls_prf_type;
+
+ if( opt.debug_level > 2 )
+ {
+ mbedtls_printf("exported maclen is %u\n", (unsigned)maclen);
+ mbedtls_printf("exported keylen is %u\n", (unsigned)keylen);
+ mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen);
+ }
+ return( 0 );
+}
+
+int nss_keylog_export( void *p_expkey,
+ const unsigned char *ms,
+ const unsigned char *kb,
+ size_t maclen,
+ size_t keylen,
+ size_t ivlen,
+ const unsigned char client_random[32],
+ const unsigned char server_random[32],
+ mbedtls_tls_prf_types tls_prf_type )
+{
+ char nss_keylog_line[ 200 ];
+ size_t const client_random_len = 32;
+ size_t const master_secret_len = 48;
+ size_t len = 0;
+ size_t j;
+ int ret = 0;
+
+ ((void) p_expkey);
+ ((void) kb);
+ ((void) maclen);
+ ((void) keylen);
+ ((void) ivlen);
+ ((void) server_random);
+ ((void) tls_prf_type);
+
+ len += sprintf( nss_keylog_line + len,
+ "%s", "CLIENT_RANDOM " );
+
+ for( j = 0; j < client_random_len; j++ )
+ {
+ len += sprintf( nss_keylog_line + len,
+ "%02x", client_random[j] );
+ }
+
+ len += sprintf( nss_keylog_line + len, " " );
+
+ for( j = 0; j < master_secret_len; j++ )
+ {
+ len += sprintf( nss_keylog_line + len,
+ "%02x", ms[j] );
+ }
+
+ len += sprintf( nss_keylog_line + len, "\n" );
+ nss_keylog_line[ len ] = '\0';
+
+ mbedtls_printf( "\n" );
+ mbedtls_printf( "---------------- NSS KEYLOG -----------------\n" );
+ mbedtls_printf( "%s", nss_keylog_line );
+ mbedtls_printf( "---------------------------------------------\n" );
+
+ if( opt.nss_keylog_file != NULL )
+ {
+ FILE *f;
+
+ if( ( f = fopen( opt.nss_keylog_file, "a" ) ) == NULL )
+ {
+ ret = -1;
+ goto exit;
+ }
+
+ if( fwrite( nss_keylog_line, 1, len, f ) != len )
+ {
+ ret = -1;
+ fclose( f );
+ goto exit;
+ }
+
+ fclose( f );
+ }
+
+exit:
+ mbedtls_platform_zeroize( nss_keylog_line,
+ sizeof( nss_keylog_line ) );
+ return( ret );
+}
+
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+int dtls_srtp_key_derivation( void *p_expkey,
+ const unsigned char *ms,
+ const unsigned char *kb,
+ size_t maclen,
+ size_t keylen,
+ size_t ivlen,
+ const unsigned char client_random[32],
+ const unsigned char server_random[32],
+ mbedtls_tls_prf_types tls_prf_type )
+{
+ dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey;
+
+ ( ( void ) kb );
+ memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
+ memcpy( keys->randbytes, client_random, 32 );
+ memcpy( keys->randbytes + 32, server_random, 32 );
+ keys->tls_prf_type = tls_prf_type;
+
+ if( opt.debug_level > 2 )
+ {
+ mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen );
+ mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen );
+ mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen );
+ }
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
+
+#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+int ssl_check_record( mbedtls_ssl_context const *ssl,
+ unsigned char const *buf, size_t len )
+{
+ int ret;
+ unsigned char *tmp_buf;
+
+ /* Record checking may modify the input buffer,
+ * so make a copy. */
+ tmp_buf = mbedtls_calloc( 1, len );
+ if( tmp_buf == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ memcpy( tmp_buf, buf, len );
+
+ ret = mbedtls_ssl_check_record( ssl, tmp_buf, len );
+ if( ret != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE )
+ {
+ int ret_repeated;
+
+ /* Test-only: Make sure that mbedtls_ssl_check_record()
+ * doesn't alter state. */
+ memcpy( tmp_buf, buf, len ); /* Restore buffer */
+ ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len );
+ if( ret != ret_repeated )
+ {
+ mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" );
+ return( -1 );
+ }
+
+ switch( ret )
+ {
+ case 0:
+ break;
+
+ case MBEDTLS_ERR_SSL_INVALID_RECORD:
+ if( opt.debug_level > 1 )
+ mbedtls_printf( "mbedtls_ssl_check_record() detected invalid record.\n" );
+ break;
+
+ case MBEDTLS_ERR_SSL_INVALID_MAC:
+ if( opt.debug_level > 1 )
+ mbedtls_printf( "mbedtls_ssl_check_record() detected unauthentic record.\n" );
+ break;
+
+ case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD:
+ if( opt.debug_level > 1 )
+ mbedtls_printf( "mbedtls_ssl_check_record() detected unexpected record.\n" );
+ break;
+
+ default:
+ mbedtls_printf( "mbedtls_ssl_check_record() failed fatally with -%#04x.\n", (unsigned int) -ret );
+ return( -1 );
+ }
+
+ /* Regardless of the outcome, forward the record to the stack. */
+ }
+
+ mbedtls_free( tmp_buf );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_RECORD_CHECKING */
+
+int recv_cb( void *ctx, unsigned char *buf, size_t len )
+{
+ io_ctx_t *io_ctx = (io_ctx_t*) ctx;
+ size_t recv_len;
+ int ret;
+
+ if( opt.nbio == 2 )
+ ret = delayed_recv( io_ctx->net, buf, len );
+ else
+ ret = mbedtls_net_recv( io_ctx->net, buf, len );
+ if( ret < 0 )
+ return( ret );
+ recv_len = (size_t) ret;
+
+ if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Here's the place to do any datagram/record checking
+ * in between receiving the packet from the underlying
+ * transport and passing it on to the TLS stack. */
+#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+ if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
+ return( -1 );
+#endif /* MBEDTLS_SSL_RECORD_CHECKING */
+ }
+
+ return( (int) recv_len );
+}
+
+int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len,
+ uint32_t timeout )
+{
+ io_ctx_t *io_ctx = (io_ctx_t*) ctx;
+ int ret;
+ size_t recv_len;
+
+ ret = mbedtls_net_recv_timeout( io_ctx->net, buf, len, timeout );
+ if( ret < 0 )
+ return( ret );
+ recv_len = (size_t) ret;
+
+ if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Here's the place to do any datagram/record checking
+ * in between receiving the packet from the underlying
+ * transport and passing it on to the TLS stack. */
+#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+ if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
+ return( -1 );
+#endif /* MBEDTLS_SSL_RECORD_CHECKING */
+ }
+
+ return( (int) recv_len );
+}
+
+int send_cb( void *ctx, unsigned char const *buf, size_t len )
+{
+ io_ctx_t *io_ctx = (io_ctx_t*) ctx;
+
+ if( opt.nbio == 2 )
+ return( delayed_send( io_ctx->net, buf, len ) );
+
+ return( mbedtls_net_send( io_ctx->net, buf, len ) );
+}
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+int ssl_sig_hashes_for_test[] = {
+#if defined(MBEDTLS_SHA512_C)
+ MBEDTLS_MD_SHA512,
+ MBEDTLS_MD_SHA384,
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ MBEDTLS_MD_SHA256,
+ MBEDTLS_MD_SHA224,
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ /* Allow SHA-1 as we use it extensively in tests. */
+ MBEDTLS_MD_SHA1,
+#endif
+ MBEDTLS_MD_NONE
+};
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c
new file mode 100644
index 0000000..46cea14
--- /dev/null
+++ b/programs/ssl/ssl_test_lib.c
@@ -0,0 +1,278 @@
+/*
+ * Common code library for SSL test programs.
+ *
+ * In addition to the functions in this file, there is shared source code
+ * that cannot be compiled separately in "ssl_test_common_source.c".
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ssl_test_lib.h"
+
+#if !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
+
+void my_debug( void *ctx, int level,
+ const char *file, int line,
+ const char *str )
+{
+ const char *p, *basename;
+
+ /* Extract basename from file */
+ for( p = basename = file; *p != '\0'; p++ )
+ if( *p == '/' || *p == '\\' )
+ basename = p + 1;
+
+ mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s",
+ basename, line, level, str );
+ fflush( (FILE *) ctx );
+}
+
+mbedtls_time_t dummy_constant_time( mbedtls_time_t* time )
+{
+ (void) time;
+ return 0x5af2a056;
+}
+
+static int dummy_entropy( void *data, unsigned char *output, size_t len )
+{
+ size_t i;
+ int ret;
+ (void) data;
+
+ ret = mbedtls_entropy_func( data, output, len );
+ for( i = 0; i < len; i++ )
+ {
+ //replace result with pseudo random
+ output[i] = (unsigned char) rand();
+ }
+ return( ret );
+}
+
+void rng_init( rng_context_t *rng )
+{
+#if defined(MBEDTLS_CTR_DRBG_C)
+ mbedtls_ctr_drbg_init( &rng->drbg );
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ mbedtls_hmac_drbg_init( &rng->drbg );
+#else
+#error "No DRBG available"
+#endif
+
+ mbedtls_entropy_init( &rng->entropy );
+}
+
+int rng_seed( rng_context_t *rng, int reproducible, const char *pers )
+{
+ int ( *f_entropy )( void *, unsigned char *, size_t ) =
+ ( reproducible ? dummy_entropy : mbedtls_entropy_func );
+
+ if ( reproducible )
+ srand( 1 );
+
+#if defined(MBEDTLS_CTR_DRBG_C)
+ int ret = mbedtls_ctr_drbg_seed( &rng->drbg,
+ f_entropy, &rng->entropy,
+ (const unsigned char *) pers,
+ strlen( pers ) );
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+#if defined(MBEDTLS_SHA256_C)
+ const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
+#elif defined(MBEDTLS_SHA512_C)
+ const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA512;
+#else
+#error "No message digest available for HMAC_DRBG"
+#endif
+ int ret = mbedtls_hmac_drbg_seed( &rng->drbg,
+ mbedtls_md_info_from_type( md_type ),
+ f_entropy, &rng->entropy,
+ (const unsigned char *) pers,
+ strlen( pers ) );
+#else
+#error "No DRBG available"
+#endif
+
+ if( ret != 0 )
+ {
+ mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n",
+ (unsigned int) -ret );
+ return( ret );
+ }
+
+ return( 0 );
+}
+
+void rng_free( rng_context_t *rng )
+{
+#if defined(MBEDTLS_CTR_DRBG_C)
+ mbedtls_ctr_drbg_free( &rng->drbg );
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ mbedtls_hmac_drbg_free( &rng->drbg );
+#else
+#error "No DRBG available"
+#endif
+
+ mbedtls_entropy_free( &rng->entropy );
+}
+
+int rng_get( void *p_rng, unsigned char *output, size_t output_len )
+{
+ rng_context_t *rng = p_rng;
+#if defined(MBEDTLS_CTR_DRBG_C)
+ return( mbedtls_ctr_drbg_random( &rng->drbg, output, output_len ) );
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ return( mbedtls_hmac_drbg_random( &rng->drbg, output, output_len ) );
+#else
+#error "No DRBG available"
+#endif
+}
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+int ca_callback( void *data, mbedtls_x509_crt const *child,
+ mbedtls_x509_crt **candidates )
+{
+ int ret = 0;
+ mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data;
+ mbedtls_x509_crt *first;
+
+ /* This is a test-only implementation of the CA callback
+ * which always returns the entire list of trusted certificates.
+ * Production implementations managing a large number of CAs
+ * should use an efficient presentation and lookup for the
+ * set of trusted certificates (such as a hashtable) and only
+ * return those trusted certificates which satisfy basic
+ * parental checks, such as the matching of child `Issuer`
+ * and parent `Subject` field or matching key identifiers. */
+ ((void) child);
+
+ first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+ if( first == NULL )
+ {
+ ret = -1;
+ goto exit;
+ }
+ mbedtls_x509_crt_init( first );
+
+ if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
+ {
+ ret = -1;
+ goto exit;
+ }
+
+ while( ca->next != NULL )
+ {
+ ca = ca->next;
+ if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
+ {
+ ret = -1;
+ goto exit;
+ }
+ }
+
+exit:
+
+ if( ret != 0 )
+ {
+ mbedtls_x509_crt_free( first );
+ mbedtls_free( first );
+ first = NULL;
+ }
+
+ *candidates = first;
+ return( ret );
+}
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
+int delayed_recv( void *ctx, unsigned char *buf, size_t len )
+{
+ static int first_try = 1;
+ int ret;
+
+ if( first_try )
+ {
+ first_try = 0;
+ return( MBEDTLS_ERR_SSL_WANT_READ );
+ }
+
+ ret = mbedtls_net_recv( ctx, buf, len );
+ if( ret != MBEDTLS_ERR_SSL_WANT_READ )
+ first_try = 1; /* Next call will be a new operation */
+ return( ret );
+}
+
+int delayed_send( void *ctx, const unsigned char *buf, size_t len )
+{
+ static int first_try = 1;
+ int ret;
+
+ if( first_try )
+ {
+ first_try = 0;
+ return( MBEDTLS_ERR_SSL_WANT_WRITE );
+ }
+
+ ret = mbedtls_net_send( ctx, buf, len );
+ if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+ first_try = 1; /* Next call will be a new operation */
+ return( ret );
+}
+
+#if !defined(MBEDTLS_TIMING_C)
+int idle( mbedtls_net_context *fd,
+ int idle_reason )
+#else
+int idle( mbedtls_net_context *fd,
+ mbedtls_timing_delay_context *timer,
+ int idle_reason )
+#endif
+{
+ int ret;
+ int poll_type = 0;
+
+ if( idle_reason == MBEDTLS_ERR_SSL_WANT_WRITE )
+ poll_type = MBEDTLS_NET_POLL_WRITE;
+ else if( idle_reason == MBEDTLS_ERR_SSL_WANT_READ )
+ poll_type = MBEDTLS_NET_POLL_READ;
+#if !defined(MBEDTLS_TIMING_C)
+ else
+ return( 0 );
+#endif
+
+ while( 1 )
+ {
+ /* Check if timer has expired */
+#if defined(MBEDTLS_TIMING_C)
+ if( timer != NULL &&
+ mbedtls_timing_get_delay( timer ) == 2 )
+ {
+ break;
+ }
+#endif /* MBEDTLS_TIMING_C */
+
+ /* Check if underlying transport became available */
+ if( poll_type != 0 )
+ {
+ ret = mbedtls_net_poll( fd, poll_type, 0 );
+ if( ret < 0 )
+ return( ret );
+ if( ret == poll_type )
+ break;
+ }
+ }
+
+ return( 0 );
+}
+
+#endif /* !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE) */
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
new file mode 100644
index 0000000..861e82a
--- /dev/null
+++ b/programs/ssl/ssl_test_lib.h
@@ -0,0 +1,223 @@
+/*
+ * Common code for SSL test programs
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H
+#define MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#define mbedtls_time time
+#define mbedtls_time_t time_t
+#define mbedtls_printf printf
+#define mbedtls_fprintf fprintf
+#define mbedtls_snprintf snprintf
+#define mbedtls_exit exit
+#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
+#endif
+
+#if !defined(MBEDTLS_ENTROPY_C) || \
+ !defined(MBEDTLS_NET_C) || \
+ !defined(MBEDTLS_SSL_TLS_C) || \
+ defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+#define MBEDTLS_SSL_TEST_IMPOSSIBLE \
+ "MBEDTLS_ENTROPY_C and/or " \
+ "MBEDTLS_NET_C and/or " \
+ "MBEDTLS_SSL_TLS_C not defined, " \
+ "and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined.\n"
+#elif !( defined(MBEDTLS_CTR_DRBG_C) || \
+ defined(MBEDTLS_HMAC_DRBG_C) && ( defined(MBEDTLS_SHA256_C) || \
+ defined(MBEDTLS_SHA512_C) ) )
+#define MBEDTLS_SSL_TEST_IMPOSSIBLE \
+ "Neither MBEDTLS_CTR_DRBG_C, nor MBEDTLS_HMAC_DRBG_C and a supported hash defined.\n"
+#else
+#undef MBEDTLS_SSL_TEST_IMPOSSIBLE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mbedtls/net_sockets.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/hmac_drbg.h"
+#include "mbedtls/certs.h"
+#include "mbedtls/x509.h"
+#include "mbedtls/error.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/timing.h"
+#include "mbedtls/base64.h"
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif
+
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#include "mbedtls/memory_buffer_alloc.h"
+#endif
+
+#include <test/helpers.h>
+
+#include "../test/query_config.h"
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+
+typedef struct eap_tls_keys
+{
+ unsigned char master_secret[48];
+ unsigned char randbytes[64];
+ mbedtls_tls_prf_types tls_prf_type;
+} eap_tls_keys;
+
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+
+/* Supported SRTP mode needs a maximum of :
+ * - 16 bytes for key (AES-128)
+ * - 14 bytes SALT
+ * One for sender, one for receiver context
+ */
+#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH 60
+
+typedef struct dtls_srtp_keys
+{
+ unsigned char master_secret[48];
+ unsigned char randbytes[64];
+ mbedtls_tls_prf_types tls_prf_type;
+} dtls_srtp_keys;
+
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
+
+typedef struct
+{
+ mbedtls_ssl_context *ssl;
+ mbedtls_net_context *net;
+} io_ctx_t;
+
+void my_debug( void *ctx, int level,
+ const char *file, int line,
+ const char *str );
+
+mbedtls_time_t dummy_constant_time( mbedtls_time_t* time );
+
+/** A context for random number generation (RNG).
+ */
+typedef struct
+{
+ mbedtls_entropy_context entropy;
+#if defined(MBEDTLS_CTR_DRBG_C)
+ mbedtls_ctr_drbg_context drbg;
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ mbedtls_hmac_drbg_context drbg;
+#else
+#error "No DRBG available"
+#endif
+} rng_context_t;
+
+/** Initialize the RNG.
+ *
+ * This function only initializes the memory used by the RNG context.
+ * Before using the RNG, it must be seeded with rng_seed().
+ */
+void rng_init( rng_context_t *rng );
+
+/* Seed the random number generator.
+ *
+ * \param rng The RNG context to use. It must have been initialized
+ * with rng_init().
+ * \param reproducible If zero, seed the RNG from entropy.
+ * If nonzero, use a fixed seed, so that the program
+ * will produce the same sequence of random numbers
+ * each time it is invoked.
+ * \param pers A null-terminated string. Different values for this
+ * string cause the RNG to emit different output for
+ * the same seed.
+ *
+ * return 0 on success, a negative value on error.
+ */
+int rng_seed( rng_context_t *rng, int reproducible, const char *pers );
+
+/** Deinitialize the RNG. Free any embedded resource.
+ *
+ * \param rng The RNG context to deinitialize. It must have been
+ * initialized with rng_init().
+ */
+void rng_free( rng_context_t *rng );
+
+/** Generate random data.
+ *
+ * This function is suitable for use as the \c f_rng argument to Mbed TLS
+ * library functions.
+ *
+ * \param p_rng The random generator context. This must be a pointer to
+ * a #rng_context_t structure.
+ * \param output The buffer to fill.
+ * \param output_len The length of the buffer in bytes.
+ *
+ * \return \c 0 on success.
+ * \return An Mbed TLS error code on error.
+ */
+int rng_get( void *p_rng, unsigned char *output, size_t output_len );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+/* The test implementation of the PSA external RNG is insecure. When
+ * MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled, before using any PSA crypto
+ * function that makes use of an RNG, you must call
+ * mbedtls_test_enable_insecure_external_rng(). */
+#include <test/fake_external_rng_for_test.h>
+#endif
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+int ca_callback( void *data, mbedtls_x509_crt const *child,
+ mbedtls_x509_crt **candidates );
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
+/*
+ * Test recv/send functions that make sure each try returns
+ * WANT_READ/WANT_WRITE at least once before sucesseding
+ */
+int delayed_recv( void *ctx, unsigned char *buf, size_t len );
+int delayed_send( void *ctx, const unsigned char *buf, size_t len );
+
+/*
+ * Wait for an event from the underlying transport or the timer
+ * (Used in event-driven IO mode).
+ */
+int idle( mbedtls_net_context *fd,
+#if defined(MBEDTLS_TIMING_C)
+ mbedtls_timing_delay_context *timer,
+#endif
+ int idle_reason );
+
+#endif /* MBEDTLS_SSL_TEST_IMPOSSIBLE conditions: else */
+#endif /* MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H */
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 49b44e7..2b1e61e 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -26,7 +26,13 @@
endif()
foreach(exe IN LISTS executables_libs executables_mbedcrypto)
- add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
+ set(extra_sources "")
+ if(exe STREQUAL "query_compile_time_config")
+ list(APPEND extra_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
+ endif()
+ add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>
+ ${extra_sources})
# This emulates "if ( ... IN_LIST ... )" which becomes available in CMake 3.3
list(FIND executables_libs ${exe} exe_index)
@@ -37,9 +43,6 @@
endif()
endforeach()
-set_property(TARGET query_compile_time_config APPEND PROPERTY SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
-
install(TARGETS ${executables_libs} ${executables_mbedcrypto}
DESTINATION "bin"
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/programs/test/cpp_dummy_build.cpp b/programs/test/cpp_dummy_build.cpp
index c69cd2b..5abb46a 100644
--- a/programs/test/cpp_dummy_build.cpp
+++ b/programs/test/cpp_dummy_build.cpp
@@ -111,8 +111,6 @@
#include "psa/crypto.h"
#include "psa/crypto_se_driver.h"
-#include "psa/crypto_entropy_driver.h"
-#include "psa/crypto_accel_driver.h"
#include "../library/psa_crypto_its.h"
int main()
diff --git a/programs/test/query_compile_time_config.c b/programs/test/query_compile_time_config.c
index abe8f76..0e356c8 100644
--- a/programs/test/query_compile_time_config.c
+++ b/programs/test/query_compile_time_config.c
@@ -40,7 +40,7 @@
"Mbed TLS build and the macro expansion of that configuration will be\n" \
"printed (if any). Otherwise, 1 will be returned.\n"
-int query_config( const char *config );
+#include "query_config.h"
int main( int argc, char *argv[] )
{
diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index 1345b11..aae8e2e 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -23,6 +23,8 @@
#include MBEDTLS_CONFIG_FILE
#endif
+#include "query_config.h"
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -1224,6 +1226,14 @@
}
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ if( strcmp( "MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG );
+ return( 0 );
+ }
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
if( strcmp( "MBEDTLS_PSA_CRYPTO_SPM", config ) == 0 )
{
@@ -2608,6 +2618,14 @@
}
#endif /* MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO */
+#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
+ if( strcmp( "MBEDTLS_PSA_HMAC_DRBG_MD_TYPE", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_HMAC_DRBG_MD_TYPE );
+ return( 0 );
+ }
+#endif /* MBEDTLS_PSA_HMAC_DRBG_MD_TYPE */
+
#if defined(MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT)
if( strcmp( "MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT", config ) == 0 )
{
diff --git a/programs/test/query_config.h b/programs/test/query_config.h
new file mode 100644
index 0000000..23009c4
--- /dev/null
+++ b/programs/test/query_config.h
@@ -0,0 +1,42 @@
+/*
+ * Query Mbed TLS compile time configurations from config.h
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_PROGRAMS_TEST_QUERY_CONFIG_H
+#define MBEDTLS_PROGRAMS_TEST_QUERY_CONFIG_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/** Check whether a given configuration symbol is enabled.
+ *
+ * \param config The symbol to query (e.g. "MBEDTLS_RSA_C").
+ * \return \c 0 if the symbol was defined at compile time
+ * (in MBEDTLS_CONFIG_FILE or config.h),
+ * \c 1 otherwise.
+ *
+ * \note This function is defined in `programs/test/query_config.c`
+ * which is automatically generated by
+ * `scripts/generate_query_config.pl`.
+ */
+int query_config( const char *config );
+
+#endif /* MBEDTLS_PROGRAMS_TEST_QUERY_CONFIG_H */
diff --git a/scripts/config.py b/scripts/config.py
index ae0614a..b60f93d 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -185,6 +185,7 @@
'MBEDTLS_PKCS11_C', # build dependency (libpkcs11-helper)
'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature
'MBEDTLS_PSA_CRYPTO_CONFIG', # toggles old/new style PSA config
+ 'MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG', # behavior change + build dependency
'MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER', # incompatible with USE_PSA_CRYPTO
'MBEDTLS_PSA_CRYPTO_SPM', # platform dependency (PSA SPM)
'MBEDTLS_PSA_INJECT_ENTROPY', # build dependency (hook functions)
diff --git a/scripts/data_files/query_config.fmt b/scripts/data_files/query_config.fmt
index be1faef..be541cb 100644
--- a/scripts/data_files/query_config.fmt
+++ b/scripts/data_files/query_config.fmt
@@ -23,6 +23,8 @@
#include MBEDTLS_CONFIG_FILE
#endif
+#include "query_config.h"
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl
index 6c2b5e4..df5d66e 100755
--- a/scripts/generate_visualc_files.pl
+++ b/scripts/generate_visualc_files.pl
@@ -161,6 +161,9 @@
$appname eq "query_compile_time_config" ) {
$srcs .= "\r\n <ClCompile Include=\"..\\..\\programs\\test\\query_config.c\" \/>";
}
+ if( $appname eq "ssl_client2" or $appname eq "ssl_server2" ) {
+ $srcs .= "\r\n <ClCompile Include=\"..\\..\\programs\\ssl\\ssl_test_lib.c\" \/>";
+ }
my $content = $template;
$content =~ s/<SOURCES>/$srcs/g;
diff --git a/tests/Makefile b/tests/Makefile
index 511db9d..d11d904 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -84,8 +84,16 @@
mbedtls_test: $(MBEDTLS_TEST_OBJS)
+TEST_OBJS_DEPS = $(wildcard include/test/*.h include/test/*/*.h)
+ifdef RECORD_PSA_STATUS_COVERAGE_LOG
+# Explicitly depend on this header because on a clean copy of the source tree,
+# it doesn't exist yet and must be generated as part of the build, and
+# therefore the wildcard enumeration above doesn't include it.
+TEST_OBJS_DEPS += include/test/instrument_record_status.h
+endif
+
# Rule to compile common test C files in src folder
-src/%.o : src/%.c
+src/%.o : src/%.c $(TEST_OBJS_DEPS)
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $<
@@ -121,20 +129,15 @@
-o .
-$(BINARIES): %$(EXEXT): %.c $(MBEDLIBS) $(MBEDTLS_TEST_OBJS)
+$(BINARIES): %$(EXEXT): %.c $(MBEDLIBS) $(TEST_OBJS_DEPS) $(MBEDTLS_TEST_OBJS)
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(MBEDTLS_TEST_OBJS) $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-# Some test suites require additional header files.
-$(filter test_suite_psa_crypto%, $(BINARIES)): include/test/psa_crypto_helpers.h
-$(addprefix embedded_,$(filter test_suite_psa_crypto%, $(APPS))): embedded_%: TESTS/mbedtls/%/psa_crypto_helpers.h
-$(filter test_suite_psa_%, $(BINARIES)): include/test/psa_helpers.h
-$(addprefix embedded_,$(filter test_suite_psa_%, $(APPS))): embedded_%: TESTS/mbedtls/%/psa_helpers.h
-
clean:
ifndef WINDOWS
rm -rf $(BINARIES) *.c *.datax TESTS
rm -f src/*.o src/drivers/*.o src/libmbed*
+ rm -f include/test/instrument_record_status.h
else
if exist *.c del /Q /F *.c
if exist *.exe del /Q /F *.exe
@@ -142,6 +145,7 @@
if exist src/*.o del /Q /F src/*.o
if exist src/drivers/*.o del /Q /F src/drivers/*.o
if exist src/libmbed* del /Q /F src/libmed*
+ if exist include/test/instrument_record_status.h del /Q /F include/test/instrument_record_status.h
ifneq ($(wildcard TESTS/.*),)
rmdir /Q /S TESTS
endif
@@ -185,9 +189,10 @@
endef
$(foreach app, $(APPS), $(foreach file, $(notdir $(wildcard include/test/*.h)), \
$(eval $(call copy_header_to_target,$(app),$(file)))))
+$(addprefix embedded_,$(filter test_suite_psa_%, $(APPS))): embedded_%: $(patsubst TESTS/mbedtls/%, include/test/%, $(wildcard include/test/*. include/test/*/*.h))
ifdef RECORD_PSA_STATUS_COVERAGE_LOG
-$(BINARIES): include/test/instrument_record_status.h
include/test/instrument_record_status.h: ../include/psa/crypto.h Makefile
+ echo " Gen $@"
sed <../include/psa/crypto.h >$@ -n 's/^psa_status_t \([A-Za-z0-9_]*\)(.*/#define \1(...) RECORD_STATUS("\1", \1(__VA_ARGS__))/p'
endif
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index bf2f538..0962898 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -208,7 +208,11 @@
$(OPENSSL) x509 -in $< -out $@ -inform PEM -outform DER
all_final += cli-rsa-sha256.crt.der
- cli-rsa.key.der: $(cli_crt_key_file_rsa)
+cli-rsa-sha256-badalg.crt.der: cli-rsa-sha256.crt.der
+ hexdump -ve '1/1 "%.2X"' $< | sed "s/06092A864886F70D01010B0500/06092A864886F70D01010B0900/2" | xxd -r -p > $@
+all_final += cli-rsa-sha256-badalg.crt.der
+
+cli-rsa.key.der: $(cli_crt_key_file_rsa)
$(OPENSSL) pkey -in $< -out $@ -inform PEM -outform DER
all_final += cli-rsa.key.der
@@ -1014,6 +1018,14 @@
$(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
all_final += server1.v1.crt server1.v1.der
+server1.ca.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+ $(MBEDTLS_CERT_WRITE) request_file=server1.req.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 is_ca=1 version=3 output_file=$@
+server1.ca_noauthid.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+ $(MBEDTLS_CERT_WRITE) request_file=server1.req.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20190210144406 not_after=20290210144406 md=SHA1 authority_identifier=0 is_ca=1 version=3 output_file=$@
+server1.ca.der: server1.ca.crt
+ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
+all_final += server1.ca.crt server1.ca_noauthid.crt server1.ca.der
+
server1_ca.crt: server1.crt $(test_ca_crt)
cat server1.crt $(test_ca_crt) > $@
all_final += server1_ca.crt
diff --git a/tests/data_files/cli-rsa-sha256-badalg.crt.der b/tests/data_files/cli-rsa-sha256-badalg.crt.der
new file mode 100644
index 0000000..c40ba2a
--- /dev/null
+++ b/tests/data_files/cli-rsa-sha256-badalg.crt.der
Binary files differ
diff --git a/tests/data_files/server1.ca.crt b/tests/data_files/server1.ca.crt
new file mode 100644
index 0000000..84691d6
--- /dev/null
+++ b/tests/data_files/server1.ca.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDRTCCAi2gAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
+A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
+uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
+d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
+CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
+lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
+bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
+o1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9
+Q1kCpjAfBgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0B
+AQUFAAOCAQEAgt0Fk6cLMjsZUkVpkpTw6EJuKA48H8ieUSTDzYoaDWJQsFY34OIc
+0UpfMwl1jl0qEcVboOdcJHug0EXsfm6XUlSJkPnmcdt/N4gU3/TVkdQwqbvrwjae
+S+Jb1E7fTAiauMi6++svV/sfKqE3OCTJWF+6D0LdgnxEVZM6DvnFU9Jvw+CPTIx6
++SYZLm5sOTL0sWMIxwAEjwGJ3T1m0sjPjnnl4Jn/XtD8UuRRYB/RS6e2TlKovwWP
+G3eUdEs2QJ5lnnD+d7AUYq9nAYnb42M1ZdAxRQxxu2wweiTpUubvT4W6wkG8veix
+UM45EKsxPinnK0rK9bzrPDwpntIHhEUcSQ==
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server1.ca.der b/tests/data_files/server1.ca.der
new file mode 100644
index 0000000..a5ff059
--- /dev/null
+++ b/tests/data_files/server1.ca.der
Binary files differ
diff --git a/tests/data_files/server1.ca_noauthid.crt b/tests/data_files/server1.ca_noauthid.crt
new file mode 100644
index 0000000..e66956d
--- /dev/null
+++ b/tests/data_files/server1.ca_noauthid.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDJDCCAgygAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
+A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
+uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
+d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
+CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
+lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
+bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
+ozIwMDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9
+Q1kCpjANBgkqhkiG9w0BAQUFAAOCAQEAMblPCsjj6RJ8sOm54sdlSJOTGWEo/1LF
+q1bJnKE3FXDeU8pbhEhpfsd2zcKdJxzp7Bg8Ms/xKBuOZhn/4C/n2FwZpEeAsS7J
+tZifKp+GXVs0xbcji9aB8niWXSl/CoICpvHpMAz8k2HT4LDvbC2ElXkqLT7n7k1B
+/ODI3BME34NquyBTDezQb4Gz7bx42OKLrxZkKrO3UF3TQTYBZvlH7IO7SvZhQPGk
+b8a2jKYfeQCCIvcywWQ7qzlgzTgnXJ0RrLyCqOqLFs6ztHPgclHa+XYF5yftSKIS
+zTJLT0IWBtwgB2opv7YSx7tKYhj+uHHY7C3iSXzAgPy5TYkissGXbw==
+-----END CERTIFICATE-----
diff --git a/tests/include/test/fake_external_rng_for_test.h b/tests/include/test/fake_external_rng_for_test.h
new file mode 100644
index 0000000..faeef22
--- /dev/null
+++ b/tests/include/test/fake_external_rng_for_test.h
@@ -0,0 +1,56 @@
+/*
+ * Insecure but standalone implementation of mbedtls_psa_external_get_random().
+ * Only for use in tests!
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FAKE_EXTERNAL_RNG_FOR_TEST_H
+#define FAKE_EXTERNAL_RNG_FOR_TEST_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+/** Enable the insecure implementation of mbedtls_psa_external_get_random().
+ *
+ * The insecure implementation of mbedtls_psa_external_get_random() is
+ * disabled by default.
+ *
+ * When MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled and the test
+ * helpers are linked into a program, you must enable this before running any
+ * code that uses the PSA subsystem to generate random data (including internal
+ * random generation for purposes such as blinding when the random generation
+ * is routed through PSA).
+ *
+ * You can enable and disable it at any time, regardless of the state
+ * of the PSA subsystem. You may disable it temporarily to simulate a
+ * depleted entropy source.
+ */
+void mbedtls_test_enable_insecure_external_rng( void );
+
+/** Disable the insecure implementation of mbedtls_psa_external_get_random().
+ *
+ * See mbedtls_test_enable_insecure_external_rng().
+ */
+void mbedtls_test_disable_insecure_external_rng( void );
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+
+#endif /* FAKE_EXTERNAL_RNG_FOR_TEST_H */
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index 2c7b179..ce8a1e2 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -190,4 +190,8 @@
void mbedtls_test_param_failed_reset_state( void );
#endif /* MBEDTLS_CHECK_PARAMS */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+#include "test/fake_external_rng_for_test.h"
+#endif
+
#endif /* TEST_HELPERS_H */
diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h
index 01b0547..b97263d 100644
--- a/tests/include/test/psa_crypto_helpers.h
+++ b/tests/include/test/psa_crypto_helpers.h
@@ -26,79 +26,48 @@
#include <psa/crypto.h>
#include <psa_crypto_slot_management.h>
-static int test_helper_is_psa_pristine( int line, const char *file )
-{
- mbedtls_psa_stats_t stats;
- const char *msg = NULL;
-
- mbedtls_psa_get_stats( &stats );
-
- if( stats.volatile_slots != 0 )
- msg = "A volatile slot has not been closed properly.";
- else if( stats.persistent_slots != 0 )
- msg = "A persistent slot has not been closed properly.";
- else if( stats.external_slots != 0 )
- msg = "An external slot has not been closed properly.";
- else if( stats.half_filled_slots != 0 )
- msg = "A half-filled slot has not been cleared properly.";
- else if( stats.locked_slots != 0 )
- {
- msg = "Some slots are still marked as locked.";
- }
-
- /* If the test has already failed, don't overwrite the failure
- * information. Do keep the stats lookup above, because it can be
- * convenient to break on it when debugging a failure. */
- if( msg != NULL && test_info.result == TEST_RESULT_SUCCESS )
- test_fail( msg, line, file );
-
- return( msg == NULL );
-}
+/** Check for things that have not been cleaned up properly in the
+ * PSA subsystem.
+ *
+ * \return NULL if nothing has leaked.
+ * \return A string literal explaining what has not been cleaned up
+ * if applicable.
+ */
+const char *mbedtls_test_helper_is_psa_leaking( void );
/** Check that no PSA Crypto key slots are in use.
+ *
+ * If any slots are in use, mark the current test as failed and jump to
+ * the exit label. This is equivalent to
+ * `TEST_ASSERT( ! mbedtls_test_helper_is_psa_leaking( ) )`
+ * but with a more informative message.
*/
-#define ASSERT_PSA_PRISTINE( ) \
- do \
- { \
- if( ! test_helper_is_psa_pristine( __LINE__, __FILE__ ) ) \
- goto exit; \
- } \
+#define ASSERT_PSA_PRISTINE( ) \
+ do \
+ { \
+ if( test_fail_if_psa_leaking( __LINE__, __FILE__ ) ) \
+ goto exit; \
+ } \
while( 0 )
-static void test_helper_psa_done( int line, const char *file )
-{
- (void) test_helper_is_psa_pristine( line, file );
- mbedtls_psa_crypto_free( );
-}
-
/** Shut down the PSA Crypto subsystem. Expect a clean shutdown, with no slots
* in use.
*/
-#define PSA_DONE( ) test_helper_psa_done( __LINE__, __FILE__ )
+#define PSA_DONE( ) \
+ do \
+ { \
+ test_fail_if_psa_leaking( __LINE__, __FILE__ ); \
+ mbedtls_psa_crypto_free( ); \
+ } \
+ while( 0 )
#if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
-#include <psa/crypto.h>
-
-/** Name of the file where return statuses are logged by #RECORD_STATUS. */
-#define STATUS_LOG_FILE_NAME "statuses.log"
-
-static psa_status_t record_status( psa_status_t status,
- const char *func,
- const char *file, int line,
- const char *expr )
-{
- /* We open the log file on first use.
- * We never close the log file, so the record_status feature is not
- * compatible with resource leak detectors such as Asan.
- */
- static FILE *log;
- if( log == NULL )
- log = fopen( STATUS_LOG_FILE_NAME, "a" );
- fprintf( log, "%d:%s:%s:%d:%s\n", (int) status, func, file, line, expr );
- return( status );
-}
+psa_status_t mbedtls_test_record_status( psa_status_t status,
+ const char *func,
+ const char *file, int line,
+ const char *expr );
/** Return value logging wrapper macro.
*
@@ -125,7 +94,7 @@
* \return The value of \p expr.
*/
#define RECORD_STATUS( string, expr ) \
- record_status( ( expr ), string, __FILE__, __LINE__, #expr )
+ mbedtls_test_record_status( ( expr ), string, __FILE__, __LINE__, #expr )
#include "instrument_record_status.h"
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index af59c62..676c804 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -915,18 +915,21 @@
msg "build: Full minus CTR_DRBG"
scripts/config.py full
scripts/config.py unset MBEDTLS_CTR_DRBG_C
- scripts/config.py unset MBEDTLS_PSA_CRYPTO_C # requires CTR_DRBG
- scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C # requires PSA Crypto
- scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C # requires PSA Crypto
- scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO # requires PSA Crypto
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
- msg "test: no CTR_DRBG"
+ msg "test: Full minus CTR_DRBG - main suites"
make test
- # no ssl-opt.sh/compat.sh as they all depend on CTR_DRBG so far
+ # In this configuration, the TLS test programs use HMAC_DRBG.
+ # The SSL tests are slow, so run a small subset, just enough to get
+ # confidence that the SSL code copes with HMAC_DRBG.
+ msg "test: Full minus CTR_DRBG - ssl-opt.sh (subset)"
+ if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private.*delay=\|tickets enabled on server'
+
+ msg "test: Full minus CTR_DRBG - compat.sh (subset)"
+ if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA PSK' -V NO -p OpenSSL
}
component_test_no_hmac_drbg () {
@@ -938,11 +941,52 @@
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
- msg "test: no HMAC_DRBG"
+ msg "test: Full minus HMAC_DRBG - main suites"
make test
- # No ssl-opt.sh/compat.sh as they never use HMAC_DRBG so far,
- # so there's little value in running those lengthy tests here.
+ # Normally our ECDSA implementation uses deterministic ECDSA. But since
+ # HMAC_DRBG is disabled in this configuration, randomized ECDSA is used
+ # instead.
+ # Test SSL with non-deterministic ECDSA. Only test features that
+ # might be affected by how ECDSA signature is performed.
+ msg "test: Full minus HMAC_DRBG - ssl-opt.sh (subset)"
+ if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
+
+ # To save time, only test one protocol version, since this part of
+ # the protocol is identical in (D)TLS up to 1.2.
+ msg "test: Full minus HMAC_DRBG - compat.sh (ECDSA)"
+ if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA'
+}
+
+component_test_psa_external_rng_no_drbg () {
+ msg "build: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG"
+ scripts/config.py full
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+ scripts/config.py unset MBEDTLS_CTR_DRBG_C
+ scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+ scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
+ scripts/config.py set MBEDTLS_ECP_NO_INTERNAL_RNG
+ make CFLAGS="$ASAN_CFLAGS -O2" LDFLAGS="$ASAN_CFLAGS"
+
+ msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG"
+ make test
+
+ # no SSL tests as they all depend on having a DRBG
+}
+
+component_test_psa_external_rng_use_psa_crypto () {
+ msg "build: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
+ scripts/config.py full
+ scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+ scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
+ scripts/config.py unset MBEDTLS_CTR_DRBG_C
+ make CFLAGS="$ASAN_CFLAGS -O2" LDFLAGS="$ASAN_CFLAGS"
+
+ msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
+ make test
+
+ msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG"
+ if_build_succeeded tests/ssl-opt.sh -f 'Default\|opaque'
}
component_test_ecp_no_internal_rng () {
diff --git a/tests/scripts/test_psa_constant_names.py b/tests/scripts/test_psa_constant_names.py
index 5de59c2..4ec98d3 100755
--- a/tests/scripts/test_psa_constant_names.py
+++ b/tests/scripts/test_psa_constant_names.py
@@ -95,8 +95,12 @@
self.dh_groups = set(['0xff'])
self.key_types = set(['0xffff'])
self.key_usage_flags = set(['0x80000000'])
- # Hard-coded value for unknown algorithms
- self.hash_algorithms = set(['0x020000fe'])
+ # Hard-coded values for unknown algorithms
+ #
+ # These have to have values that are correct for their respective
+ # PSA_ALG_IS_xxx macros, but are also not currently assigned and are
+ # not likely to be assigned in the near future.
+ self.hash_algorithms = set(['0x020000fe']) # 0x020000ff is PSA_ALG_ANY_HASH
self.mac_algorithms = set(['0x0300ffff'])
self.ka_algorithms = set(['0x09fc0000'])
self.kdf_algorithms = set(['0x080000ff'])
diff --git a/tests/src/fake_external_rng_for_test.c b/tests/src/fake_external_rng_for_test.c
new file mode 100644
index 0000000..98b3fe0
--- /dev/null
+++ b/tests/src/fake_external_rng_for_test.c
@@ -0,0 +1,56 @@
+/** \file psa_crypto_helpers.c
+ *
+ * \brief Helper functions to test PSA crypto functionality.
+ */
+
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <test/fake_external_rng_for_test.h>
+
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+#include <test/random.h>
+#include <psa/crypto.h>
+
+static int test_insecure_external_rng_enabled = 0;
+
+void mbedtls_test_enable_insecure_external_rng( void )
+{
+ test_insecure_external_rng_enabled = 1;
+}
+
+void mbedtls_test_disable_insecure_external_rng( void )
+{
+ test_insecure_external_rng_enabled = 0;
+}
+
+psa_status_t mbedtls_psa_external_get_random(
+ mbedtls_psa_external_random_context_t *context,
+ uint8_t *output, size_t output_size, size_t *output_length )
+{
+ (void) context;
+
+ if( !test_insecure_external_rng_enabled )
+ return( PSA_ERROR_INSUFFICIENT_ENTROPY );
+
+ /* This implementation is for test purposes only!
+ * Use the libc non-cryptographic random generator. */
+ mbedtls_test_rnd_std_rand( NULL, output, output_size );
+ *output_length = output_size;
+ return( PSA_SUCCESS );
+}
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c
new file mode 100644
index 0000000..cb79a22
--- /dev/null
+++ b/tests/src/psa_crypto_helpers.c
@@ -0,0 +1,72 @@
+/** \file psa_crypto_helpers.c
+ *
+ * \brief Helper functions to test PSA crypto functionality.
+ */
+
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <test/helpers.h>
+#include <test/macros.h>
+#include <test/psa_crypto_helpers.h>
+
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+
+#include <psa/crypto.h>
+
+const char *mbedtls_test_helper_is_psa_leaking( void )
+{
+ mbedtls_psa_stats_t stats;
+
+ mbedtls_psa_get_stats( &stats );
+
+ if( stats.volatile_slots != 0 )
+ return( "A volatile slot has not been closed properly." );
+ if( stats.persistent_slots != 0 )
+ return( "A persistent slot has not been closed properly." );
+ if( stats.external_slots != 0 )
+ return( "An external slot has not been closed properly." );
+ if( stats.half_filled_slots != 0 )
+ return( "A half-filled slot has not been cleared properly." );
+ if( stats.locked_slots != 0 )
+ return( "Some slots are still marked as locked." );
+
+ return( NULL );
+}
+
+#if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
+/** Name of the file where return statuses are logged by #RECORD_STATUS. */
+#define STATUS_LOG_FILE_NAME "statuses.log"
+
+psa_status_t mbedtls_test_record_status( psa_status_t status,
+ const char *func,
+ const char *file, int line,
+ const char *expr )
+{
+ /* We open the log file on first use.
+ * We never close the log file, so the record_status feature is not
+ * compatible with resource leak detectors such as Asan.
+ */
+ static FILE *log;
+ if( log == NULL )
+ log = fopen( STATUS_LOG_FILE_NAME, "a" );
+ fprintf( log, "%d:%s:%s:%d:%s\n", (int) status, func, file, line, expr );
+ return( status );
+}
+#endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */
+
+#endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index aafcf5c..1dc6721 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -5,6 +5,9 @@
#include <test/macros.h>
#include <test/helpers.h>
#include <test/random.h>
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+#include <test/psa_crypto_helpers.h>
+#endif
#include <stdlib.h>
@@ -418,6 +421,26 @@
test_info.filename = filename;
}
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+/** Check that no PSA Crypto key slots are in use.
+ *
+ * If any slots are in use, mark the current test as failed.
+ *
+ * \return 0 if the key store is empty, 1 otherwise.
+ */
+int test_fail_if_psa_leaking( int line_no, const char *filename )
+{
+ const char *msg = mbedtls_test_helper_is_psa_leaking( );
+ if( msg == NULL )
+ return 0;
+ else
+ {
+ test_fail( msg, line_no, filename );
+ return 1;
+ }
+}
+#endif /* defined(MBEDTLS_PSA_CRYPTO_C) */
+
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
static int redirect_output( FILE* out_stream, const char* path )
{
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 256224e..98dab3e 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -164,6 +164,10 @@
*/
void execute_function_ptr(TestWrapper_t fp, void **params)
{
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ mbedtls_test_enable_insecure_external_rng( );
+#endif
+
#if defined(MBEDTLS_CHECK_PARAMS)
mbedtls_test_param_failed_location_record_t location_record;
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index ea1e9ad..76e474f 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -9,10 +9,65 @@
#include "mbedtls/gcm.h"
#endif
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-#include "test/psa_crypto_helpers.h"
+#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
+#define MBEDTLS_CIPHER_AUTH_CRYPT
#endif
+#if defined(MBEDTLS_CIPHER_AUTH_CRYPT)
+/* Helper for resetting key/direction
+ *
+ * The documentation doesn't explicitly say whether calling
+ * mbedtls_cipher_setkey() twice is allowed or not. This currently works with
+ * the default software implementation, but only by accident. It isn't
+ * guaranteed to work with new ciphers or with alternative implementations of
+ * individual ciphers, and it doesn't work with the PSA wrappers. So don't do
+ * it, and instead start with a fresh context.
+ */
+static int cipher_reset_key( mbedtls_cipher_context_t *ctx, int cipher_id,
+ int use_psa, size_t tag_len, const data_t *key, int direction )
+{
+ mbedtls_cipher_free( ctx );
+ mbedtls_cipher_init( ctx );
+
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
+ (void) use_psa;
+ (void) tag_len;
+#else
+ if( use_psa == 1 )
+ {
+ TEST_ASSERT( 0 == mbedtls_cipher_setup_psa( ctx,
+ mbedtls_cipher_info_from_type( cipher_id ),
+ tag_len ) );
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+ TEST_ASSERT( 0 == mbedtls_cipher_setup( ctx,
+ mbedtls_cipher_info_from_type( cipher_id ) ) );
+ }
+
+ TEST_ASSERT( 0 == mbedtls_cipher_setkey( ctx, key->x, 8 * key->len,
+ direction ) );
+ return( 1 );
+
+exit:
+ return( 0 );
+}
+
+/*
+ * Check if a buffer is all-0 bytes:
+ * return 1 if it is,
+ * 0 if it isn't.
+ */
+int buffer_is_all_zero( const uint8_t *buf, size_t size )
+{
+ for( size_t i = 0; i < size; i++ )
+ if( buf[i] != 0 )
+ return 0;
+ return 1;
+}
+#endif /* MBEDTLS_CIPHER_AUTH_CRYPT */
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -485,6 +540,108 @@
NULL, valid_size ) );
#endif /* defined(MBEDTLS_CIPHER_MODE_AEAD) */
+#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
+ /* mbedtls_cipher_auth_encrypt_ext */
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_encrypt_ext( NULL,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_encrypt_ext( &valid_ctx,
+ NULL, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_encrypt_ext( &valid_ctx,
+ valid_buffer, valid_size,
+ NULL, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_encrypt_ext( &valid_ctx,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ NULL, valid_size,
+ valid_buffer, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_encrypt_ext( &valid_ctx,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ NULL, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_encrypt_ext( &valid_ctx,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size, NULL,
+ valid_size ) );
+
+ /* mbedtls_cipher_auth_decrypt_ext */
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_decrypt_ext( NULL,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_decrypt_ext( &valid_ctx,
+ NULL, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_decrypt_ext( &valid_ctx,
+ valid_buffer, valid_size,
+ NULL, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_decrypt_ext( &valid_ctx,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ NULL, valid_size,
+ valid_buffer, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_decrypt_ext( &valid_ctx,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ NULL, valid_size, &size_t_var,
+ valid_size ) );
+ TEST_INVALID_PARAM_RET(
+ MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA,
+ mbedtls_cipher_auth_decrypt_ext( &valid_ctx,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size,
+ valid_buffer, valid_size, NULL,
+ valid_size ) );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
+
/* mbedtls_cipher_free() */
TEST_VALID_PARAM( mbedtls_cipher_free( NULL ) );
exit:
@@ -959,129 +1116,338 @@
}
/* END_CASE */
-/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_AEAD */
+/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_AUTH_CRYPT */
void auth_crypt_tv( int cipher_id, data_t * key, data_t * iv,
data_t * ad, data_t * cipher, data_t * tag,
char * result, data_t * clear, int use_psa )
{
- /* Takes an AEAD ciphertext + tag and performs a pair
- * of AEAD decryption and AEAD encryption. It checks that
+ /*
+ * Take an AEAD ciphertext + tag and perform a pair
+ * of AEAD decryption and AEAD encryption. Check that
* this results in the expected plaintext, and that
- * decryption and encryption are inverse to one another. */
+ * decryption and encryption are inverse to one another.
+ *
+ * Do that twice:
+ * - once with legacy functions auth_decrypt/auth_encrypt
+ * - once with new functions auth_decrypt_ext/auth_encrypt_ext
+ * This allows testing both without duplicating test cases.
+ */
int ret;
- unsigned char output[300]; /* Temporary buffer for results of
- * encryption and decryption. */
- unsigned char *output_tag = NULL; /* Temporary buffer for tag in the
- * encryption step. */
+ int using_nist_kw, using_nist_kw_padding;
mbedtls_cipher_context_t ctx;
size_t outlen;
+ unsigned char *cipher_plus_tag = NULL;
+ size_t cipher_plus_tag_len;
+ unsigned char *decrypt_buf = NULL;
+ size_t decrypt_buf_len = 0;
+ unsigned char *encrypt_buf = NULL;
+ size_t encrypt_buf_len = 0;
+
+#if !defined(MBEDTLS_DEPRECATED_WARNING) && \
+ !defined(MBEDTLS_DEPRECATED_REMOVED)
unsigned char *tmp_tag = NULL;
unsigned char *tmp_cipher = NULL;
+ unsigned char *tag_buf = NULL;
+#endif /* !MBEDTLS_DEPRECATED_WARNING && !MBEDTLS_DEPRECATED_REMOVED */
+
+ /* Null pointers are documented as valid for inputs of length 0.
+ * The test framework passes non-null pointers, so set them to NULL.
+ * key, cipher and tag can't be empty. */
+ if( iv->len == 0 )
+ iv->x = NULL;
+ if( ad->len == 0 )
+ ad->x = NULL;
+ if( clear->len == 0 )
+ clear->x = NULL;
mbedtls_cipher_init( &ctx );
- memset( output, 0xFF, sizeof( output ) );
- /* Prepare context */
-#if !defined(MBEDTLS_USE_PSA_CRYPTO)
- (void) use_psa;
-#else
+ /* Initialize PSA Crypto */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( use_psa == 1 )
- {
PSA_ASSERT( psa_crypto_init( ) );
-
- /* PSA requires that the tag immediately follows the ciphertext. */
- tmp_cipher = mbedtls_calloc( 1, cipher->len + tag->len );
- TEST_ASSERT( tmp_cipher != NULL );
- tmp_tag = tmp_cipher + cipher->len;
-
- memcpy( tmp_cipher, cipher->x, cipher->len );
- memcpy( tmp_tag, tag->x, tag->len );
-
- TEST_ASSERT( 0 == mbedtls_cipher_setup_psa( &ctx,
- mbedtls_cipher_info_from_type( cipher_id ),
- tag->len ) );
- }
- else
+#else
+ (void) use_psa;
#endif
+
+ /*
+ * Are we using NIST_KW? with padding?
+ */
+ using_nist_kw_padding = cipher_id == MBEDTLS_CIPHER_AES_128_KWP ||
+ cipher_id == MBEDTLS_CIPHER_AES_192_KWP ||
+ cipher_id == MBEDTLS_CIPHER_AES_256_KWP;
+ using_nist_kw = cipher_id == MBEDTLS_CIPHER_AES_128_KW ||
+ cipher_id == MBEDTLS_CIPHER_AES_192_KW ||
+ cipher_id == MBEDTLS_CIPHER_AES_256_KW ||
+ using_nist_kw_padding;
+
+ /****************************************************************
+ * *
+ * Part 1: non-deprecated API *
+ * *
+ ****************************************************************/
+
+ /*
+ * Prepare context for decryption
+ */
+ if( ! cipher_reset_key( &ctx, cipher_id, use_psa, tag->len, key,
+ MBEDTLS_DECRYPT ) )
+ goto exit;
+
+ /*
+ * prepare buffer for decryption
+ * (we need the tag appended to the ciphertext)
+ */
+ cipher_plus_tag_len = cipher->len + tag->len;
+ ASSERT_ALLOC( cipher_plus_tag, cipher_plus_tag_len );
+ memcpy( cipher_plus_tag, cipher->x, cipher->len );
+ memcpy( cipher_plus_tag + cipher->len, tag->x, tag->len );
+
+ /*
+ * Compute length of output buffer according to the documentation
+ */
+ if( using_nist_kw )
+ decrypt_buf_len = cipher_plus_tag_len - 8;
+ else
+ decrypt_buf_len = cipher_plus_tag_len - tag->len;
+
+
+ /*
+ * Try decrypting to a buffer that's 1B too small
+ */
+ if( decrypt_buf_len != 0 )
{
- tmp_tag = tag->x;
- tmp_cipher = cipher->x;
- TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx,
- mbedtls_cipher_info_from_type( cipher_id ) ) );
+ ASSERT_ALLOC( decrypt_buf, decrypt_buf_len - 1 );
+
+ outlen = 0;
+ ret = mbedtls_cipher_auth_decrypt_ext( &ctx, iv->x, iv->len,
+ ad->x, ad->len, cipher_plus_tag, cipher_plus_tag_len,
+ decrypt_buf, decrypt_buf_len - 1, &outlen, tag->len );
+ TEST_ASSERT( ret == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ mbedtls_free( decrypt_buf );
+ decrypt_buf = NULL;
}
- TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key->x, 8 * key->len,
- MBEDTLS_DECRYPT ) );
+ /*
+ * Authenticate and decrypt, and check result
+ */
+ ASSERT_ALLOC( decrypt_buf, decrypt_buf_len );
- /* decode buffer and check tag->x */
+ outlen = 0;
+ ret = mbedtls_cipher_auth_decrypt_ext( &ctx, iv->x, iv->len,
+ ad->x, ad->len, cipher_plus_tag, cipher_plus_tag_len,
+ decrypt_buf, decrypt_buf_len, &outlen, tag->len );
- /* Sanity check that we don't use overly long inputs. */
- TEST_ASSERT( sizeof( output ) >= cipher->len );
-
- ret = mbedtls_cipher_auth_decrypt( &ctx, iv->x, iv->len, ad->x, ad->len,
- tmp_cipher, cipher->len, output, &outlen,
- tmp_tag, tag->len );
-
- /* make sure the message is rejected if it should be */
if( strcmp( result, "FAIL" ) == 0 )
{
TEST_ASSERT( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED );
- goto exit;
+ TEST_ASSERT( buffer_is_all_zero( decrypt_buf, decrypt_buf_len ) );
+ }
+ else
+ {
+ TEST_ASSERT( ret == 0 );
+ ASSERT_COMPARE( decrypt_buf, outlen, clear->x, clear->len );
}
- /* otherwise, make sure it was decrypted properly */
- TEST_ASSERT( ret == 0 );
+ /* Free this, but keep cipher_plus_tag for deprecated function with PSA */
+ mbedtls_free( decrypt_buf );
+ decrypt_buf = NULL;
- TEST_ASSERT( outlen == clear->len );
- TEST_ASSERT( memcmp( output, clear->x, clear->len ) == 0 );
+ /*
+ * Encrypt back if test data was authentic
+ */
+ if( strcmp( result, "FAIL" ) != 0 )
+ {
+ /* prepare context for encryption */
+ if( ! cipher_reset_key( &ctx, cipher_id, use_psa, tag->len, key,
+ MBEDTLS_ENCRYPT ) )
+ goto exit;
- /* then encrypt the clear->x and make sure we get the same ciphertext and tag->x */
- mbedtls_cipher_free( &ctx );
+ /*
+ * Compute size of output buffer according to documentation
+ */
+ if( using_nist_kw )
+ {
+ encrypt_buf_len = clear->len + 8;
+ if( using_nist_kw_padding && encrypt_buf_len % 8 != 0 )
+ encrypt_buf_len += 8 - encrypt_buf_len % 8;
+ }
+ else
+ {
+ encrypt_buf_len = clear->len + tag->len;
+ }
+
+ /*
+ * Try encrypting with an output buffer that's 1B too small
+ */
+ ASSERT_ALLOC( encrypt_buf, encrypt_buf_len - 1 );
+
+ outlen = 0;
+ ret = mbedtls_cipher_auth_encrypt_ext( &ctx, iv->x, iv->len,
+ ad->x, ad->len, clear->x, clear->len,
+ encrypt_buf, encrypt_buf_len - 1, &outlen, tag->len );
+ TEST_ASSERT( ret != 0 );
+
+ mbedtls_free( encrypt_buf );
+ encrypt_buf = NULL;
+
+ /*
+ * Encrypt and check the result
+ */
+ ASSERT_ALLOC( encrypt_buf, encrypt_buf_len );
+
+ outlen = 0;
+ ret = mbedtls_cipher_auth_encrypt_ext( &ctx, iv->x, iv->len,
+ ad->x, ad->len, clear->x, clear->len,
+ encrypt_buf, encrypt_buf_len, &outlen, tag->len );
+ TEST_ASSERT( ret == 0 );
+
+ TEST_ASSERT( outlen == cipher->len + tag->len );
+ TEST_ASSERT( memcmp( encrypt_buf, cipher->x, cipher->len ) == 0 );
+ TEST_ASSERT( memcmp( encrypt_buf + cipher->len,
+ tag->x, tag->len ) == 0 );
+
+ mbedtls_free( encrypt_buf );
+ encrypt_buf = NULL;
+ }
+
+ /****************************************************************
+ * *
+ * Part 2: deprecated API *
+ * *
+ ****************************************************************/
+
+#if !defined(MBEDTLS_DEPRECATED_WARNING) && \
+ !defined(MBEDTLS_DEPRECATED_REMOVED)
+
+ /*
+ * Prepare context for decryption
+ */
+ if( ! cipher_reset_key( &ctx, cipher_id, use_psa, tag->len, key,
+ MBEDTLS_DECRYPT ) )
+ goto exit;
+
+ /*
+ * Prepare pointers for decryption
+ */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( use_psa == 1 )
{
- TEST_ASSERT( 0 == mbedtls_cipher_setup_psa( &ctx,
- mbedtls_cipher_info_from_type( cipher_id ),
- tag->len ) );
+ /* PSA requires that the tag immediately follows the ciphertext.
+ * Fortunately, we already have that from testing the new API. */
+ tmp_cipher = cipher_plus_tag;
+ tmp_tag = tmp_cipher + cipher->len;
}
else
-#endif
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
{
- TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx,
- mbedtls_cipher_info_from_type( cipher_id ) ) );
+ tmp_cipher = cipher->x;
+ tmp_tag = tag->x;
}
- TEST_ASSERT( 0 == mbedtls_cipher_setkey( &ctx, key->x, 8 * key->len,
- MBEDTLS_ENCRYPT ) );
- memset( output, 0xFF, sizeof( output ) );
+ /*
+ * Authenticate and decrypt, and check result
+ */
+
+ ASSERT_ALLOC( decrypt_buf, cipher->len );
outlen = 0;
+ ret = mbedtls_cipher_auth_decrypt( &ctx, iv->x, iv->len, ad->x, ad->len,
+ tmp_cipher, cipher->len, decrypt_buf, &outlen,
+ tmp_tag, tag->len );
- /* Sanity check that we don't use overly long inputs. */
- TEST_ASSERT( sizeof( output ) >= clear->len + tag->len );
+ if( using_nist_kw )
+ {
+ /* NIST_KW with legacy API */
+ TEST_ASSERT( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+ else if( strcmp( result, "FAIL" ) == 0 )
+ {
+ /* unauthentic message */
+ TEST_ASSERT( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+ TEST_ASSERT( buffer_is_all_zero( decrypt_buf, cipher->len ) );
+ }
+ else
+ {
+ /* authentic message: is the plaintext correct? */
+ TEST_ASSERT( ret == 0 );
+ ASSERT_COMPARE( decrypt_buf, outlen, clear->x, clear->len );
+ }
- output_tag = output + clear->len;
- ret = mbedtls_cipher_auth_encrypt( &ctx, iv->x, iv->len, ad->x, ad->len,
- clear->x, clear->len, output, &outlen,
- output_tag, tag->len );
- TEST_ASSERT( ret == 0 );
+ mbedtls_free( decrypt_buf );
+ decrypt_buf = NULL;
+ mbedtls_free( cipher_plus_tag );
+ cipher_plus_tag = NULL;
- TEST_ASSERT( outlen == cipher->len );
- TEST_ASSERT( memcmp( output, cipher->x, cipher->len ) == 0 );
- TEST_ASSERT( memcmp( output_tag, tag->x, tag->len ) == 0 );
+ /*
+ * Encrypt back if test data was authentic
+ */
+ if( strcmp( result, "FAIL" ) != 0 )
+ {
+ /* prepare context for encryption */
+ if( ! cipher_reset_key( &ctx, cipher_id, use_psa, tag->len, key,
+ MBEDTLS_ENCRYPT ) )
+ goto exit;
+
+ /* prepare buffers for encryption */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( use_psa )
+ {
+ ASSERT_ALLOC( cipher_plus_tag, cipher->len + tag->len );
+ tmp_cipher = cipher_plus_tag;
+ tmp_tag = cipher_plus_tag + cipher->len;
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+ ASSERT_ALLOC( encrypt_buf, cipher->len );
+ ASSERT_ALLOC( tag_buf, tag->len );
+ tmp_cipher = encrypt_buf;
+ tmp_tag = tag_buf;
+ }
+
+ /*
+ * Encrypt and check the result
+ */
+ outlen = 0;
+ ret = mbedtls_cipher_auth_encrypt( &ctx, iv->x, iv->len, ad->x, ad->len,
+ clear->x, clear->len, tmp_cipher, &outlen,
+ tmp_tag, tag->len );
+
+ if( using_nist_kw )
+ {
+ TEST_ASSERT( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+ else
+ {
+ TEST_ASSERT( ret == 0 );
+
+ TEST_ASSERT( outlen == cipher->len );
+ if( cipher->len != 0 )
+ TEST_ASSERT( memcmp( tmp_cipher, cipher->x, cipher->len ) == 0 );
+ TEST_ASSERT( memcmp( tmp_tag, tag->x, tag->len ) == 0 );
+ }
+ }
+
+#endif /* !MBEDTLS_DEPRECATED_WARNING && !MBEDTLS_DEPRECATED_REMOVED */
exit:
mbedtls_cipher_free( &ctx );
+ mbedtls_free( decrypt_buf );
+ mbedtls_free( encrypt_buf );
+ mbedtls_free( cipher_plus_tag );
+#if !defined(MBEDTLS_DEPRECATED_WARNING) && \
+ !defined(MBEDTLS_DEPRECATED_REMOVED)
+ mbedtls_free( tag_buf );
+#endif /* !MBEDTLS_DEPRECATED_WARNING && !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( use_psa == 1 )
- {
- mbedtls_free( tmp_cipher );
PSA_DONE( );
- }
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
/* END_CASE */
diff --git a/tests/suites/test_suite_dhm.data b/tests/suites/test_suite_dhm.data
index 4e884f4..c4795b6 100644
--- a/tests/suites/test_suite_dhm.data
+++ b/tests/suites/test_suite_dhm.data
@@ -22,6 +22,12 @@
Diffie-Hellman zero modulus
dhm_do_dhm:10:"0":10:"5":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+Diffie-Hellman MPI_MAX_SIZE modulus
+dhm_make_public:MBEDTLS_MPI_MAX_SIZE:10:"5":0
+
+Diffie-Hellman MPI_MAX_SIZE + 1 modulus
+dhm_make_public:MBEDTLS_MPI_MAX_SIZE + 1:10:"5":MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED+MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
Diffie-Hellman load parameters from file [#1]
dhm_file:"data_files/dhparams.pem":"9e35f430443a09904f3a39a979797d070df53378e79c2438bef4e761f3c714553328589b041c809be1d6c6b5f1fc9f47d3a25443188253a992a56818b37ba9de5a40d362e56eff0be5417474c125c199272c8fe41dea733df6f662c92ae76556e755d10c64e6a50968f67fc6ea73d0dca8569be2ba204e23580d8bca2f4975b3":"02":128
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index 0a5c617..1726b9e 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -223,6 +223,36 @@
}
/* END_CASE */
+/* BEGIN_CASE */
+void dhm_make_public( int P_bytes, int radix_G, char *input_G, int result )
+{
+ mbedtls_mpi P, G;
+ mbedtls_dhm_context ctx;
+ unsigned char output[MBEDTLS_MPI_MAX_SIZE];
+
+ mbedtls_mpi_init( &P );
+ mbedtls_mpi_init( &G );
+ mbedtls_dhm_init( &ctx );
+
+ TEST_ASSERT( mbedtls_mpi_lset( &P, 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_shift_l( &P, ( P_bytes * 8 ) - 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_set_bit( &P, 0, 1 ) == 0 );
+
+ TEST_ASSERT( mbedtls_mpi_read_string( &G, radix_G, input_G ) == 0 );
+
+ TEST_ASSERT( mbedtls_dhm_set_group( &ctx, &P, &G ) == 0 );
+ TEST_ASSERT( mbedtls_dhm_make_public( &ctx, (int) mbedtls_mpi_size( &P ),
+ output, sizeof(output),
+ &mbedtls_test_rnd_pseudo_rand,
+ NULL ) == result );
+
+exit:
+ mbedtls_mpi_free( &P );
+ mbedtls_mpi_free( &G );
+ mbedtls_dhm_free( &ctx );
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
void dhm_file( char * filename, char * p, char * g, int len )
{
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 212c2f3..0966393 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -685,16 +685,36 @@
Base test mbedtls_mpi_exp_mod #5 (Negative exponent)
mbedtls_mpi_exp_mod:10:"23":10:"-13":10:"29":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
-Base test mbedtls_mpi_exp_mod #7 (Negative base + exponent)
+Base test mbedtls_mpi_exp_mod #6 (Negative base + exponent)
mbedtls_mpi_exp_mod:10:"-23":10:"-13":10:"29":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+Test mbedtls_mpi_exp_mod: MAX_SIZE exponent
+mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE:10:10:"":0
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE + 1 exponent
+mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE + 1:10:10:"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE modulus
+mbedtls_mpi_exp_mod_size:2:2:MBEDTLS_MPI_MAX_SIZE:10:"":0
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE + 1 modulus
+mbedtls_mpi_exp_mod_size:2:2:MBEDTLS_MPI_MAX_SIZE + 1:10:"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE exponent and modulus
+mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE:10:"":0
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE + 1 exponent and modulus
+mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE + 1:MBEDTLS_MPI_MAX_SIZE + 1:10:"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
Test mbedtls_mpi_exp_mod #1
+depends_on:MPI_MAX_BITS_LARGER_THAN_792
mbedtls_mpi_exp_mod:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"583137007797276923956891216216022144052044091311388601652961409557516421612874571554415606746479105795833145583959622117418531166391184939066520869800857530421873250114773204354963864729386957427276448683092491947566992077136553066273207777134303397724679138833126700957":10:"":10:"114597449276684355144920670007147953232659436380163461553186940113929777196018164149703566472936578890991049344459204199888254907113495794730452699842273939581048142004834330369483813876618772578869083248061616444392091693787039636316845512292127097865026290173004860736":0
Test mbedtls_mpi_exp_mod (Negative base) [#1]
mbedtls_mpi_exp_mod:10:"-10000000000":10:"10000000000":10:"99999":10:"":10:"1":0
Test mbedtls_mpi_exp_mod (Negative base) [#2]
+depends_on:MPI_MAX_BITS_LARGER_THAN_792
mbedtls_mpi_exp_mod:16:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":16:"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":16:"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":16:"":16:"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0
Base test GCD #1
@@ -935,6 +955,48 @@
Test bit set (Invalid bit value)
mbedtls_mpi_set_bit:16:"00":5:2:16:"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+Fill random: 0 bytes
+mpi_fill_random:0:0:0
+
+Fill random: 1 byte, good
+mpi_fill_random:1:1:0
+
+Fill random: 2 bytes, good, no leading zero
+mpi_fill_random:2:2:0
+
+Fill random: 2 bytes, good, 1 leading zero
+mpi_fill_random:2:256:0
+
+Fill random: MAX_SIZE - 7, good
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE - 7:MBEDTLS_MPI_MAX_SIZE - 7:0
+
+Fill random: MAX_SIZE, good
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE:0
+
+Fill random: 1 byte, RNG failure
+mpi_fill_random:1:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 2 bytes, RNG failure after 1 byte
+mpi_fill_random:2:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 4 bytes, RNG failure after 3 bytes
+mpi_fill_random:4:3:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 8 bytes, RNG failure after 7 bytes
+mpi_fill_random:8:7:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 16 bytes, RNG failure after 1 bytes
+mpi_fill_random:16:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 16 bytes, RNG failure after 8 bytes
+mpi_fill_random:16:8:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 16 bytes, RNG failure after 15 bytes
+mpi_fill_random:16:15:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: MAX_SIZE bytes, RNG failure after MAX_SIZE-1 bytes
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE-1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
MPI Selftest
depends_on:MBEDTLS_SELF_TEST
mpi_selftest:
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index 8436742..c5bb5a6 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -1,5 +1,10 @@
/* BEGIN_HEADER */
#include "mbedtls/bignum.h"
+#include "mbedtls/entropy.h"
+
+#if MBEDTLS_MPI_MAX_BITS > 792
+#define MPI_MAX_BITS_LARGER_THAN_792
+#endif
typedef struct mbedtls_test_mpi_random
{
@@ -43,6 +48,22 @@
return( 0 );
}
+
+/* Random generator that is told how many bytes to return. */
+static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
+{
+ size_t *bytes_left = state;
+ size_t i;
+ for( i = 0; i < len; i++ )
+ {
+ if( *bytes_left == 0 )
+ return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+ buf[i] = *bytes_left & 0xff;
+ --( *bytes_left );
+ }
+ return( 0 );
+}
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -1167,6 +1188,40 @@
/* END_CASE */
/* BEGIN_CASE */
+void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
+ int radix_RR, char * input_RR, int exp_result )
+{
+ mbedtls_mpi A, E, N, RR, Z;
+ mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
+ mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
+
+ /* Set A to 2^(A_bytes - 1) + 1 */
+ TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
+
+ /* Set E to 2^(E_bytes - 1) + 1 */
+ TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
+
+ /* Set N to 2^(N_bytes - 1) + 1 */
+ TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
+
+ if( strlen( input_RR ) )
+ TEST_ASSERT( mbedtls_mpi_read_string( &RR, radix_RR, input_RR ) == 0 );
+
+ TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
+
+exit:
+ mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
+ mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mbedtls_mpi_inv_mod( int radix_X, char * input_X, int radix_Y,
char * input_Y, int radix_A, char * input_A,
int div_result )
@@ -1310,6 +1365,37 @@
}
/* END_CASE */
+/* BEGIN_CASE */
+void mpi_fill_random( int wanted_bytes, int rng_bytes, int expected_ret )
+{
+ mbedtls_mpi X;
+ int ret;
+ size_t bytes_left = rng_bytes;
+ mbedtls_mpi_init( &X );
+
+ ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
+ f_rng_bytes_left, &bytes_left );
+ TEST_ASSERT( ret == expected_ret );
+
+ if( expected_ret == 0 )
+ {
+ /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
+ * as a big-endian representation of the number. We know when
+ * our RNG function returns null bytes, so we know how many
+ * leading zero bytes the number has. */
+ size_t leading_zeros = 0;
+ if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
+ leading_zeros = 1;
+ TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
+ (size_t) wanted_bytes );
+ TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
+ }
+
+exit:
+ mbedtls_mpi_free( &X );
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void mpi_selftest( )
{
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 98016c6..577fb47 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -17,13 +17,13 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "mbedtls/psa_util.h"
-#include "test/psa_crypto_helpers.h"
#define PSA_INIT( ) PSA_ASSERT( psa_crypto_init( ) )
#else
/* Define empty macros so that we can use them in the preamble and teardown
* of every test function that uses PSA conditionally based on
* MBEDTLS_USE_PSA_CRYPTO. */
#define PSA_INIT( ) ( (void) 0 )
+#undef PSA_DONE
#define PSA_DONE( ) ( (void) 0 )
#endif
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 8e71610..7c1cbcb 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -9,8 +9,6 @@
* uses mbedtls_ctr_drbg internally. */
#include "mbedtls/ctr_drbg.h"
-#include "test/psa_crypto_helpers.h"
-
/* Tests that require more than 128kB of RAM plus change have this symbol
* as a dependency. Currently we always define this symbol, so the tests
* are always executed. In the future we should make this conditional
@@ -287,7 +285,7 @@
TEST_ASSERT( bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS );
else if( PSA_KEY_TYPE_IS_RSA( type ) )
TEST_ASSERT( bits <= PSA_VENDOR_RSA_MAX_KEY_BITS );
- TEST_ASSERT( PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) <= PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE );
+ TEST_ASSERT( PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE );
ok = 1;
@@ -447,7 +445,7 @@
PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
/* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
* have this macro yet. */
- iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE(
+ iv_length = PSA_BLOCK_CIPHER_BLOCK_LENGTH(
psa_get_key_type( &attributes ) );
maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
psa_reset_key_attributes( &attributes );
@@ -550,7 +548,7 @@
* the hash encoded in the algorithm. Use this input size
* even for algorithms that allow other input sizes. */
if( hash_alg != 0 )
- payload_length = PSA_HASH_SIZE( hash_alg );
+ payload_length = PSA_HASH_LENGTH( hash_alg );
PSA_ASSERT( psa_sign_hash( key, alg,
payload, payload_length,
signature, sizeof( signature ),
@@ -714,7 +712,7 @@
private_key_type = psa_get_key_type( &attributes );
key_bits = psa_get_key_bits( &attributes );
public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
- public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
+ public_key_length = PSA_EXPORT_KEY_OUTPUT_SIZE( public_key_type, key_bits );
ASSERT_ALLOC( public_key, public_key_length );
PSA_ASSERT( psa_export_public_key( key, public_key, public_key_length,
&public_key_length ) );
@@ -755,7 +753,7 @@
private_key_type = psa_get_key_type( &attributes );
key_bits = psa_get_key_bits( &attributes );
public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
- public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
+ public_key_length = PSA_EXPORT_KEY_OUTPUT_SIZE( public_key_type, key_bits );
ASSERT_ALLOC( public_key, public_key_length );
PSA_ASSERT( psa_export_public_key( key,
public_key, public_key_length,
@@ -868,7 +866,7 @@
if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
else
- TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
+ TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE( type, bits ) );
#if defined(MBEDTLS_DES_C)
if( type == PSA_KEY_TYPE_DES )
@@ -1037,8 +1035,8 @@
goto exit;
}
- exported_size = PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( &attributes ),
- psa_get_key_bits( &attributes ) );
+ exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE( psa_get_key_type( &attributes ),
+ psa_get_key_bits( &attributes ) );
ASSERT_ALLOC( exported, exported_size );
PSA_ASSERT( psa_export_key( key,
@@ -1078,8 +1076,8 @@
public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
psa_get_key_type( &attributes ) );
- exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type,
- psa_get_key_bits( &attributes ) );
+ exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE( public_type,
+ psa_get_key_bits( &attributes ) );
ASSERT_ALLOC( exported, exported_size );
PSA_ASSERT( psa_export_public_key( key,
@@ -1735,7 +1733,7 @@
reexported, reexported_length );
PSA_ASSERT( psa_destroy_key( key2 ) );
}
- TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
+ TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE( type, psa_get_key_bits( &got_attributes ) ) );
destroy:
/* Destroy the key */
@@ -1795,7 +1793,7 @@
PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
bits = psa_get_key_bits( &attributes );
TEST_ASSERT( expected_public_key->len <=
- PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
+ PSA_EXPORT_KEY_OUTPUT_SIZE( public_type, bits ) );
ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
exported, exported_length );
}
@@ -2643,9 +2641,9 @@
/* Compute with tight buffer */
PSA_ASSERT( psa_hash_compute( alg, input->x, input->len,
- output, PSA_HASH_SIZE( alg ),
+ output, PSA_HASH_LENGTH( alg ),
&output_length ) );
- TEST_EQUAL( output_length, PSA_HASH_SIZE( alg ) );
+ TEST_EQUAL( output_length, PSA_HASH_LENGTH( alg ) );
ASSERT_COMPARE( output, output_length,
expected_output->x, expected_output->len );
@@ -2653,7 +2651,7 @@
PSA_ASSERT( psa_hash_compute( alg, input->x, input->len,
output, sizeof( output ),
&output_length ) );
- TEST_EQUAL( output_length, PSA_HASH_SIZE( alg ) );
+ TEST_EQUAL( output_length, PSA_HASH_LENGTH( alg ) );
ASSERT_COMPARE( output, output_length,
expected_output->x, expected_output->len );
@@ -2785,7 +2783,7 @@
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb };
- size_t expected_size = PSA_HASH_SIZE( alg );
+ size_t expected_size = PSA_HASH_LENGTH( alg );
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
PSA_ASSERT( psa_crypto_init( ) );
@@ -2815,7 +2813,7 @@
{
psa_algorithm_t alg = PSA_ALG_SHA_256;
unsigned char hash[PSA_HASH_MAX_SIZE];
- size_t expected_size = PSA_HASH_SIZE( alg );
+ size_t expected_size = PSA_HASH_LENGTH( alg );
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
size_t hash_len;
@@ -3119,7 +3117,7 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
uint8_t *actual_mac = NULL;
size_t mac_buffer_size =
- PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key_data->len ), alg );
+ PSA_MAC_LENGTH( key_type, PSA_BYTES_TO_BITS( key_data->len ), alg );
size_t mac_length = 0;
const size_t output_sizes_to_test[] = {
0,
@@ -3130,7 +3128,7 @@
};
TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
- /* We expect PSA_MAC_FINAL_SIZE to be exact. */
+ /* We expect PSA_MAC_LENGTH to be exact. */
TEST_ASSERT( expected_mac->len == mac_buffer_size );
PSA_ASSERT( psa_crypto_init( ) );
@@ -3342,14 +3340,14 @@
psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
- unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
+ unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES)] = { 0 };
const uint8_t key_data[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa };
const uint8_t text[] = {
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
0xbb, 0xbb, 0xbb, 0xbb };
- uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
+ uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES)] = { 0 };
size_t length = 0;
PSA_ASSERT( psa_crypto_init( ) );
@@ -3522,7 +3520,7 @@
}
output_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output, output_buffer_size );
PSA_ASSERT( psa_cipher_update( &operation,
@@ -3590,7 +3588,7 @@
}
output_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output, output_buffer_size );
TEST_ASSERT( first_part_size <= input->len );
@@ -3663,7 +3661,7 @@
}
output_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output, output_buffer_size );
TEST_ASSERT( first_part_size <= input->len );
@@ -3734,7 +3732,7 @@
}
output_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output, output_buffer_size );
PSA_ASSERT( psa_cipher_update( &operation,
@@ -3805,7 +3803,7 @@
&iv_length ) );
}
output1_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output1, output1_size );
PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
@@ -3899,7 +3897,7 @@
}
output1_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output1, output1_buffer_size );
TEST_ASSERT( first_part_size <= input->len );
@@ -5645,7 +5643,7 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
uint8_t *exported = NULL;
size_t exported_size =
- PSA_KEY_EXPORT_MAX_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
+ PSA_EXPORT_KEY_OUTPUT_SIZE( PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits );
size_t exported_length = SIZE_MAX;
uint8_t *e_read_buffer = NULL;
int is_default_public_exponent = 0;
@@ -5756,7 +5754,7 @@
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
unsigned char *first_export = NULL;
unsigned char *second_export = NULL;
- size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
+ size_t export_size = PSA_EXPORT_KEY_OUTPUT_SIZE( type, bits );
size_t first_exported_length;
size_t second_exported_length;
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index 6d20eff..dd01ab6 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -1,6 +1,4 @@
/* BEGIN_HEADER */
-#include "test/psa_crypto_helpers.h"
-
#include "test/drivers/test_driver.h"
/* END_HEADER */
@@ -326,7 +324,7 @@
test_driver_cipher_hooks.hits = 0;
output_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output, output_buffer_size );
if( mock_output_arg )
@@ -418,7 +416,7 @@
test_driver_cipher_hooks.hits = 0;
output_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output, output_buffer_size );
TEST_ASSERT( first_part_size <= input->len );
@@ -503,7 +501,7 @@
test_driver_cipher_hooks.hits = 0;
output_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output, output_buffer_size );
TEST_ASSERT( first_part_size <= input->len );
@@ -591,7 +589,7 @@
test_driver_cipher_hooks.hits = 0;
output_buffer_size = ( (size_t) input->len +
- PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
ASSERT_ALLOC( output, output_buffer_size );
if( mock_output_arg )
diff --git a/tests/suites/test_suite_psa_crypto_entropy.data b/tests/suites/test_suite_psa_crypto_entropy.data
index 61593e9..0e53b60 100644
--- a/tests/suites/test_suite_psa_crypto_entropy.data
+++ b/tests/suites/test_suite_psa_crypto_entropy.data
@@ -1,3 +1,30 @@
+PSA external RNG failure: generate random and key
+external_rng_failure_generate:
+
+# When verifying the impact of a forced RNG failure, depend on the built-in
+# implementation of the algorithm that uses randomization, whether it's
+# because the algorithm is randomized or because our implementation uses
+# randomization for (e.g.) blinding. An external implementation could use
+# its own randomness source which is not affected by the forced failure of
+# the RNG driver.
+# Key types and non-randomized auxilary algorithms (in practice, hashes) can
+# use an external implementation.
+PSA external RNG failure: randomized ECDSA
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PSA_BUILTIN_ALG_ECDSA:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+external_rng_failure_sign:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA_ANY:32
+
+PSA external RNG failure: deterministic ECDSA (software implementation)
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:PSA_WANT_ALG_SHA_256
+external_rng_failure_sign:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):32
+
+PSA external RNG failure: RSA-PSS
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256
+external_rng_failure_sign:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):32
+
+PSA external RNG failure: RSA PKCS#1v1.5 (software implementation)
+depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN
+external_rng_failure_sign:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:32
+
PSA validate entropy injection: good, minimum size
validate_entropy_seed_injection:MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE:PSA_SUCCESS:MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE:PSA_ERROR_NOT_PERMITTED
diff --git a/tests/suites/test_suite_psa_crypto_entropy.function b/tests/suites/test_suite_psa_crypto_entropy.function
index 66c241e..8c1fdab 100644
--- a/tests/suites/test_suite_psa_crypto_entropy.function
+++ b/tests/suites/test_suite_psa_crypto_entropy.function
@@ -1,19 +1,23 @@
/* BEGIN_HEADER */
#include <stdint.h>
+#include <string.h>
+
+#include <psa/crypto.h>
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
-#include "test/psa_crypto_helpers.h"
+/* Calculating the minimum allowed entropy size in bytes */
+#define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+
#if defined(MBEDTLS_PSA_ITS_FILE_C)
#include <stdio.h>
#else
#include <psa/internal_trusted_storage.h>
#endif
-/* Calculating the minimum allowed entropy size in bytes */
-#define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
-
/* Remove the entropy seed file. Since the library does not expose a way
* to do this (it would be a security risk if such a function was ever
* accessible in production), implement this functionality in a white-box
@@ -30,14 +34,89 @@
#endif
}
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
+
/* END_HEADER */
-/* BEGIN_DEPENDENCIES
- * depends_on:MBEDTLS_PSA_INJECT_ENTROPY
- * END_DEPENDENCIES
- */
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+void external_rng_failure_generate( )
+{
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
+ psa_set_key_bits( &attributes, 128 );
+ mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+ uint8_t output[1];
-/* BEGIN_CASE */
+ PSA_ASSERT( psa_crypto_init( ) );
+
+ PSA_ASSERT( psa_generate_random( output, sizeof( output ) ) );
+ PSA_ASSERT( psa_generate_key( &attributes, &key ) );
+ PSA_ASSERT( psa_destroy_key( key ) );
+
+ mbedtls_test_disable_insecure_external_rng( );
+ TEST_EQUAL( PSA_ERROR_INSUFFICIENT_ENTROPY,
+ psa_generate_random( output, sizeof( output ) ) );
+ TEST_EQUAL( PSA_ERROR_INSUFFICIENT_ENTROPY,
+ psa_generate_key( &attributes, &key ) );
+
+exit:
+ psa_destroy_key( key );
+ PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+void external_rng_failure_sign( int key_type, data_t *key_data, int alg,
+ int input_size_arg )
+{
+ /* This test case is only expected to pass if the signature mechanism
+ * requires randomness, either because it is a randomized signature
+ * or because the implementation uses blinding. */
+
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_set_key_type( &attributes, key_type );
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
+ psa_set_key_algorithm( &attributes, alg );
+ mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+ size_t input_size = input_size_arg;
+ uint8_t *input = NULL;
+ uint8_t *signature = NULL;
+ size_t signature_size = PSA_SIGNATURE_MAX_SIZE;
+ size_t signature_length;
+
+ ASSERT_ALLOC( input, input_size );
+ ASSERT_ALLOC( signature, signature_size );
+
+ PSA_ASSERT( psa_crypto_init( ) );
+ PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+ &key ) );
+ PSA_ASSERT( psa_sign_hash( key, alg,
+ input, input_size,
+ signature, signature_size,
+ &signature_length ) );
+ PSA_ASSERT( psa_destroy_key( key ) );
+
+ mbedtls_test_disable_insecure_external_rng( );
+ /* Import the key again, because for RSA Mbed TLS caches blinding values
+ * in the key object and this could perturb the test. */
+ PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+ &key ) );
+ TEST_EQUAL( PSA_ERROR_INSUFFICIENT_ENTROPY,
+ psa_sign_hash( key, alg,
+ input, input_size,
+ signature, signature_size,
+ &signature_length ) );
+ PSA_ASSERT( psa_destroy_key( key ) );
+
+exit:
+ psa_destroy_key( key );
+ PSA_DONE( );
+ mbedtls_free( input );
+ mbedtls_free( signature );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_INJECT_ENTROPY */
void validate_entropy_seed_injection( int seed_length_a,
int expected_status_a,
int seed_length_b,
@@ -81,7 +160,7 @@
}
/* END_CASE */
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_INJECT_ENTROPY */
void run_entropy_inject_with_crypto_init( )
{
psa_status_t status;
diff --git a/tests/suites/test_suite_psa_crypto_hash.function b/tests/suites/test_suite_psa_crypto_hash.function
index 1bc9331..b0da2bf 100644
--- a/tests/suites/test_suite_psa_crypto_hash.function
+++ b/tests/suites/test_suite_psa_crypto_hash.function
@@ -2,8 +2,6 @@
#include <stdint.h>
-#include "test/psa_crypto_helpers.h"
-
/* END_HEADER */
/* BEGIN_DEPENDENCIES
diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function
index 62ef6e2..40efb87 100644
--- a/tests/suites/test_suite_psa_crypto_init.function
+++ b/tests/suites/test_suite_psa_crypto_init.function
@@ -1,7 +1,6 @@
/* BEGIN_HEADER */
#include <stdint.h>
-#include "test/psa_crypto_helpers.h"
/* Some tests in this module configure entropy sources. */
#include "psa_crypto_invasive.h"
@@ -11,11 +10,23 @@
#define ENTROPY_MIN_NV_SEED_SIZE \
MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
+#include "psa_crypto_random_impl.h"
+#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
+/* PSA crypto uses the HMAC_DRBG module. It reads from the entropy source twice:
+ * once for the initial entropy and once for a nonce. The nonce length is
+ * half the entropy length. For SHA-256, SHA-384 or SHA-512, the
+ * entropy length is 256 per the documentation of mbedtls_hmac_drbg_seed(),
+ * and PSA crypto doesn't support other hashes for HMAC_DRBG. */
+#define ENTROPY_NONCE_LEN ( 256 / 2 )
+#else
/* PSA crypto uses the CTR_DRBG module. In some configurations, it needs
* to read from the entropy source twice: once for the initial entropy
* and once for a nonce. */
#include "mbedtls/ctr_drbg.h"
#define ENTROPY_NONCE_LEN MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN
+#endif
+
+#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
typedef struct
{
@@ -118,6 +129,8 @@
MBEDTLS_ENTROPY_SOURCE_STRONG );
}
+#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -125,7 +138,7 @@
* END_DEPENDENCIES
*/
-/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED */
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
void create_nv_seed( )
{
static unsigned char seed[ENTROPY_MIN_NV_SEED_SIZE];
@@ -201,7 +214,7 @@
}
/* END_CASE */
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
void custom_entropy_sources( int sources_arg, int expected_init_status_arg )
{
psa_status_t expected_init_status = expected_init_status_arg;
@@ -222,7 +235,7 @@
}
/* END_CASE */
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
void fake_entropy_source( int threshold,
int amount1,
int amount2,
@@ -262,7 +275,7 @@
}
/* END_CASE */
-/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED */
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
void entropy_from_nv_seed( int seed_size_arg,
int expected_init_status_arg )
{
diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function
index 7c0929e..45f639e 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.function
+++ b/tests/suites/test_suite_psa_crypto_metadata.function
@@ -156,7 +156,7 @@
algorithm_classification( alg, classification_flags );
/* Length */
- TEST_EQUAL( length, PSA_MAC_FINAL_SIZE( key_type, key_bits, alg ) );
+ TEST_EQUAL( length, PSA_MAC_LENGTH( key_type, key_bits, alg ) );
exit: ;
}
@@ -226,7 +226,7 @@
TEST_EQUAL( PSA_ALG_HKDF_GET_HASH( hkdf_alg ), alg );
/* Hash length */
- TEST_EQUAL( length, PSA_HASH_SIZE( alg ) );
+ TEST_EQUAL( length, PSA_HASH_LENGTH( alg ) );
TEST_ASSERT( length <= PSA_HASH_MAX_SIZE );
}
/* END_CASE */
@@ -483,7 +483,7 @@
TEST_EQUAL( type & PSA_KEY_TYPE_CATEGORY_MASK,
PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
- TEST_EQUAL( PSA_BLOCK_CIPHER_BLOCK_SIZE( type ), block_size );
+ TEST_EQUAL( PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ), block_size );
}
/* END_CASE */
@@ -496,7 +496,7 @@
TEST_EQUAL( type & PSA_KEY_TYPE_CATEGORY_MASK,
PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
- TEST_EQUAL( PSA_BLOCK_CIPHER_BLOCK_SIZE( type ), 1 );
+ TEST_EQUAL( PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ), 1 );
}
/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index 8e10158..9759077 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -9,7 +9,6 @@
#include <stdint.h>
-#include "test/psa_crypto_helpers.h"
#include "psa_crypto_slot_management.h"
#include "psa_crypto_storage.h"
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
index 1add9b4..cf6ca5e 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
@@ -1,5 +1,4 @@
/* BEGIN_HEADER */
-#include "test/psa_crypto_helpers.h"
#include "psa/crypto_se_driver.h"
#include "psa_crypto_se.h"
@@ -293,8 +292,8 @@
{
psa_status_t status;
size_t required_storage =
- PSA_KEY_EXPORT_MAX_SIZE( psa_get_key_type( attributes ),
- psa_get_key_bits( attributes ) );
+ PSA_EXPORT_KEY_OUTPUT_SIZE( psa_get_key_type( attributes ),
+ psa_get_key_bits( attributes ) );
DRIVER_ASSERT_RETURN( *pubkey_length == 0 );
if( ! PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) )
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
index 629c924..12c58eb 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
@@ -1,5 +1,4 @@
/* BEGIN_HEADER */
-#include "test/psa_crypto_helpers.h"
#include "psa/crypto_se_driver.h"
#include "psa_crypto_se.h"
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index 57d4789..b0c660b 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -1,7 +1,6 @@
/* BEGIN_HEADER */
#include <stdint.h>
-#include "test/psa_crypto_helpers.h"
#include "psa_crypto_slot_management.h"
#include "psa_crypto_storage.h"
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index bb26246..2b01227 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
Check compiletime library version
-check_compiletime_version:"2.24.0"
+check_compiletime_version:"2.25.0"
Check runtime library version
-check_runtime_version:"2.24.0"
+check_runtime_version:"2.25.0"
Check for MBEDTLS_VERSION_C
check_feature:"MBEDTLS_VERSION_C":0
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index bfdbab2..3b84609 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -2652,6 +2652,10 @@
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
x509parse_crt_file:"data_files/server7_trailing_space.crt":0
+X509 File parse (Algorithm Params Tag mismatch)
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
+x509parse_crt_file:"data_files/cli-rsa-sha256-badalg.crt.der":MBEDTLS_ERR_X509_SIG_MISMATCH
+
X509 Get time (UTC no issues)
depends_on:MBEDTLS_X509_USE_C
x509_get_time:MBEDTLS_ASN1_UTC_TIME:"500101000000Z":0:1950:1:1:0:0:0
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index b3f209e..e0f80be 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -56,35 +56,43 @@
Certificate write check Server1 SHA1
depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:-1:"data_files/server1.crt":0
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:-1:"data_files/server1.crt":0:0
Certificate write check Server1 SHA1, key_usage
depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:0:0:1:-1:"data_files/server1.key_usage.crt":0
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:0:0:1:-1:"data_files/server1.key_usage.crt":0:0
Certificate write check Server1 SHA1, ns_cert_type
depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:1:-1:"data_files/server1.cert_type.crt":0
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:1:-1:"data_files/server1.cert_type.crt":0:0
Certificate write check Server1 SHA1, version 1
depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":0
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":0:0
+
+Certificate write check Server1 SHA1, CA
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:1:-1:"data_files/server1.ca.crt":0:1
Certificate write check Server1 SHA1, RSA_ALT
depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:0:-1:"data_files/server1.noauthid.crt":1
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:0:-1:"data_files/server1.noauthid.crt":1:0
Certificate write check Server1 SHA1, RSA_ALT, key_usage
depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:0:0:0:-1:"data_files/server1.key_usage_noauthid.crt":1
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:0:0:0:-1:"data_files/server1.key_usage_noauthid.crt":1:0
Certificate write check Server1 SHA1, RSA_ALT, ns_cert_type
depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:0:-1:"data_files/server1.cert_type_noauthid.crt":1
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:0:-1:"data_files/server1.cert_type_noauthid.crt":1:0
Certificate write check Server1 SHA1, RSA_ALT, version 1
depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:0:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":1
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:0:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":1:0
+
+Certificate write check Server1 SHA1, RSA_ALT, CA
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:0:0:0:-1:"data_files/server1.ca_noauthid.crt":1:1
X509 String to Names #1
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index 3803377..9960989 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -6,24 +6,11 @@
#include "mbedtls/oid.h"
#include "mbedtls/rsa.h"
-/* These are the same depends as the test function x509_crs_check_opaque(),
- * the only function using PSA here. Using a weaker condition would result in
- * warnings about the static functions defined in psa_crypto_helpers.h being
- * unused. */
-#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
- defined(MBEDTLS_PEM_WRITE_C) && \
- defined(MBEDTLS_X509_CSR_WRITE_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
-#include "test/psa_crypto_helpers.h"
#define PSA_INIT( ) PSA_ASSERT( psa_crypto_init( ) )
-#else
-/* Define empty macros so that we can use them in the preamble and teardown
- * of every test function that uses PSA conditionally based on
- * MBEDTLS_USE_PSA_CRYPTO. */
-#define PSA_INIT( ) ( (void) 0 )
-#define PSA_DONE( ) ( (void) 0 )
-#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_PEM_WRITE_C && MBEDTLS_X509_CSR_WRITE_C */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_RSA_C)
int mbedtls_rsa_decrypt_func( void *ctx, int mode, size_t *olen,
@@ -219,7 +206,7 @@
char *serial_str, char *not_before, char *not_after,
int md_type, int key_usage, int set_key_usage,
int cert_type, int set_cert_type, int auth_ident,
- int ver, char *cert_check_file, int rsa_alt )
+ int ver, char *cert_check_file, int rsa_alt, int is_ca )
{
mbedtls_pk_context subject_key, issuer_key, issuer_key_alt;
mbedtls_pk_context *key = &issuer_key;
@@ -282,7 +269,9 @@
if( crt.version >= MBEDTLS_X509_CRT_VERSION_3 )
{
- TEST_ASSERT( mbedtls_x509write_crt_set_basic_constraints( &crt, 0, 0 ) == 0 );
+ /* For the CA case, a path length of -1 means unlimited. */
+ TEST_ASSERT( mbedtls_x509write_crt_set_basic_constraints( &crt, is_ca,
+ (is_ca ? -1 : 0) ) == 0 );
TEST_ASSERT( mbedtls_x509write_crt_set_subject_key_identifier( &crt ) == 0 );
if( auth_ident )
TEST_ASSERT( mbedtls_x509write_crt_set_authority_key_identifier( &crt ) == 0 );
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index 0af4145..78832eb 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -222,11 +222,9 @@
<ClInclude Include="..\..\include\mbedtls\x509_csr.h" />
<ClInclude Include="..\..\include\mbedtls\xtea.h" />
<ClInclude Include="..\..\include\psa\crypto.h" />
- <ClInclude Include="..\..\include\psa\crypto_accel_driver.h" />
<ClInclude Include="..\..\include\psa\crypto_compat.h" />
<ClInclude Include="..\..\include\psa\crypto_config.h" />
<ClInclude Include="..\..\include\psa\crypto_driver_common.h" />
- <ClInclude Include="..\..\include\psa\crypto_entropy_driver.h" />
<ClInclude Include="..\..\include\psa\crypto_extra.h" />
<ClInclude Include="..\..\include\psa\crypto_platform.h" />
<ClInclude Include="..\..\include\psa\crypto_se_driver.h" />
@@ -235,6 +233,7 @@
<ClInclude Include="..\..\include\psa\crypto_types.h" />
<ClInclude Include="..\..\include\psa\crypto_values.h" />
<ClInclude Include="..\..\tests\include\test\constant_flow.h" />
+ <ClInclude Include="..\..\tests\include\test\fake_external_rng_for_test.h" />
<ClInclude Include="..\..\tests\include\test\helpers.h" />
<ClInclude Include="..\..\tests\include\test\macros.h" />
<ClInclude Include="..\..\tests\include\test\psa_crypto_helpers.h" />
@@ -251,6 +250,7 @@
<ClInclude Include="..\..\library\psa_crypto_driver_wrappers.h" />
<ClInclude Include="..\..\library\psa_crypto_invasive.h" />
<ClInclude Include="..\..\library\psa_crypto_its.h" />
+ <ClInclude Include="..\..\library\psa_crypto_random_impl.h" />
<ClInclude Include="..\..\library\psa_crypto_se.h" />
<ClInclude Include="..\..\library\psa_crypto_service_integration.h" />
<ClInclude Include="..\..\library\psa_crypto_slot_management.h" />
@@ -349,7 +349,9 @@
<ClCompile Include="..\..\library\x509write_crt.c" />
<ClCompile Include="..\..\library\x509write_csr.c" />
<ClCompile Include="..\..\library\xtea.c" />
+ <ClCompile Include="..\..\tests\src\fake_external_rng_for_test.c" />
<ClCompile Include="..\..\tests\src\helpers.c" />
+ <ClCompile Include="..\..\tests\src\psa_crypto_helpers.c" />
<ClCompile Include="..\..\tests\src\random.c" />
<ClCompile Include="..\..\3rdparty\everest\library\everest.c" />
<ClCompile Include="..\..\3rdparty\everest\library\Hacl_Curve25519_joined.c" />
diff --git a/visualc/VS2010/ssl_client2.vcxproj b/visualc/VS2010/ssl_client2.vcxproj
index 9021602..9884f23 100644
--- a/visualc/VS2010/ssl_client2.vcxproj
+++ b/visualc/VS2010/ssl_client2.vcxproj
@@ -21,6 +21,7 @@
<ItemGroup>
<ClCompile Include="..\..\programs\ssl\ssl_client2.c" />
<ClCompile Include="..\..\programs\test\query_config.c" />
+ <ClCompile Include="..\..\programs\ssl\ssl_test_lib.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="mbedTLS.vcxproj">
diff --git a/visualc/VS2010/ssl_server2.vcxproj b/visualc/VS2010/ssl_server2.vcxproj
index 61eedaa..d8f3e59 100644
--- a/visualc/VS2010/ssl_server2.vcxproj
+++ b/visualc/VS2010/ssl_server2.vcxproj
@@ -21,6 +21,7 @@
<ItemGroup>
<ClCompile Include="..\..\programs\ssl\ssl_server2.c" />
<ClCompile Include="..\..\programs\test\query_config.c" />
+ <ClCompile Include="..\..\programs\ssl\ssl_test_lib.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="mbedTLS.vcxproj">