Merge pull request #6766 from wernerlewis/bignum_mod_docs
Bignum: document conventions for bignum mod and mod_raw
diff --git a/BRANCHES.md b/BRANCHES.md
index 6240023..c7a6082 100644
--- a/BRANCHES.md
+++ b/BRANCHES.md
@@ -101,6 +101,6 @@
- [`development`](https://github.com/Mbed-TLS/mbedtls/)
- [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28)
maintained until at least the end of 2024, see
- <https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.0>.
+ <https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.2>.
Users are urged to always use the latest version of a maintained branch.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 59a960a..519604b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -304,22 +304,15 @@
# additional convenience targets for Unix only
if(UNIX)
- ADD_CUSTOM_TARGET(covtest
- COMMAND make test
- COMMAND programs/test/selftest
- COMMAND tests/compat.sh
- COMMAND tests/ssl-opt.sh
- )
-
+ # For coverage testing:
+ # 1. Build with:
+ # cmake -D CMAKE_BUILD_TYPE=Coverage /path/to/source && make
+ # 2. Run the relevant tests for the part of the code you're interested in.
+ # For the reference coverage measurement, see
+ # tests/scripts/basic-build-test.sh
+ # 3. Run scripts/lcov.sh to generate an HTML report.
ADD_CUSTOM_TARGET(lcov
- COMMAND rm -rf Coverage
- COMMAND lcov --capture --initial --directory library/CMakeFiles/mbedtls.dir -o files.info
- COMMAND lcov --capture --directory library/CMakeFiles/mbedtls.dir -o tests.info
- COMMAND lcov --add-tracefile files.info --add-tracefile tests.info -o all.info
- COMMAND lcov --remove all.info -o final.info '*.h'
- COMMAND gendesc tests/Descriptions.txt -o descriptions
- COMMAND genhtml --title "mbed TLS" --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info
- COMMAND rm -f files.info tests.info all.info final.info descriptions
+ COMMAND scripts/lcov.sh
)
ADD_CUSTOM_TARGET(memcheck
@@ -350,12 +343,12 @@
write_basic_package_version_file(
"cmake/MbedTLSConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
- VERSION 3.2.1)
+ VERSION 3.3.0)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfigVersion.cmake"
- DESTINATION "cmake")
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MbedTLS")
export(
EXPORT MbedTLSTargets
@@ -365,7 +358,7 @@
install(
EXPORT MbedTLSTargets
NAMESPACE MbedTLS::
- DESTINATION "cmake"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MbedTLS"
FILE "MbedTLSTargets.cmake")
if(CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d19fe57..fc79e49 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -32,13 +32,9 @@
The project aims to minimise the impact on users upgrading to newer versions of the library and it should not be necessary for a user to make any changes to their own code to work with a newer version of the library. Unless the user has made an active decision to use newer features, a newer generation of the library or a change has been necessary due to a security issue or other significant software defect, no modifications to their own code should be necessary. To achieve this, API compatibility is maintained between different versions of Mbed TLS on the main development branch and in LTS (Long Term Support) branches, as described in [BRANCHES.md](BRANCHES.md).
-To minimise such disruption to users, where a change to the interface is required, all changes to the ABI or API, even on the main development branch where new features are added, need to be justifiable by either being a significant enhancement, new feature or bug fix which is best resolved by an interface change. If there is an API change, the contribution, if accepted, will be merged only when there will be a major release.
+To minimise such disruption to users, where a change to the interface is required, all changes to the ABI or API, even on the main development branch where new features are added, need to be justifiable by either being a significant enhancement, new feature or bug fix which is best resolved by an interface change. If there is an API change, the contribution, if accepted, will be merged only when there is a major release.
-Where changes to an existing interface are necessary, functions in the public interface which need to be changed, are marked as 'deprecated'. This is done with the preprocessor symbols `MBEDTLS_DEPRECATED_WARNING` and `MBEDTLS_DEPRECATED_REMOVED`. Then, a new function with a new name but similar if not identical behaviour to the original function containing the necessary changes should be created alongside the existing deprecated function.
-
-When a build is made with the deprecation preprocessor symbols defined, a compiler warning will be generated to warn a user that the function will be removed at some point in the future, notifying users that they should change from the older deprecated function to the newer function at their own convenience.
-
-Therefore, no changes are permitted to the definition of functions in the public interface which will change the API. Instead the interface can only be changed by its extension. As described above, if a function needs to be changed, a new function needs to be created alongside it, with a new name, and whatever change is necessary, such as a new parameter or the addition of a return value.
+No changes are permitted to the definition of functions in the public interface which will change the API. Instead the interface can only be changed by its extension. Where changes to an existing interface are necessary, functions in the public interface which need to be changed are marked as 'deprecated'. If there is a strong reason to replace an existing function with one that has a slightly different interface (different prototype, or different documented behavior), create a new function with a new name with the desired interface. Keep the old function, but mark it as deprecated.
Periodically, the library will remove deprecated functions from the library which will be a breaking change in the API, but such changes will be made only in a planned, structured way that gives sufficient notice to users of the library.
diff --git a/ChangeLog b/ChangeLog
index cb277dc..1404d36 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,209 @@
Mbed TLS ChangeLog (Sorted per branch, date)
+= Mbed TLS 3.3.0 branch released 2022-12-14
+
+Default behavior changes
+ * Previously the macro MBEDTLS_SSL_DTLS_CONNECTION_ID implemented version 05
+ of the IETF draft, and was marked experimental and disabled by default.
+ It is now no longer experimental, and implements the final version from
+ RFC 9146, which is not interoperable with the draft-05 version.
+ If you need to communicate with peers that use earlier versions of
+ Mbed TLS, then you need to define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
+ to 1, but then you won't be able to communicate with peers that use the
+ standard (non-draft) version.
+ If you need to interoperate with both classes of peers with the
+ same build of Mbed TLS, please let us know about your situation on the
+ mailing list or GitHub.
+
+Requirement changes
+ * When building with PSA drivers using generate_driver_wrappers.py, or
+ when building the library from the development branch rather than
+ from a release, the Python module jsonschema is now necessary, in
+ addition to jinja2. The official list of required Python modules is
+ maintained in scripts/basic.requirements.txt and may change again
+ in the future.
+
+New deprecations
+ * Deprecate mbedtls_asn1_free_named_data().
+ Use mbedtls_asn1_free_named_data_list()
+ or mbedtls_asn1_free_named_data_list_shallow().
+
+Features
+ * Support rsa_pss_rsae_* signature algorithms in TLS 1.2.
+ * make: enable building unversioned shared library, with e.g.:
+ "SHARED=1 SOEXT_TLS=so SOEXT_X509=so SOEXT_CRYPTO=so make lib"
+ resulting in library names like "libmbedtls.so" rather than
+ "libmbedcrypto.so.11".
+ * Expose the EC J-PAKE functionality through the Draft PSA PAKE Crypto API.
+ Only the ECC primitive with secp256r1 curve and SHA-256 hash algorithm
+ are supported in this implementation.
+ * Some modules can now use PSA drivers for hashes, including with no
+ built-in implementation present, but only in some configurations.
+ - RSA OAEP and PSS (PKCS#1 v2.1), PKCS5, PKCS12 and EC J-PAKE now use
+ hashes from PSA when (and only when) MBEDTLS_MD_C is disabled.
+ - PEM parsing of encrypted files now uses MD-5 from PSA when (and only
+ when) MBEDTLS_MD5_C is disabled.
+ See the documentation of the corresponding macros in mbedtls_config.h for
+ details.
+ Note that some modules are not able to use hashes from PSA yet, including
+ the entropy module. As a consequence, for now the only way to build with
+ all hashes only provided by drivers (no built-in hash) is to use
+ MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
+ * When MBEDTLS_USE_PSA_CRYPTO is enabled, X.509, TLS 1.2 and TLS 1.3 now
+ properly negotiate/accept hashes based on their availability in PSA.
+ As a consequence, they now work in configurations where the built-in
+ implementations of (some) hashes are excluded and those hashes are only
+ provided by PSA drivers. (See previous entry for limitation on RSA-PSS
+ though: that module only use hashes from PSA when MBEDTLS_MD_C is off).
+ * Add support for opaque keys as the private keys associated to certificates
+ for authentication in TLS 1.3.
+ * Add the LMS post-quantum-safe stateful-hash asymmetric signature scheme.
+ Signature verification is production-ready, but generation is for testing
+ purposes only. This currently only supports one parameter set
+ (LMS_SHA256_M32_H10), meaning that each private key can be used to sign
+ 1024 messages. As such, it is not intended for use in TLS, but instead
+ for verification of assets transmitted over an insecure channel,
+ particularly firmware images.
+ * Add the LM-OTS post-quantum-safe one-time signature scheme, which is
+ required for LMS. This can be used independently, but each key can only
+ be used to sign one message so is impractical for most circumstances.
+ * Mbed TLS now supports TLS 1.3 key establishment via pre-shared keys.
+ The pre-shared keys can be provisioned externally or via the ticket
+ mechanism (session resumption).
+ The ticket mechanism is supported when the configuration option
+ MBEDTLS_SSL_SESSION_TICKETS is enabled.
+ New options MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_xxx_ENABLED
+ control the support for the three possible TLS 1.3 key exchange modes.
+ * cert_write: support for setting extended key usage attributes. A
+ corresponding new public API call has been added in the library,
+ mbedtls_x509write_crt_set_ext_key_usage().
+ * cert_write: support for writing certificate files in either PEM
+ or DER format.
+ * The PSA driver wrapper generator generate_driver_wrappers.py now
+ supports a subset of the driver description language, including
+ the following entry points: import_key, export_key, export_public_key,
+ get_builtin_key, copy_key.
+ * The new functions mbedtls_asn1_free_named_data_list() and
+ mbedtls_asn1_free_named_data_list_shallow() simplify the management
+ of memory in named data lists in X.509 structures.
+ * The TLS 1.2 EC J-PAKE key exchange can now use the PSA Crypto API.
+ Additional PSA key slots will be allocated in the process of such key
+ exchange for builds that enable MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED and
+ MBEDTLS_USE_PSA_CRYPTO.
+ * Add support for DTLS Connection ID as defined by RFC 9146, controlled by
+ MBEDTLS_SSL_DTLS_CONNECTION_ID (enabled by default) and configured with
+ mbedtls_ssl_set_cid().
+ * Add a driver dispatch layer for raw key agreement, enabling alternative
+ implementations of raw key agreement through the key_agreement driver
+ entry point. This entry point is specified in the proposed PSA driver
+ interface, but had not yet been implemented.
+ * Add an ad-hoc key derivation function handling EC J-PAKE to PMS
+ calculation that can be used to derive the session secret in TLS 1.2,
+ as described in draft-cragie-tls-ecjpake-01. This can be achieved by
+ using PSA_ALG_TLS12_ECJPAKE_TO_PMS as the key derivation algorithm.
+
+Security
+ * Fix potential heap buffer overread and overwrite in DTLS if
+ MBEDTLS_SSL_DTLS_CONNECTION_ID is enabled and
+ MBEDTLS_SSL_CID_IN_LEN_MAX > 2 * MBEDTLS_SSL_CID_OUT_LEN_MAX.
+ * An adversary with access to precise enough information about memory
+ accesses (typically, an untrusted operating system attacking a secure
+ enclave) could recover an RSA private key after observing the victim
+ performing a single private-key operation if the window size used for the
+ exponentiation was 3 or smaller. Found and reported by Zili KOU,
+ Wenjian HE, Sharad Sinha, and Wei ZHANG. See "Cache Side-channel Attacks
+ and Defenses of the Sliding Window Algorithm in TEEs" - Design, Automation
+ and Test in Europe 2023.
+
+Bugfix
+ * Refactor mbedtls_aes_context to support shallow-copying. Fixes #2147.
+ * Fix an issue with in-tree CMake builds in releases with GEN_FILES
+ turned off: if a shipped file was missing from the working directory,
+ it could be turned into a symbolic link to itself.
+ * Fix a long-standing build failure when building x86 PIC code with old
+ gcc (4.x). The code will be slower, but will compile. We do however
+ recommend upgrading to a more recent compiler instead. Fixes #1910.
+ * Fix support for little-endian Microblaze when MBEDTLS_HAVE_ASM is defined.
+ Contributed by Kazuyuki Kimura to fix #2020.
+ * Use double quotes to include private header file psa_crypto_cipher.h.
+ Fixes 'file not found with <angled> include' error
+ when building with Xcode.
+ * Fix handling of broken symlinks when loading certificates using
+ mbedtls_x509_crt_parse_path(). Instead of returning an error as soon as a
+ broken link is encountered, skip the broken link and continue parsing
+ other certificate files. Contributed by Eduardo Silva in #2602.
+ * Fix an interoperability failure between an Mbed TLS client with both
+ TLS 1.2 and TLS 1.3 support, and a TLS 1.2 server that supports
+ rsa_pss_rsae_* signature algorithms. This failed because Mbed TLS
+ advertised support for PSS in both TLS 1.2 and 1.3, but only
+ actually supported PSS in TLS 1.3.
+ * Fix a compilation error when using CMake with an IAR toolchain.
+ Fixes #5964.
+ * Fix a build error due to a missing prototype warning when
+ MBEDTLS_DEPRECATED_REMOVED is enabled.
+ * Fix mbedtls_ctr_drbg_free() on an initialized but unseeded context. When
+ MBEDTLS_AES_ALT is enabled, it could call mbedtls_aes_free() on an
+ uninitialized context.
+ * Fix a build issue on Windows using CMake where the source and build
+ directories could not be on different drives. Fixes #5751.
+ * Fix bugs and missing dependencies when building and testing
+ configurations with only one encryption type enabled in TLS 1.2.
+ * Provide the missing definition of mbedtls_setbuf() in some configurations
+ with MBEDTLS_PLATFORM_C disabled. Fixes #6118, #6196.
+ * Fix compilation errors when trying to build with
+ PSA drivers for AEAD (GCM, CCM, Chacha20-Poly1305).
+ * Fix memory leak in ssl_parse_certificate_request() caused by
+ mbedtls_x509_get_name() not freeing allocated objects in case of error.
+ Change mbedtls_x509_get_name() to clean up allocated objects on error.
+ * Fix build failure with MBEDTLS_RSA_C and MBEDTLS_PSA_CRYPTO_C but not
+ MBEDTLS_USE_PSA_CRYPTO or MBEDTLS_PK_WRITE_C. Fixes #6408.
+ * Fix build failure with MBEDTLS_RSA_C and MBEDTLS_PSA_CRYPTO_C but not
+ MBEDTLS_PK_PARSE_C. Fixes #6409.
+ * Fix ECDSA verification, where it was not always validating the
+ public key. This bug meant that it was possible to verify a
+ signature with an invalid public key, in some cases. Reported by
+ Guido Vranken using Cryptofuzz in #4420.
+ * Fix a possible null pointer dereference if a memory allocation fails
+ in TLS PRF code. Reported by Michael Madsen in #6516.
+ * Fix TLS 1.3 session resumption. Fixes #6488.
+ * Add a configuration check to exclude optional client authentication
+ in TLS 1.3 (where it is forbidden).
+ * Fix a bug in which mbedtls_x509_crt_info() would produce non-printable
+ bytes when parsing certificates containing a binary RFC 4108
+ HardwareModuleName as a Subject Alternative Name extension. Hardware
+ serial numbers are now rendered in hex format. Fixes #6262.
+ * Fix bug in error reporting in dh_genprime.c where upon failure,
+ the error code returned by mbedtls_mpi_write_file() is overwritten
+ and therefore not printed.
+ * In the bignum module, operations of the form (-A) - (+A) or (-A) - (-A)
+ with A > 0 created an unintended representation of the value 0 which was
+ not processed correctly by some bignum operations. Fix this. This had no
+ consequence on cryptography code, but might affect applications that call
+ bignum directly and use negative numbers.
+ * Fix a bug whereby the list of signature algorithms sent as part of
+ the TLS 1.2 server certificate request would get corrupted, meaning the
+ first algorithm would not get sent and an entry consisting of two random
+ bytes would be sent instead. Found by Serban Bejan and Dudek Sebastian.
+ * Fix undefined behavior (typically harmless in practice) of
+ mbedtls_mpi_add_mpi(), mbedtls_mpi_add_abs() and mbedtls_mpi_add_int()
+ when both operands are 0 and the left operand is represented with 0 limbs.
+ * Fix undefined behavior (typically harmless in practice) when some bignum
+ functions receive the most negative value of mbedtls_mpi_sint. Credit
+ to OSS-Fuzz. Fixes #6597.
+ * Fix undefined behavior (typically harmless in practice) in PSA ECB
+ encryption and decryption.
+ * Move some SSL-specific code out of libmbedcrypto where it had been placed
+ accidentally.
+ * Fix a build error when compiling the bignum module for some Arm platforms.
+ Fixes #6089, #6124, #6217.
+
+Changes
+ * Add the ability to query PSA_WANT_xxx macros to query_compile_time_config.
+ * Calling AEAD tag-specific functions for non-AEAD algorithms (which
+ should not be done - they are documented for use only by AES-GCM and
+ ChaCha20+Poly1305) now returns MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
+ instead of success (0).
+
= Mbed TLS 3.2.1 branch released 2022-07-12
Bugfix
@@ -249,7 +453,7 @@
make to break on a clean checkout. Fixes #5340.
* Work around an MSVC ARM64 compiler bug causing incorrect behaviour
in mbedtls_mpi_exp_mod(). Reported by Tautvydas Žilys in #5467.
- * Removed the prompt to exit from all windows build programs that was causing
+ * Removed the prompt to exit from all windows build programs, which was causing
issues in CI/CD environments.
Changes
diff --git a/ChangeLog.d/LMS.txt b/ChangeLog.d/LMS.txt
deleted file mode 100644
index 785bfcf..0000000
--- a/ChangeLog.d/LMS.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Features
- * Add the LMS post-quantum-safe stateful-hash asymmetric signature scheme.
- Signature verification is production-ready, but generation is for testing
- purposes only. This currently only supports one parameter set
- (LMS_SHA256_M32_H10), meaning that each private key can be used to sign
- 1024 messages. As such, it is not intended for use in TLS, but instead
- for verification of assets transmitted over an insecure channel,
- particularly firmware images.
- * Add the LM-OTS post-quantum-safe one-time signature scheme, which is
- required for LMS. This can be used independently, but each key can only
- be used to sign one message so is impractical for most circumstances.
diff --git a/ChangeLog.d/add-rsa-pss-rsae-support-for-tls12.txt b/ChangeLog.d/add-rsa-pss-rsae-support-for-tls12.txt
deleted file mode 100644
index 0d40968..0000000
--- a/ChangeLog.d/add-rsa-pss-rsae-support-for-tls12.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Features
- * Support rsa_pss_rsae_* signature algorithms in TLS 1.2.
-Bugfix
- * Fix an interoperability failure between an Mbed TLS client with both
- TLS 1.2 and TLS 1.3 support, and a TLS 1.2 server that supports
- rsa_pss_rsae_* signature algorithms. This failed because Mbed TLS
- advertised support for PSS in both TLS 1.2 and 1.3, but only
- actually supported PSS in TLS 1.3.
diff --git a/ChangeLog.d/bn_mul-fix-x86-pic-compilation-for-gcc-4.txt b/ChangeLog.d/bn_mul-fix-x86-pic-compilation-for-gcc-4.txt
deleted file mode 100644
index 1d59c22..0000000
--- a/ChangeLog.d/bn_mul-fix-x86-pic-compilation-for-gcc-4.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix a long-standing build failure when building x86 PIC code with old
- gcc (4.x). The code will be slower, but will compile. We do however
- recommend upgrading to a more recent compiler instead. Fixes #1910.
diff --git a/ChangeLog.d/cert_write-set-extended-key-usages.txt b/ChangeLog.d/cert_write-set-extended-key-usages.txt
deleted file mode 100644
index 18b7b04..0000000
--- a/ChangeLog.d/cert_write-set-extended-key-usages.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Features
- * cert_write: support for setting extended key usage attributes. A
- corresponding new public API call has been added in the library,
- mbedtls_x509write_crt_set_ext_key_usage().
- * cert_write: support for writing certificate files in either PEM
- or DER format.
diff --git a/ChangeLog.d/cmake-install.txt b/ChangeLog.d/cmake-install.txt
new file mode 100644
index 0000000..d8eb72e
--- /dev/null
+++ b/ChangeLog.d/cmake-install.txt
@@ -0,0 +1,3 @@
+Changes
+ * Install the .cmake files into CMAKE_INSTALL_LIBDIR/cmake/MbedTLS,
+ typically /usr/lib/cmake/MbedTLS.
diff --git a/ChangeLog.d/driver-only-hashes.txt b/ChangeLog.d/driver-only-hashes.txt
deleted file mode 100644
index 6ccd199..0000000
--- a/ChangeLog.d/driver-only-hashes.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Features
- * Some modules can now use PSA drivers for hashes, including with no
- built-in implementation present, but only in some configurations.
- - RSA OAEP and PSS (PKCS#1 v2.1), PKCS5, PKCS12 and EC J-PAKE now use
- hashes from PSA when (and only when) MBEDTLS_MD_C is disabled.
- - PEM parsing of encrypted files now uses MD-5 from PSA when (and only
- when) MBEDTLS_MD5_C is disabled.
- See the documentation of the corresponding macros in mbedtls_config.h for
- details.
- Note that some modules are not able to use hashes from PSA yet, including
- the entropy module. As a consequence, for now the only way to build with
- all hashes only provided by drivers (no built-in hash) is to use
- MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
- * When MBEDTLS_USE_PSA_CRYPTO is enabled, X.509, TLS 1.2 and TLS 1.3 now
- properly negotiate/accept hashes based on their availability in PSA.
- As a consequence, they now work in configurations where the built-in
- implementations of (some) hashes are excluded and those hashes are only
- provided by PSA drivers. (See previous entry for limitation on RSA-PSS
- though: that module only use hashes from PSA when MBEDTLS_MD_C is off).
diff --git a/ChangeLog.d/dtls-connection-id.txt b/ChangeLog.d/dtls-connection-id.txt
deleted file mode 100644
index 840f837..0000000
--- a/ChangeLog.d/dtls-connection-id.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Features
- * Add support for DTLS Connection ID as defined by RFC 9146, controlled by
- MBEDTLS_SSL_DTLS_CONNECTION_ID (enabled by default) and configured with
- mbedtls_ssl_set_cid().
-
-Default behavior changes
- * Previously the macro MBEDTLS_SSL_DTLS_CONNECTION_ID implemented version 05
- of the IETF draft, and was marked experimental and disabled by default.
- It is now no longer experimental, and implements the final version from
- RFC 9146, which is not interoperable with the draft-05 version.
- If you need to communicate with peers that use earlier versions of
- Mbed TLS, then you need to define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
- to 1, but then you won't be able to communicate with peers that use the
- standard (non-draft) version.
- If you need to interoperate with both classes of peers with the
- same build of Mbed TLS, please let us know about your situation on the
- mailing list or GitHub.
diff --git a/ChangeLog.d/ecdsa-verify-fixes.txt b/ChangeLog.d/ecdsa-verify-fixes.txt
deleted file mode 100644
index b41b046..0000000
--- a/ChangeLog.d/ecdsa-verify-fixes.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
- * Fix ECDSA verification, where it was not always validating the
- public key. This bug meant that it was possible to verify a
- signature with an invalid public key, in some cases. Reported by
- Guido Vranken using Cryptofuzz in #4420.
diff --git a/ChangeLog.d/ecjpake-in-tls.txt b/ChangeLog.d/ecjpake-in-tls.txt
deleted file mode 100644
index b84caab..0000000
--- a/ChangeLog.d/ecjpake-in-tls.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Features
- * The TLS 1.2 EC J-PAKE key exchange can now use the PSA Crypto API.
- Additional PSA key slots will be allocated in the process of such key
- exchange for builds that enable MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED and
- MBEDTLS_USE_PSA_CRYPTO.
diff --git a/ChangeLog.d/ecjpake_to_pms.txt b/ChangeLog.d/ecjpake_to_pms.txt
deleted file mode 100644
index 4dd2075..0000000
--- a/ChangeLog.d/ecjpake_to_pms.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-API changes
- * Add an ad-hoc key derivation function handling ECJPAKE to PMS
- calculation that can be used to derive the session secret in TLS 1.2,
- as described in draft-cragie-tls-ecjpake-01. This can be achieved by
- using PSA_ALG_TLS12_ECJPAKE_TO_PMS as the key derivation algorithm.
diff --git a/ChangeLog.d/extend-query_compile_time_config-to-psa_want.txt b/ChangeLog.d/extend-query_compile_time_config-to-psa_want.txt
deleted file mode 100644
index 99b2ec4..0000000
--- a/ChangeLog.d/extend-query_compile_time_config-to-psa_want.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Changes
- * Add the ability to query PSA_WANT_xxx macros to query_compile_time_config.
diff --git a/ChangeLog.d/fix-aes-shallow-copying.txt b/ChangeLog.d/fix-aes-shallow-copying.txt
deleted file mode 100644
index 0c119d6..0000000
--- a/ChangeLog.d/fix-aes-shallow-copying.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Bugfix
- * Refactor mbedtls_aes_context to support shallow-copying. Fixes #2147.
diff --git a/ChangeLog.d/fix-ctr-drbg-may-free-invalid-aes-context.txt b/ChangeLog.d/fix-ctr-drbg-may-free-invalid-aes-context.txt
deleted file mode 100644
index fe62c28..0000000
--- a/ChangeLog.d/fix-ctr-drbg-may-free-invalid-aes-context.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix mbedtls_ctr_drbg_free() on an initialized but unseeded context. When
- MBEDTLS_AES_ALT is enabled, it could call mbedtls_aes_free() on an
- uninitialized context.
diff --git a/ChangeLog.d/fix-possible-false-success-in-mbedtls_cipher_check_tag.txt b/ChangeLog.d/fix-possible-false-success-in-mbedtls_cipher_check_tag.txt
deleted file mode 100644
index 1f9e0aa..0000000
--- a/ChangeLog.d/fix-possible-false-success-in-mbedtls_cipher_check_tag.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Changes
- * Calling AEAD tag-specific functions for non-AEAD algorithms (which
- should not be done - they are documented for use only by AES-GCM and
- ChaCha20+Poly1305) now returns MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
- instead of success (0).
diff --git a/ChangeLog.d/fix-tls12server-sent-sigalgs.txt b/ChangeLog.d/fix-tls12server-sent-sigalgs.txt
deleted file mode 100644
index b74c6ec..0000000
--- a/ChangeLog.d/fix-tls12server-sent-sigalgs.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
- * Fix a bug whereby the list of signature algorithms sent as part of
- the TLS 1.2 server certificate request would get corrupted, meaning the
- first algorithm would not get sent and an entry consisting of two random
- bytes would be sent instead. Found by Serban Bejan and Dudek Sebastian.
diff --git a/ChangeLog.d/fix_aead_psa_driver_build.txt b/ChangeLog.d/fix_aead_psa_driver_build.txt
deleted file mode 100644
index a6d11d3..0000000
--- a/ChangeLog.d/fix_aead_psa_driver_build.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix compilation errors when trying to build with
- PSA drivers for AEAD (GCM, CCM, Chacha20-Poly1305).
diff --git a/ChangeLog.d/fix_arm_compile_erorr.txt b/ChangeLog.d/fix_arm_compile_erorr.txt
deleted file mode 100644
index 28c1d45..0000000
--- a/ChangeLog.d/fix_arm_compile_erorr.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix a build error when compiling the bignum module for some Arm platforms.
- Fixes #6089, #6124, #6217.
diff --git a/ChangeLog.d/fix_build_error_for_mbedtls_deprecated_removed.txt b/ChangeLog.d/fix_build_error_for_mbedtls_deprecated_removed.txt
deleted file mode 100644
index f0fa000..0000000
--- a/ChangeLog.d/fix_build_error_for_mbedtls_deprecated_removed.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix a build error due to a missing prototype warning when
- MBEDTLS_DEPRECATED_REMOVED is enabled.
diff --git a/ChangeLog.d/fix_build_tls1_2_with_single_encryption_type.txt b/ChangeLog.d/fix_build_tls1_2_with_single_encryption_type.txt
deleted file mode 100644
index c7d2691..0000000
--- a/ChangeLog.d/fix_build_tls1_2_with_single_encryption_type.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix bugs and missing dependencies when building and testing
- configurations with only one encryption type enabled in TLS 1.2.
diff --git a/ChangeLog.d/fix_cmake_gen_files.txt b/ChangeLog.d/fix_cmake_gen_files.txt
deleted file mode 100644
index cdec6e8..0000000
--- a/ChangeLog.d/fix_cmake_gen_files.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix an issue with in-tree CMake builds in releases with GEN_FILES
- turned off: if a shipped file was missing from the working directory,
- it could be turned into a symbolic link to itself.
diff --git a/ChangeLog.d/fix_cmake_using_iar_toolchain.txt b/ChangeLog.d/fix_cmake_using_iar_toolchain.txt
deleted file mode 100644
index 9ec6e0d..0000000
--- a/ChangeLog.d/fix_cmake_using_iar_toolchain.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix a compilation error when using CMake with an IAR toolchain.
- Fixes #5964.
diff --git a/ChangeLog.d/fix_dh_genprime_error_reporting.txt b/ChangeLog.d/fix_dh_genprime_error_reporting.txt
deleted file mode 100644
index 1c98947..0000000
--- a/ChangeLog.d/fix_dh_genprime_error_reporting.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix bug in error reporting in dh_genprime.c where upon failure,
- the error code returned by mbedtls_mpi_write_file() is overwritten
- and therefore not printed.
diff --git a/ChangeLog.d/fix_hard_link_across_drives.txt b/ChangeLog.d/fix_hard_link_across_drives.txt
deleted file mode 100644
index 46d05c0..0000000
--- a/ChangeLog.d/fix_hard_link_across_drives.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix a build issue on Windows using CMake where the source and build
- directories could not be on different drives. Fixes #5751.
diff --git a/ChangeLog.d/fix_psa_crypto_cipher_h_include.txt b/ChangeLog.d/fix_psa_crypto_cipher_h_include.txt
deleted file mode 100644
index bf2e65d..0000000
--- a/ChangeLog.d/fix_psa_crypto_cipher_h_include.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Use double quotes to include private header file psa_crypto_cipher.h.
- Fixes 'file not found with <angled> include' error
- when building with Xcode.
diff --git a/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt b/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt
deleted file mode 100644
index 9f5c649..0000000
--- a/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix TLS 1.3 session resumption. Fixes #6488.
- * Add a configuration check to exclude optional client authentication
- in TLS 1.3 (where it is forbidden).
diff --git a/ChangeLog.d/fix_x509_get_name_mem_leak.txt b/ChangeLog.d/fix_x509_get_name_mem_leak.txt
deleted file mode 100644
index 358d1af..0000000
--- a/ChangeLog.d/fix_x509_get_name_mem_leak.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix memory leak in ssl_parse_certificate_request() caused by
- mbedtls_x509_get_name() not freeing allocated objects in case of error.
- Change mbedtls_x509_get_name() to clean up allocated objects on error.
diff --git a/ChangeLog.d/fix_x509_info_hwmodulename.txt b/ChangeLog.d/fix_x509_info_hwmodulename.txt
deleted file mode 100644
index 8b227ce..0000000
--- a/ChangeLog.d/fix_x509_info_hwmodulename.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
- * Fix a bug in which mbedtls_x509_crt_info() would produce non-printable
- bytes when parsing certificates containing a binary RFC 4108
- HardwareModuleName as a Subject Alternative Name extension. Hardware
- serial numbers are now rendered in hex format. Fixes #6262.
diff --git a/ChangeLog.d/fix_zeroization.txt b/ChangeLog.d/fix_zeroization.txt
deleted file mode 100644
index 8b00dcc..0000000
--- a/ChangeLog.d/fix_zeroization.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix a possible null pointer dereference if a memory allocation fails
- in TLS PRF code. Reported by Michael Madsen in #6516.
diff --git a/ChangeLog.d/mbedtls_asn1_type_free.txt b/ChangeLog.d/mbedtls_asn1_type_free.txt
deleted file mode 100644
index 3459bbe..0000000
--- a/ChangeLog.d/mbedtls_asn1_type_free.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Features
- * The new functions mbedtls_asn1_free_named_data_list() and
- mbedtls_asn1_free_named_data_list_shallow() simplify the management
- of memory in named data lists in X.509 structures.
-New deprecations
- * Deprecate mbedtls_asn1_free_named_data().
- Use mbedtls_asn1_free_named_data_list()
- or mbedtls_asn1_free_named_data_list_shallow().
diff --git a/ChangeLog.d/move-ssl-modules.txt b/ChangeLog.d/move-ssl-modules.txt
deleted file mode 100644
index f00e5ad..0000000
--- a/ChangeLog.d/move-ssl-modules.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Move some SSL-specific code out of libmbedcrypto where it had been placed
- accidentally.
diff --git a/ChangeLog.d/mpi-add-0-ub.txt b/ChangeLog.d/mpi-add-0-ub.txt
deleted file mode 100644
index 9f131a4..0000000
--- a/ChangeLog.d/mpi-add-0-ub.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix undefined behavior (typically harmless in practice) of
- mbedtls_mpi_add_mpi(), mbedtls_mpi_add_abs() and mbedtls_mpi_add_int()
- when both operands are 0 and the left operand is represented with 0 limbs.
diff --git a/ChangeLog.d/mpi-most-negative-sint.txt b/ChangeLog.d/mpi-most-negative-sint.txt
deleted file mode 100644
index 5e775c4..0000000
--- a/ChangeLog.d/mpi-most-negative-sint.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
- * Fix undefined behavior (typically harmless in practice) when some bignum
- functions receive the most negative value of mbedtls_mpi_sint. Credit
- to OSS-Fuzz. Fixes #6597.
diff --git a/ChangeLog.d/muladdc_microblaze.txt b/ChangeLog.d/muladdc_microblaze.txt
deleted file mode 100644
index 70fdff0..0000000
--- a/ChangeLog.d/muladdc_microblaze.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix support for little-endian Microblaze when MBEDTLS_HAVE_ASM is defined.
- Contributed by Kazuyuki Kimura to fix #2020.
diff --git a/ChangeLog.d/negative-zero-from-add.txt b/ChangeLog.d/negative-zero-from-add.txt
deleted file mode 100644
index 107d858..0000000
--- a/ChangeLog.d/negative-zero-from-add.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Bugfix
- * In the bignum module, operations of the form (-A) - (+A) or (-A) - (-A)
- with A > 0 created an unintended representation of the value 0 which was
- not processed correctly by some bignum operations. Fix this. This had no
- consequence on cryptography code, but might affect applications that call
- bignum directly and use negative numbers.
diff --git a/ChangeLog.d/nonversioned-library-soname.txt b/ChangeLog.d/nonversioned-library-soname.txt
deleted file mode 100644
index 8d83a2d..0000000
--- a/ChangeLog.d/nonversioned-library-soname.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Features
- * make: enable building unversioned shared library, with e.g.:
- "SHARED=1 SOEXT_TLS=so SOEXT_X509=so SOEXT_CRYPTO=so make lib"
- resulting in library names like "libmbedtls.so" rather than
- "libmbedcrypto.so.11".
diff --git a/ChangeLog.d/pk-sign-restartable.txt b/ChangeLog.d/pk-sign-restartable.txt
new file mode 100644
index 0000000..35da2be
--- /dev/null
+++ b/ChangeLog.d/pk-sign-restartable.txt
@@ -0,0 +1,5 @@
+Changes
+ * When MBEDTLS_USE_PSA_CRYPTO and MBEDTLS_ECDSA_DETERMINISTIC are both
+ defined, mbedtls_pk_sign() now use deterministic ECDSA for ECDSA
+ signatures. This aligns the behaviour with MBEDTLS_USE_PSA_CRYPTO to
+ the behaviour without it, where deterministic ECDSA was already used.
diff --git a/ChangeLog.d/platform-setbuf.txt b/ChangeLog.d/platform-setbuf.txt
deleted file mode 100644
index 844f70c..0000000
--- a/ChangeLog.d/platform-setbuf.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Provide the missing definition of mbedtls_setbuf() in some configurations
- with MBEDTLS_PLATFORM_C disabled. Fixes #6118, #6196.
diff --git a/ChangeLog.d/psa-ecb-ub.txt b/ChangeLog.d/psa-ecb-ub.txt
deleted file mode 100644
index 9d725ac..0000000
--- a/ChangeLog.d/psa-ecb-ub.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
- * Fix undefined behavior (typically harmless in practice) in PSA ECB
- encryption and decryption.
diff --git a/ChangeLog.d/psa_crypto_code_gen_1_1.txt b/ChangeLog.d/psa_crypto_code_gen_1_1.txt
deleted file mode 100644
index e10a81c..0000000
--- a/ChangeLog.d/psa_crypto_code_gen_1_1.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Features
- * The PSA driver wrapper generator generate_driver_wrappers.py now
- supports a subset of the driver description language, including
- the following entry points: import_key, export_key, export_public_key,
- get_builtin_key, copy_key.
-
-Requirement changes
- * When building with PSA drivers using generate_driver_wrappers.py, or
- when building the library from the development branch rather than
- from a release, the Python module jsonschema is now necessary, in
- addition to jinja2. The official list of required Python modules is
- maintained in scripts/basic.requirements.txt and may change again
- in the future.
diff --git a/ChangeLog.d/psa_crypto_pake.txt b/ChangeLog.d/psa_crypto_pake.txt
deleted file mode 100644
index e0ae046..0000000
--- a/ChangeLog.d/psa_crypto_pake.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Features
- * Expose the EC J-PAKE functionality through the Draft PSA PAKE Crypto API.
- Only the ECC primitive with secp256r1 curve and SHA-256 hash algorithm
- are supported in this implementation.
diff --git a/ChangeLog.d/psa_driver_wrapper_for_raw_key_agreement.txt b/ChangeLog.d/psa_driver_wrapper_for_raw_key_agreement.txt
deleted file mode 100644
index b9c78a6..0000000
--- a/ChangeLog.d/psa_driver_wrapper_for_raw_key_agreement.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Features
- * Add a driver dispatch layer for raw key agreement, enabling alternative
- implementations of raw key agreement through the key_agreement driver
- entry point. This entry point is specified in the proposed PSA driver
- interface, but had not yet been implemented.
diff --git a/ChangeLog.d/psa_rsa_needs_pk.txt b/ChangeLog.d/psa_rsa_needs_pk.txt
deleted file mode 100644
index 995963d..0000000
--- a/ChangeLog.d/psa_rsa_needs_pk.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
- * Fix build failure with MBEDTLS_RSA_C and MBEDTLS_PSA_CRYPTO_C but not
- MBEDTLS_USE_PSA_CRYPTO or MBEDTLS_PK_WRITE_C. Fixes #6408.
- * Fix build failure with MBEDTLS_RSA_C and MBEDTLS_PSA_CRYPTO_C but not
- MBEDTLS_PK_PARSE_C. Fixes #6409.
diff --git a/ChangeLog.d/tls13-misc.txt b/ChangeLog.d/tls13-misc.txt
deleted file mode 100644
index 6733173..0000000
--- a/ChangeLog.d/tls13-misc.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Features
- * Mbed TLS now supports TLS 1.3 key establishment via pre-shared keys.
- The pre-shared keys can be provisioned externally or via the ticket
- mechanism (session resumption).
- The ticket mechanism is supported when the configuration option
- MBEDTLS_SSL_SESSION_TICKETS is enabled.
- New options MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_xxx_ENABLED
- control the support for the three possible TLS 1.3 key exchange modes.
diff --git a/ChangeLog.d/tls13_sig_alg_selection.txt b/ChangeLog.d/tls13_sig_alg_selection.txt
deleted file mode 100644
index 8857750..0000000
--- a/ChangeLog.d/tls13_sig_alg_selection.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Features
- * Add support for opaque keys as the private keys associated to certificates
- for authentication in TLS 1.3.
diff --git a/ChangeLog.d/x509-broken-symlink-handling.txt b/ChangeLog.d/x509-broken-symlink-handling.txt
deleted file mode 100644
index 52288dc..0000000
--- a/ChangeLog.d/x509-broken-symlink-handling.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
- * Fix handling of broken symlinks when loading certificates using
- mbedtls_x509_crt_parse_path(). Instead of returning an error as soon as a
- broken link is encountered, skip the broken link and continue parsing
- other certificate files. Contributed by Eduardo Silva in #2602.
diff --git a/Makefile b/Makefile
index 5b2ad16..2f1be65 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
.SILENT:
-.PHONY: all no_test programs lib tests install uninstall clean test check covtest lcov apidoc apidoc_clean
+.PHONY: all no_test programs lib tests install uninstall clean test check lcov apidoc apidoc_clean
all: programs tests
$(MAKE) post_build
@@ -136,23 +136,15 @@
test: check
ifndef WINDOWS
-# note: for coverage testing, build with:
-# make CFLAGS='--coverage -g3 -O0'
-covtest:
- $(MAKE) check
- programs/test/selftest
- tests/compat.sh
- tests/ssl-opt.sh
-
+# For coverage testing:
+# 1. Build with:
+# make CFLAGS='--coverage -g3 -O0' LDFLAGS='--coverage'
+# 2. Run the relevant tests for the part of the code you're interested in.
+# For the reference coverage measurement, see
+# tests/scripts/basic-build-test.sh
+# 3. Run scripts/lcov.sh to generate an HTML report.
lcov:
- rm -rf Coverage
- lcov --capture --initial --directory library -o files.info
- lcov --rc lcov_branch_coverage=1 --capture --directory library -o tests.info
- lcov --rc lcov_branch_coverage=1 --add-tracefile files.info --add-tracefile tests.info -o all.info
- lcov --rc lcov_branch_coverage=1 --remove all.info -o final.info '*.h'
- gendesc tests/Descriptions.txt -o descriptions
- genhtml --title "mbed TLS" --description-file descriptions --keep-descriptions --legend --branch-coverage -o Coverage final.info
- rm -f files.info tests.info all.info final.info descriptions
+ scripts/lcov.sh
apidoc:
mkdir -p apidoc
diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md
index e565b28..c368023 100644
--- a/docs/architecture/psa-migration/psa-limitations.md
+++ b/docs/architecture/psa-migration/psa-limitations.md
@@ -17,8 +17,11 @@
There is currently no support for that in PSA at all, but it will be added at
some point, see <https://github.com/orgs/Mbed-TLS/projects/1#column-18816849>.
-Currently, `MBEDTLS_USE_PSA_CRYPTO` is simply incompatible with
-`MBEDTLS_ECP_RESTARTABLE`.
+Currently, when `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_ECP_RESTARTABLE` are
+both enabled, some operations that should be restartable are not (ECDH in TLS
+1.2 clients using ECDHE-ECDSA), as they are using PSA instead, and some
+operations that should use PSA do not (signature generation & verification) as
+they use the legacy API instead, in order to get restartable behaviour.
Things that are in the API but not implemented yet
--------------------------------------------------
diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md
index 11442ed..194d96f 100644
--- a/docs/use-psa-crypto.md
+++ b/docs/use-psa-crypto.md
@@ -7,9 +7,6 @@
General considerations
----------------------
-**Compile-time:** enabling `MBEDTLS_USE_PSA_CRYPTO` requires
-`MBEDTLS_ECP_RESTARTABLE` to be disabled.
-
**Application code:** when this option is enabled, you need to call
`psa_crypto_init()` before calling any function from the SSL/TLS, X.509 or PK
module.
@@ -86,28 +83,34 @@
Current exceptions:
-- finite-field (non-EC) Diffie-Hellman (used in key exchanges: DHE-RSA,
- DHE-PSK)
+- Finite-field (non-EC) Diffie-Hellman (used in key exchanges: DHE-RSA,
+ DHE-PSK).
+- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
+ the documentation of that option).
Other than the above exceptions, all crypto operations are based on PSA when
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
### X.509: most crypto operations based on PSA
-Current exception:
+Current exceptions:
-- verification of RSA-PSS signatures with a salt length that is different from
+- Verification of RSA-PSS signatures with a salt length that is different from
the hash length.
+- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
+ the documentation of that option).
Other than the above exception, all crypto operations are based on PSA when
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
### PK layer: most crypto operations based on PSA
-Current exception:
+Current exceptions:
-- verification of RSA-PSS signatures with a salt length that is different from
+- Verification of RSA-PSS signatures with a salt length that is different from
the hash length, or with an MGF hash that's different from the message hash.
+- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
+ the documentation of that option).
Other than the above exception, all crypto operations are based on PSA when
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index c05042b..7c6464f 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -22,7 +22,7 @@
*/
/**
- * @mainpage mbed TLS v3.2.1 source code documentation
+ * @mainpage mbed TLS v3.3.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 f722d28..0c744da 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -1,4 +1,4 @@
-PROJECT_NAME = "mbed TLS v3.2.1"
+PROJECT_NAME = "mbed TLS v3.3.0"
OUTPUT_DIRECTORY = ../apidoc/
FULL_PATH_NAMES = NO
OPTIMIZE_OUTPUT_FOR_C = YES
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index 362ce2f..049a120 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -37,17 +37,17 @@
* Major, Minor, Patchlevel
*/
#define MBEDTLS_VERSION_MAJOR 3
-#define MBEDTLS_VERSION_MINOR 2
-#define MBEDTLS_VERSION_PATCH 1
+#define MBEDTLS_VERSION_MINOR 3
+#define MBEDTLS_VERSION_PATCH 0
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x03020100
-#define MBEDTLS_VERSION_STRING "3.2.1"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.2.1"
+#define MBEDTLS_VERSION_NUMBER 0x03030000
+#define MBEDTLS_VERSION_STRING "3.3.0"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.3.0"
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index dfb4c5f..99584c4 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -117,15 +117,19 @@
#endif
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
- ( defined(MBEDTLS_USE_PSA_CRYPTO) || \
- defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
+ ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \
defined(MBEDTLS_ECDSA_SIGN_ALT) || \
defined(MBEDTLS_ECDSA_VERIFY_ALT) || \
defined(MBEDTLS_ECDSA_GENKEY_ALT) || \
defined(MBEDTLS_ECP_INTERNAL_ALT) || \
defined(MBEDTLS_ECP_ALT) )
-#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative or PSA-based ECP implementation"
+#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
+#endif
+
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+ !defined(MBEDTLS_ECP_C)
+#error "MBEDTLS_ECP_RESTARTABLE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
@@ -330,7 +334,7 @@
/* Use of EC J-PAKE in TLS requires SHA-256.
* This will be taken from MD if it is present, or from PSA if MD is absent.
- * Note: ECJPAKE_C depends on MD_C || PSA_CRYPTO_C. */
+ * Note: MBEDTLS_ECJPAKE_C depends on MBEDTLS_MD_C || MBEDTLS_PSA_CRYPTO_C. */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
!( defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C) ) && \
!( !defined(MBEDTLS_MD_C) && defined(PSA_WANT_ALG_SHA_256) )
diff --git a/include/mbedtls/legacy_or_psa.h b/include/mbedtls/legacy_or_psa.h
index f872dda..35798a5 100644
--- a/include/mbedtls/legacy_or_psa.h
+++ b/include/mbedtls/legacy_or_psa.h
@@ -64,7 +64,7 @@
* The naming scheme for these macros is:
* MBEDTLS_HAS_feature_VIA_legacy_OR_PSA(_condition)
* where:
- * - feature is expressed the same way as in PSA_WANT macros, for example:
+ * - feature is expressed the same way as in PSA_WANT_xxx macros, for example:
* KEY_TYPE_AES, ALG_SHA_256, ECC_SECP_R1_256;
* - legacy is either LOWLEVEL or the name of the layer: MD, CIPHER;
* - condition is omitted if it's based on availability, else it's
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 78c3635..b9c896f 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -690,11 +690,42 @@
* This is useful in non-threaded environments if you want to avoid blocking
* for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
*
- * Uncomment this macro to enable restartable ECC computations.
+ * This option:
+ * - Adds xxx_restartable() variants of existing operations in the
+ * following modules, with corresponding restart context types:
+ * - ECP (for Short Weierstrass curves only): scalar multiplication (mul),
+ * linear combination (muladd);
+ * - ECDSA: signature generation & verification;
+ * - PK: signature generation & verification;
+ * - X509: certificate chain verification.
+ * - Adds mbedtls_ecdh_enable_restart() in the ECDH module.
+ * - Changes the behaviour of TLS 1.2 clients (not servers) when using the
+ * ECDHE-ECDSA key exchange (not other key exchanges) to make all ECC
+ * computations restartable:
+ * - ECDH operations from the key exchange, only for Short Weierstass
+ * curves, only when MBEDTLS_USE_PSA_CRYPTO is not enabled.
+ * - verification of the server's key exchange signature;
+ * - verification of the server's certificate chain;
+ * - generation of the client's signature if client authentication is used,
+ * with an ECC key/certificate.
+ *
+ * \note In the cases above, the usual SSL/TLS functions, such as
+ * mbedtls_ssl_handshake(), can now return
+ * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS.
+ *
+ * \note When this option and MBEDTLS_USE_PSA_CRYPTO are both enabled,
+ * restartable operations in PK, X.509 and TLS (see above) are not
+ * using PSA. On the other hand, ECDH computations in TLS are using
+ * PSA, and are not restartable. These are temporary limitations that
+ * should be lifted in the future.
*
* \note This option only works with the default software implementation of
* elliptic curve functionality. It is incompatible with
* MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT.
+ *
+ * Requires: MBEDTLS_ECP_C
+ *
+ * Uncomment this macro to enable restartable ECC computations.
*/
//#define MBEDTLS_ECP_RESTARTABLE
@@ -1923,7 +1954,6 @@
* before calling any function from the SSL/TLS, X.509 or PK modules.
*
* Requires: MBEDTLS_PSA_CRYPTO_C.
- * Conflicts with: MBEDTLS_ECP_RESTARTABLE
*
* Uncomment this to enable internal use of PSA Crypto and new associated APIs.
*/
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 3f48377..7751560 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -3899,6 +3899,23 @@
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
const unsigned char *pw,
size_t pw_len );
+
+/**
+ * \brief Set the EC J-PAKE opaque password for current handshake.
+ *
+ * \note The key must remain valid until the handshake is over.
+ *
+ * \note The SSL context needs to be already set up. The right place
+ * to call this function is between \c mbedtls_ssl_setup() or
+ * \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake().
+ *
+ * \param ssl SSL context
+ * \param pwd EC J-PAKE opaque password
+ *
+ * \return 0 on success, or a negative error code.
+ */
+int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl,
+ mbedtls_svc_key_id_t pwd );
#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN)
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index c9c1ec0..cf8a7b2 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -1760,7 +1760,7 @@
#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x08000100)
/** Macro to build an HKDF algorithm.
*
- * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
+ * For example, `PSA_ALG_HKDF(PSA_ALG_SHA_256)` is HKDF using HMAC-SHA-256.
*
* This key derivation algorithm uses the following inputs:
* - #PSA_KEY_DERIVATION_INPUT_SALT is the salt used in the "extract" step.
@@ -1805,7 +1805,7 @@
#define PSA_ALG_HKDF_EXTRACT_BASE ((psa_algorithm_t)0x08000400)
/** Macro to build an HKDF-Extract algorithm.
*
- * For example, `PSA_ALG_HKDF_EXTRACT(PSA_ALG_SHA256)` is
+ * For example, `PSA_ALG_HKDF_EXTRACT(PSA_ALG_SHA_256)` is
* HKDF-Extract using HMAC-SHA-256.
*
* This key derivation algorithm uses the following inputs:
@@ -1854,7 +1854,7 @@
#define PSA_ALG_HKDF_EXPAND_BASE ((psa_algorithm_t)0x08000500)
/** Macro to build an HKDF-Expand algorithm.
*
- * For example, `PSA_ALG_HKDF_EXPAND(PSA_ALG_SHA256)` is
+ * For example, `PSA_ALG_HKDF_EXPAND(PSA_ALG_SHA_256)` is
* HKDF-Expand using HMAC-SHA-256.
*
* This key derivation algorithm uses the following inputs:
@@ -1925,7 +1925,7 @@
* concatenation of ServerHello.Random + ClientHello.Random,
* and the label is "key expansion".
*
- * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the
+ * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)` represents the
* TLS 1.2 PRF using HMAC-SHA-256.
*
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
@@ -1995,7 +1995,7 @@
* PSA_ALG_RSA_PKCS1V15_CRYPT, passed to the key derivation operation
* with `psa_key_derivation_input_bytes()`.
*
- * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the
+ * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256)` represents the
* TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256.
*
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
@@ -2050,7 +2050,7 @@
* PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2).
* This macro specifies the PBKDF2 algorithm constructed using a PRF based on
* HMAC with the specified hash.
- * For example, `PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA256)` specifies PBKDF2
+ * For example, `PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256)` specifies PBKDF2
* using the PRF HMAC-SHA-256.
*
* This key derivation algorithm uses the following inputs, which must be
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 8106dab..c9714bb 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -282,7 +282,7 @@
if(USE_SHARED_MBEDTLS_LIBRARY)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
add_library(${mbedcrypto_target} SHARED ${src_crypto})
- set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.2.1 SOVERSION 12)
+ set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.3.0 SOVERSION 13)
target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
if(TARGET everest)
@@ -290,11 +290,11 @@
endif()
add_library(${mbedx509_target} SHARED ${src_x509})
- set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.2.1 SOVERSION 4)
+ set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.3.0 SOVERSION 4)
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
add_library(${mbedtls_target} SHARED ${src_tls})
- set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.2.1 SOVERSION 18)
+ set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.3.0 SOVERSION 19)
target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
endif(USE_SHARED_MBEDTLS_LIBRARY)
diff --git a/library/Makefile b/library/Makefile
index 5073517..dd16d06 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -47,9 +47,9 @@
endif
endif
-SOEXT_TLS?=so.18
+SOEXT_TLS?=so.19
SOEXT_X509?=so.4
-SOEXT_CRYPTO?=so.12
+SOEXT_CRYPTO?=so.13
# 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 a68957a..fc4ddf6 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1590,11 +1590,11 @@
mbedtls_mpi *prec_RR )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t wbits, wsize, one = 1;
+ size_t window_bitsize;
size_t i, j, nblimbs;
size_t bufsize, nbits;
mbedtls_mpi_uint ei, mm, state;
- mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos;
+ mbedtls_mpi RR, T, W[ (size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos;
int neg;
MPI_VALIDATE_RET( X != NULL );
@@ -1623,21 +1623,59 @@
i = mbedtls_mpi_bitlen( E );
- wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
+ window_bitsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
#if( MBEDTLS_MPI_WINDOW_SIZE < 6 )
- if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
- wsize = MBEDTLS_MPI_WINDOW_SIZE;
+ if( window_bitsize > MBEDTLS_MPI_WINDOW_SIZE )
+ window_bitsize = MBEDTLS_MPI_WINDOW_SIZE;
#endif
+ const size_t w_table_used_size = (size_t) 1 << window_bitsize;
+
+ /*
+ * This function is not constant-trace: its memory accesses depend on the
+ * exponent value. To defend against timing attacks, callers (such as RSA
+ * and DHM) should use exponent blinding. However this is not enough if the
+ * adversary can find the exponent in a single trace, so this function
+ * takes extra precautions against adversaries who can observe memory
+ * access patterns.
+ *
+ * This function performs a series of multiplications by table elements and
+ * squarings, and we want the prevent the adversary from finding out which
+ * table element was used, and from distinguishing between multiplications
+ * and squarings. Firstly, when multiplying by an element of the window
+ * W[i], we do a constant-trace table lookup to obfuscate i. This leaves
+ * squarings as having a different memory access patterns from other
+ * multiplications. So secondly, we put the accumulator X in the table as
+ * well, and also do a constant-trace table lookup to multiply by X.
+ *
+ * This way, all multiplications take the form of a lookup-and-multiply.
+ * The number of lookup-and-multiply operations inside each iteration of
+ * the main loop still depends on the bits of the exponent, but since the
+ * other operations in the loop don't have an easily recognizable memory
+ * trace, an adversary is unlikely to be able to observe the exact
+ * patterns.
+ *
+ * An adversary may still be able to recover the exponent if they can
+ * observe both memory accesses and branches. However, branch prediction
+ * exploitation typically requires many traces of execution over the same
+ * data, which is defeated by randomized blinding.
+ *
+ * To achieve this, we make a copy of X and we use the table entry in each
+ * calculation from this point on.
+ */
+ const size_t x_index = 0;
+ mbedtls_mpi_init( &W[x_index] );
+ mbedtls_mpi_copy( &W[x_index], X );
+
j = N->n + 1;
/* All W[i] and X must have at least N->n limbs for the mpi_montmul()
* and mpi_montred() calls later. Here we ensure that W[1] and X are
* large enough, and later we'll grow other W[i] to the same length.
* They must not be shrunk midway through this function!
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[x_index], j ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
@@ -1686,28 +1724,36 @@
mpi_montmul( &W[1], &RR, N, mm, &T );
/*
- * X = R^2 * R^-1 mod N = R mod N
+ * W[x_index] = R^2 * R^-1 mod N = R mod N
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
- mpi_montred( X, N, mm, &T );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[x_index], &RR ) );
+ mpi_montred( &W[x_index], N, mm, &T );
- if( wsize > 1 )
+
+ if( window_bitsize > 1 )
{
/*
- * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
+ * W[i] = W[1] ^ i
+ *
+ * The first bit of the sliding window is always 1 and therefore we
+ * only need to store the second half of the table.
+ *
+ * (There are two special elements in the table: W[0] for the
+ * accumulator/result and W[1] for A in Montgomery form. Both of these
+ * are already set at this point.)
*/
- j = one << ( wsize - 1 );
+ j = w_table_used_size / 2;
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
- for( i = 0; i < wsize - 1; i++ )
+ for( i = 0; i < window_bitsize - 1; i++ )
mpi_montmul( &W[j], &W[j], N, mm, &T );
/*
* W[i] = W[i - 1] * W[1]
*/
- for( i = j + 1; i < ( one << wsize ); i++ )
+ for( i = j + 1; i < w_table_used_size; i++ )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
@@ -1719,7 +1765,7 @@
nblimbs = E->n;
bufsize = 0;
nbits = 0;
- wbits = 0;
+ size_t exponent_bits_in_window = 0;
state = 0;
while( 1 )
@@ -1747,9 +1793,10 @@
if( ei == 0 && state == 1 )
{
/*
- * out of window, square X
+ * out of window, square W[x_index]
*/
- mpi_montmul( X, X, N, mm, &T );
+ MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size, x_index ) );
+ mpi_montmul( &W[x_index], &WW, N, mm, &T );
continue;
}
@@ -1759,25 +1806,30 @@
state = 2;
nbits++;
- wbits |= ( ei << ( wsize - nbits ) );
+ exponent_bits_in_window |= ( ei << ( window_bitsize - nbits ) );
- if( nbits == wsize )
+ if( nbits == window_bitsize )
{
/*
- * X = X^wsize R^-1 mod N
+ * W[x_index] = W[x_index]^window_bitsize R^-1 mod N
*/
- for( i = 0; i < wsize; i++ )
- mpi_montmul( X, X, N, mm, &T );
+ for( i = 0; i < window_bitsize; i++ )
+ {
+ MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size,
+ x_index ) );
+ mpi_montmul( &W[x_index], &WW, N, mm, &T );
+ }
/*
- * X = X * W[wbits] R^-1 mod N
+ * W[x_index] = W[x_index] * W[exponent_bits_in_window] R^-1 mod N
*/
- MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) );
- mpi_montmul( X, &WW, N, mm, &T );
+ MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size,
+ exponent_bits_in_window ) );
+ mpi_montmul( &W[x_index], &WW, N, mm, &T );
state--;
nbits = 0;
- wbits = 0;
+ exponent_bits_in_window = 0;
}
}
@@ -1786,31 +1838,45 @@
*/
for( i = 0; i < nbits; i++ )
{
- mpi_montmul( X, X, N, mm, &T );
+ MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size, x_index ) );
+ mpi_montmul( &W[x_index], &WW, N, mm, &T );
- wbits <<= 1;
+ exponent_bits_in_window <<= 1;
- if( ( wbits & ( one << wsize ) ) != 0 )
- mpi_montmul( X, &W[1], N, mm, &T );
+ if( ( exponent_bits_in_window & ( (size_t) 1 << window_bitsize ) ) != 0 )
+ {
+ MBEDTLS_MPI_CHK( mpi_select( &WW, W, w_table_used_size, 1 ) );
+ mpi_montmul( &W[x_index], &WW, N, mm, &T );
+ }
}
/*
- * X = A^E * R * R^-1 mod N = A^E mod N
+ * W[x_index] = A^E * R * R^-1 mod N = A^E mod N
*/
- mpi_montred( X, N, mm, &T );
+ mpi_montred( &W[x_index], N, mm, &T );
if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
{
- X->s = -1;
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
+ W[x_index].s = -1;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &W[x_index], N, &W[x_index] ) );
}
+ /*
+ * Load the result in the output variable.
+ */
+ mbedtls_mpi_copy( X, &W[x_index] );
+
cleanup:
- for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
+ /* The first bit of the sliding window is always 1 and therefore the first
+ * half of the table was unused. */
+ for( i = w_table_used_size/2; i < w_table_used_size; i++ )
mbedtls_mpi_free( &W[i] );
- mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
+ mbedtls_mpi_free( &W[x_index] );
+ mbedtls_mpi_free( &W[1] );
+ mbedtls_mpi_free( &T );
+ mbedtls_mpi_free( &Apos );
mbedtls_mpi_free( &WW );
if( prec_RR == NULL || prec_RR->p == NULL )
@@ -1966,75 +2032,19 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
- int count;
- unsigned lt_lower = 1, lt_upper = 0;
- size_t n_bits = mbedtls_mpi_bitlen( N );
- size_t n_bytes = ( n_bits + 7 ) / 8;
- mbedtls_mpi lower_bound;
-
if( min < 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( N, min ) <= 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
- /*
- * When min == 0, each try has at worst a probability 1/2 of failing
- * (the msb has a probability 1/2 of being 0, and then the result will
- * be < N), so after 30 tries failure probability is a most 2**(-30).
- *
- * When N is just below a power of 2, as is the case when generating
- * a random scalar on most elliptic curves, 1 try is enough with
- * overwhelming probability. When N is just above a power of 2,
- * as when generating a random scalar on secp224k1, each try has
- * a probability of failing that is almost 1/2.
- *
- * The probabilities are almost the same if min is nonzero but negligible
- * compared to N. This is always the case when N is crypto-sized, but
- * it's convenient to support small N for testing purposes. When N
- * is small, use a higher repeat count, otherwise the probability of
- * failure is macroscopic.
- */
- count = ( n_bytes > 4 ? 30 : 250 );
-
- mbedtls_mpi_init( &lower_bound );
-
/* Ensure that target MPI has exactly the same number of limbs
* as the upper bound, even if the upper bound has leading zeros.
- * This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
- MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
+ * This is necessary for mbedtls_mpi_core_random. */
+ int ret = mbedtls_mpi_resize_clear( X, N->n );
+ if( ret != 0 )
+ return( ret );
- /*
- * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
- * when f_rng is a suitably parametrized instance of HMAC_DRBG:
- * - use the same byte ordering;
- * - keep the leftmost n_bits bits of the generated octet string;
- * - try until result is in the desired range.
- * This also avoids any bias, which is especially important for ECDSA.
- */
- do
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_core_fill_random( X->p, X->n,
- n_bytes,
- f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, 8 * n_bytes - n_bits ) );
-
- if( --count == 0 )
- {
- ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
- goto cleanup;
- }
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, <_lower ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, <_upper ) );
- }
- while( lt_lower != 0 || lt_upper == 0 );
-
-cleanup:
- mbedtls_mpi_free( &lower_bound );
- return( ret );
+ return( mbedtls_mpi_core_random( X->p, min, N->p, X->n, f_rng, p_rng ) );
}
/*
diff --git a/library/bignum_core.c b/library/bignum_core.c
index 1ce8457..064b158 100644
--- a/library/bignum_core.c
+++ b/library/bignum_core.c
@@ -134,6 +134,27 @@
}
}
+/* Whether min <= A, in constant time.
+ * A_limbs must be at least 1. */
+unsigned mbedtls_mpi_core_uint_le_mpi( mbedtls_mpi_uint min,
+ const mbedtls_mpi_uint *A,
+ size_t A_limbs )
+{
+ /* min <= least significant limb? */
+ unsigned min_le_lsl = 1 ^ mbedtls_ct_mpi_uint_lt( A[0], min );
+
+ /* limbs other than the least significant one are all zero? */
+ mbedtls_mpi_uint msll_mask = 0;
+ for( size_t i = 1; i < A_limbs; i++ )
+ msll_mask |= A[i];
+ /* The most significant limbs of A are not all zero iff msll_mask != 0. */
+ unsigned msll_nonzero = mbedtls_ct_mpi_uint_mask( msll_mask ) & 1;
+
+ /* min <= A iff the lowest limb of A is >= min or the other limbs
+ * are not all zero. */
+ return( min_le_lsl | msll_nonzero );
+}
+
void mbedtls_mpi_core_cond_assign( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
size_t limbs,
@@ -561,6 +582,67 @@
return( ret );
}
+int mbedtls_mpi_core_random( mbedtls_mpi_uint *X,
+ mbedtls_mpi_uint min,
+ const mbedtls_mpi_uint *N,
+ size_t limbs,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ unsigned ge_lower = 1, lt_upper = 0;
+ size_t n_bits = mbedtls_mpi_core_bitlen( N, limbs );
+ size_t n_bytes = ( n_bits + 7 ) / 8;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /*
+ * When min == 0, each try has at worst a probability 1/2 of failing
+ * (the msb has a probability 1/2 of being 0, and then the result will
+ * be < N), so after 30 tries failure probability is a most 2**(-30).
+ *
+ * When N is just below a power of 2, as is the case when generating
+ * a random scalar on most elliptic curves, 1 try is enough with
+ * overwhelming probability. When N is just above a power of 2,
+ * as when generating a random scalar on secp224k1, each try has
+ * a probability of failing that is almost 1/2.
+ *
+ * The probabilities are almost the same if min is nonzero but negligible
+ * compared to N. This is always the case when N is crypto-sized, but
+ * it's convenient to support small N for testing purposes. When N
+ * is small, use a higher repeat count, otherwise the probability of
+ * failure is macroscopic.
+ */
+ int count = ( n_bytes > 4 ? 30 : 250 );
+
+ /*
+ * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
+ * when f_rng is a suitably parametrized instance of HMAC_DRBG:
+ * - use the same byte ordering;
+ * - keep the leftmost n_bits bits of the generated octet string;
+ * - try until result is in the desired range.
+ * This also avoids any bias, which is especially important for ECDSA.
+ */
+ do
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_core_fill_random( X, limbs,
+ n_bytes,
+ f_rng, p_rng ) );
+ mbedtls_mpi_core_shift_r( X, limbs, 8 * n_bytes - n_bits );
+
+ if( --count == 0 )
+ {
+ ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+ goto cleanup;
+ }
+
+ ge_lower = mbedtls_mpi_core_uint_le_mpi( min, X, limbs );
+ lt_upper = mbedtls_mpi_core_lt_ct( X, N, limbs );
+ }
+ while( ge_lower == 0 || lt_upper == 0 );
+
+cleanup:
+ return( ret );
+}
+
/* BEGIN MERGE SLOT 1 */
static size_t exp_mod_get_window_size( size_t Ebits )
diff --git a/library/bignum_core.h b/library/bignum_core.h
index b7af4d0..bfc9725 100644
--- a/library/bignum_core.h
+++ b/library/bignum_core.h
@@ -129,6 +129,22 @@
void mbedtls_mpi_core_bigendian_to_host( mbedtls_mpi_uint *A,
size_t A_limbs );
+/** \brief Compare a machine integer with an MPI.
+ *
+ * This function operates in constant time with respect
+ * to the values of \p min and \p A.
+ *
+ * \param min A machine integer.
+ * \param[in] A An MPI.
+ * \param A_limbs The number of limbs of \p A.
+ * This must be at least 1.
+ *
+ * \return 1 if \p min is less than or equal to \p A, otherwise 0.
+ */
+unsigned mbedtls_mpi_core_uint_le_mpi( mbedtls_mpi_uint min,
+ const mbedtls_mpi_uint *A,
+ size_t A_limbs );
+
/**
* \brief Perform a safe conditional copy of an MPI which doesn't reveal
* whether assignment was done or not.
@@ -496,6 +512,43 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
+/** Generate a random number uniformly in a range.
+ *
+ * This function generates a random number between \p min inclusive and
+ * \p N exclusive.
+ *
+ * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA)
+ * when the RNG is a suitably parametrized instance of HMAC_DRBG
+ * and \p min is \c 1.
+ *
+ * \note There are `N - min` possible outputs. The lower bound
+ * \p min can be reached, but the upper bound \p N cannot.
+ *
+ * \param X The destination MPI, with \p limbs limbs.
+ * It must not be aliased with \p N or otherwise overlap it.
+ * \param min The minimum value to return.
+ * \param N The upper bound of the range, exclusive, with \p limbs limbs.
+ * In other words, this is one plus the maximum value to return.
+ * \p N must be strictly larger than \p min.
+ * \param limbs The number of limbs of \p N and \p X.
+ * This must not be 0.
+ * \param f_rng The RNG function to use. This must not be \c NULL.
+ * \param p_rng The RNG parameter to be passed to \p f_rng.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was
+ * unable to find a suitable value within a limited number
+ * of attempts. This has a negligible probability if \p N
+ * is significantly larger than \p min, which is the case
+ * for all usual cryptographic applications.
+ */
+int mbedtls_mpi_core_random( mbedtls_mpi_uint *X,
+ mbedtls_mpi_uint min,
+ const mbedtls_mpi_uint *N,
+ size_t limbs,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
/* BEGIN MERGE SLOT 1 */
/**
diff --git a/library/bignum_mod.c b/library/bignum_mod.c
index 7cf2fb2..0057eba 100644
--- a/library/bignum_mod.c
+++ b/library/bignum_mod.c
@@ -198,7 +198,18 @@
/* END MERGE SLOT 4 */
/* BEGIN MERGE SLOT 5 */
+int mbedtls_mpi_mod_add( mbedtls_mpi_mod_residue *X,
+ const mbedtls_mpi_mod_residue *A,
+ const mbedtls_mpi_mod_residue *B,
+ const mbedtls_mpi_mod_modulus *N )
+{
+ if( X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N);
+
+ return( 0 );
+}
/* END MERGE SLOT 5 */
/* BEGIN MERGE SLOT 6 */
diff --git a/library/bignum_mod.h b/library/bignum_mod.h
index bae671c..f089f65 100644
--- a/library/bignum_mod.h
+++ b/library/bignum_mod.h
@@ -256,7 +256,36 @@
/* END MERGE SLOT 4 */
/* BEGIN MERGE SLOT 5 */
-
+/**
+ * \brief Perform a fixed-size modular addition.
+ *
+ * Calculate `A + B modulo N`.
+ *
+ * \p A, \p B and \p X must all be associated with the modulus \p N and must
+ * all have the same number of limbs as \p N.
+ *
+ * \p X may be aliased to \p A or \p B, or even both, but may not overlap
+ * either otherwise.
+ *
+ * \note This function does not check that \p A or \p B are in canonical
+ * form (that is, are < \p N) - that will have been done by
+ * mbedtls_mpi_mod_residue_setup().
+ *
+ * \param[out] X The address of the result residue. Must be initialized.
+ * Must have the same number of limbs as the modulus \p N.
+ * \param[in] A The address of the first input residue.
+ * \param[in] B The address of the second input residue.
+ * \param[in] N The address of the modulus. Used to perform a modulo
+ * operation on the result of the addition.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the given MPIs do not
+ * have the correct number of limbs.
+ */
+int mbedtls_mpi_mod_add( mbedtls_mpi_mod_residue *X,
+ const mbedtls_mpi_mod_residue *A,
+ const mbedtls_mpi_mod_residue *B,
+ const mbedtls_mpi_mod_modulus *N );
/* END MERGE SLOT 5 */
/* BEGIN MERGE SLOT 6 */
diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c
index 266d915..c98a1c1 100644
--- a/library/bignum_mod_raw.c
+++ b/library/bignum_mod_raw.c
@@ -213,6 +213,18 @@
mbedtls_free( T );
return( 0 );
}
+
+void mbedtls_mpi_mod_raw_neg( mbedtls_mpi_uint *X,
+ const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_mod_modulus *m )
+{
+ mbedtls_mpi_core_sub( X, m->p, A, m->limbs );
+
+ /* If A=0 initially, then X=N now. Detect this by
+ * subtracting N and catching the carry. */
+ mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub( X, X, m->p, m->limbs );
+ (void) mbedtls_mpi_core_add_if( X, m->p, m->limbs, (unsigned) borrow );
+}
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */
diff --git a/library/bignum_mod_raw.h b/library/bignum_mod_raw.h
index 6f424ca..e6237b3 100644
--- a/library/bignum_mod_raw.h
+++ b/library/bignum_mod_raw.h
@@ -323,6 +323,23 @@
*/
int mbedtls_mpi_mod_raw_from_mont_rep( mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *m );
+
+/** \brief Perform fixed width modular negation.
+ *
+ * The size of the operation is determined by \p m. \p A must have
+ * the same number of limbs as \p m.
+ *
+ * \p X may be aliased to \p A.
+ *
+ * \param[out] X The result of the modular negation.
+ * This must be initialized.
+ * \param[in] A Little-endian presentation of the input operand. This
+ * must be less than or equal to \p m.
+ * \param[in] m The modulus to use.
+ */
+void mbedtls_mpi_mod_raw_neg( mbedtls_mpi_uint *X,
+ const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_mod_modulus *m);
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */
diff --git a/library/entropy.c b/library/entropy.c
index 1e0d9d3..545fd9d 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -564,7 +564,7 @@
}
/*
- * A test to ensure hat the entropy sources are functioning correctly
+ * A test to ensure that the entropy sources are functioning correctly
* and there is no obvious failure. The test performs the following checks:
* - The entropy source is not providing only 0s (all bits unset) or 1s (all
* bits set).
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 5de8fa6..ea7d726 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -1162,8 +1162,12 @@
size_t key_len;
unsigned char buf[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES];
unsigned char *p;
- psa_algorithm_t psa_sig_md =
- PSA_ALG_ECDSA( mbedtls_hash_info_psa_from_md( md_alg ) );
+ psa_algorithm_t psa_hash = mbedtls_hash_info_psa_from_md( md_alg );
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+ psa_algorithm_t psa_sig_md = PSA_ALG_DETERMINISTIC_ECDSA( psa_hash );
+#else
+ psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA( psa_hash );
+#endif
size_t curve_bits;
psa_ecc_family_t curve =
mbedtls_ecc_group_to_psa( ctx->grp.id, &curve_bits );
diff --git a/library/pkcs7.c b/library/pkcs7.c
index 5b22afa..9100980 100644
--- a/library/pkcs7.c
+++ b/library/pkcs7.c
@@ -253,6 +253,24 @@
return( 0 );
}
+static void pkcs7_free_signer_info( mbedtls_pkcs7_signer_info *signer )
+{
+ mbedtls_x509_name *name_cur;
+ mbedtls_x509_name *name_prv;
+
+ if( signer == NULL )
+ return;
+
+ name_cur = signer->issuer.next;
+ while( name_cur != NULL )
+ {
+ name_prv = name_cur;
+ name_cur = name_cur->next;
+ mbedtls_free( name_prv );
+ }
+ signer->issuer.next = NULL;
+}
+
/**
* SignerInfo ::= SEQUENCE {
* version Version;
@@ -329,33 +347,16 @@
ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
out:
- if( asn1_ret != 0 )
+ if( asn1_ret != 0 || ret != 0 )
+ {
+ pkcs7_free_signer_info( signer );
ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
asn1_ret );
- else if( ret != 0 )
- ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
+ }
return( ret );
}
-static void pkcs7_free_signer_info( mbedtls_pkcs7_signer_info *signer )
-{
- mbedtls_x509_name *name_cur;
- mbedtls_x509_name *name_prv;
-
- if( signer == NULL )
- return;
-
- name_cur = signer->issuer.next;
- while( name_cur != NULL )
- {
- name_prv = name_cur;
- name_cur = name_cur->next;
- mbedtls_free( name_prv );
- }
- signer->issuer.next = NULL;
-}
-
/**
* SignerInfos ::= SET of SignerInfo
* Return number of signers added to the signed data,
@@ -387,7 +388,7 @@
ret = pkcs7_get_signer_info( p, end_set, signers_set );
if( ret != 0 )
- goto cleanup;
+ return( ret );
count++;
mbedtls_pkcs7_signer_info *prev = signers_set;
diff --git a/library/psa_crypto_aead.h b/library/psa_crypto_aead.h
index 17b3953..70f714a 100644
--- a/library/psa_crypto_aead.h
+++ b/library/psa_crypto_aead.h
@@ -508,4 +508,4 @@
psa_status_t mbedtls_psa_aead_abort(
mbedtls_psa_aead_operation_t *operation );
-#endif /* PSA_CRYPTO_AEAD */
+#endif /* PSA_CRYPTO_AEAD_H */
diff --git a/library/psa_crypto_its.h b/library/psa_crypto_its.h
index 3a3f49a..1b8dc20 100644
--- a/library/psa_crypto_its.h
+++ b/library/psa_crypto_its.h
@@ -73,7 +73,7 @@
* \return A status indicating the success/failure of the operation
*
* \retval #PSA_SUCCESS The operation completed successfully
- * \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_WRITE_ONCE_FLAG
+ * \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_FLAG_WRITE_ONCE
* \retval #PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
@@ -137,7 +137,7 @@
*
* \retval #PSA_SUCCESS The operation completed successfully
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided key value was not found in the storage
- * \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_WRITE_ONCE_FLAG
+ * \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_FLAG_WRITE_ONCE
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
*/
psa_status_t psa_its_remove(psa_storage_uid_t uid);
diff --git a/library/psa_crypto_rsa.h b/library/psa_crypto_rsa.h
index 197caa8..5835c6f 100644
--- a/library/psa_crypto_rsa.h
+++ b/library/psa_crypto_rsa.h
@@ -249,7 +249,7 @@
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
@@ -306,7 +306,7 @@
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_TAMPERING_DETECTED
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \retval #PSA_ERROR_INVALID_PADDING
* \retval #PSA_ERROR_BAD_STATE
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 2c4ce43..e838845 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -518,18 +518,22 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
- unsigned char cookie_len = 0;
+#if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
+ uint8_t cookie_len = 0;
+#else
+ uint16_t cookie_len = 0;
+#endif /* !MBEDTLS_SSL_PROTO_TLS1_3 */
if( handshake->cookie != NULL )
{
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
handshake->cookie,
- handshake->verify_cookie_len );
- cookie_len = handshake->verify_cookie_len;
+ handshake->cookie_len );
+ cookie_len = handshake->cookie_len;
}
MBEDTLS_SSL_CHK_BUF_PTR( p, end, cookie_len + 1 );
- *p++ = cookie_len;
+ *p++ = ( unsigned char )cookie_len;
if( cookie_len > 0 )
{
memcpy( p, handshake->cookie, cookie_len );
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 5808cab..8254964 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -846,19 +846,33 @@
} buffering;
#if defined(MBEDTLS_SSL_CLI_C) && \
- ( defined(MBEDTLS_SSL_PROTO_DTLS) || defined(MBEDTLS_SSL_PROTO_TLS1_3) )
- unsigned char *cookie; /*!< HelloVerifyRequest cookie for DTLS
- * HelloRetryRequest cookie for TLS 1.3 */
+ ( defined(MBEDTLS_SSL_PROTO_DTLS) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_3) )
+ unsigned char *cookie; /*!< HelloVerifyRequest cookie for DTLS
+ * HelloRetryRequest cookie for TLS 1.3 */
+#if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
+ /* RFC 6347 page 15
+ ...
+ opaque cookie<0..2^8-1>;
+ ...
+ */
+ uint8_t cookie_len;
+#else
+ /* RFC 8446 page 39
+ ...
+ opaque cookie<0..2^16-1>;
+ ...
+ If TLS1_3 is enabled, the max length is 2^16 - 1
+ */
+ uint16_t cookie_len; /*!< DTLS: HelloVerifyRequest cookie length
+ * TLS1_3: HelloRetryRequest cookie length */
+#endif
#endif /* MBEDTLS_SSL_CLI_C &&
- ( MBEDTLS_SSL_PROTO_DTLS || MBEDTLS_SSL_PROTO_TLS1_3 ) */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- unsigned char verify_cookie_len; /*!< Cli: HelloVerifyRequest cookie
- * length
- * Srv: flag for sending a cookie */
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
- uint16_t hrr_cookie_len; /*!< HelloRetryRequest cookie length */
-#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_3 */
+ ( MBEDTLS_SSL_PROTO_DTLS ||
+ MBEDTLS_SSL_PROTO_TLS1_3 ) */
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_DTLS)
+ unsigned char cookie_verify_result; /*!< Srv: flag for sending a cookie */
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
@@ -1135,7 +1149,7 @@
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
uint8_t in_cid_len;
uint8_t out_cid_len;
- unsigned char in_cid [ MBEDTLS_SSL_CID_OUT_LEN_MAX ];
+ unsigned char in_cid [ MBEDTLS_SSL_CID_IN_LEN_MAX ];
unsigned char out_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ];
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 9bb9dc2..b757613 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1863,27 +1863,55 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-/*
- * Set EC J-PAKE password for current handshake
- */
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
-int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
- const unsigned char *pw,
- size_t pw_len )
-{
- psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_pake_role_t psa_role;
- psa_status_t status;
- if( ssl->handshake == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static psa_status_t mbedtls_ssl_set_hs_ecjpake_password_common(
+ mbedtls_ssl_context *ssl,
+ mbedtls_svc_key_id_t pwd )
+{
+ psa_status_t status;
+ psa_pake_role_t psa_role;
+ psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
+
+ psa_pake_cs_set_algorithm( &cipher_suite, PSA_ALG_JPAKE );
+ psa_pake_cs_set_primitive( &cipher_suite,
+ PSA_PAKE_PRIMITIVE( PSA_PAKE_PRIMITIVE_TYPE_ECC,
+ PSA_ECC_FAMILY_SECP_R1,
+ 256) );
+ psa_pake_cs_set_hash( &cipher_suite, PSA_ALG_SHA_256 );
+
+ status = psa_pake_setup( &ssl->handshake->psa_pake_ctx, &cipher_suite );
+ if( status != PSA_SUCCESS )
+ return status;
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
psa_role = PSA_PAKE_ROLE_SERVER;
else
psa_role = PSA_PAKE_ROLE_CLIENT;
+ status = psa_pake_set_role( &ssl->handshake->psa_pake_ctx, psa_role );
+ if( status != PSA_SUCCESS )
+ return status;
+
+ status = psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, pwd );
+ if( status != PSA_SUCCESS )
+ return status;
+
+ ssl->handshake->psa_pake_ctx_is_ok = 1;
+
+ return ( PSA_SUCCESS );
+}
+
+int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
+ const unsigned char *pw,
+ size_t pw_len )
+{
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t status;
+
+ if( ssl->handshake == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
/* Empty password is not valid */
if( ( pw == NULL) || ( pw_len == 0 ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -1897,21 +1925,8 @@
if( status != PSA_SUCCESS )
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- psa_pake_cs_set_algorithm( &cipher_suite, PSA_ALG_JPAKE );
- psa_pake_cs_set_primitive( &cipher_suite,
- PSA_PAKE_PRIMITIVE( PSA_PAKE_PRIMITIVE_TYPE_ECC,
- PSA_ECC_FAMILY_SECP_R1,
- 256) );
- psa_pake_cs_set_hash( &cipher_suite, PSA_ALG_SHA_256 );
-
- status = psa_pake_setup( &ssl->handshake->psa_pake_ctx, &cipher_suite );
- if( status != PSA_SUCCESS )
- {
- psa_destroy_key( ssl->handshake->psa_pake_password );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
-
- status = psa_pake_set_role( &ssl->handshake->psa_pake_ctx, psa_role );
+ status = mbedtls_ssl_set_hs_ecjpake_password_common( ssl,
+ ssl->handshake->psa_pake_password );
if( status != PSA_SUCCESS )
{
psa_destroy_key( ssl->handshake->psa_pake_password );
@@ -1919,17 +1934,27 @@
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
- psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx,
- ssl->handshake->psa_pake_password );
+ return( 0 );
+}
+
+int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl,
+ mbedtls_svc_key_id_t pwd )
+{
+ psa_status_t status;
+
+ if( ssl->handshake == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( mbedtls_svc_key_id_is_null( pwd ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ status = mbedtls_ssl_set_hs_ecjpake_password_common( ssl, pwd );
if( status != PSA_SUCCESS )
{
- psa_destroy_key( ssl->handshake->psa_pake_password );
psa_pake_abort( &ssl->handshake->psa_pake_ctx );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
- ssl->handshake->psa_pake_ctx_is_ok = 1;
-
return( 0 );
}
#else /* MBEDTLS_USE_PSA_CRYPTO */
@@ -1942,6 +1967,10 @@
if( ssl->handshake == NULL || ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ /* Empty password is not valid */
+ if( ( pw == NULL) || ( pw_len == 0 ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
role = MBEDTLS_ECJPAKE_SERVER;
else
@@ -3996,7 +4025,15 @@
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_pake_abort( &handshake->psa_pake_ctx );
- psa_destroy_key( handshake->psa_pake_password );
+ /*
+ * Opaque keys are not stored in the handshake's data and it's the user
+ * responsibility to destroy them. Clear ones, instead, are created by
+ * the TLS library and should be destroyed at the same level
+ */
+ if( ! mbedtls_svc_key_id_is_null( handshake->psa_pake_password ) )
+ {
+ psa_destroy_key( handshake->psa_pake_password );
+ }
handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT;
#else
mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index 7a17452..76588d3 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -1137,7 +1137,12 @@
{
const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
uint16_t dtls_legacy_version;
- unsigned char cookie_len;
+
+#if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
+ uint8_t cookie_len;
+#else
+ uint16_t cookie_len;
+#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
@@ -1200,7 +1205,7 @@
}
memcpy( ssl->handshake->cookie, p, cookie_len );
- ssl->handshake->verify_cookie_len = cookie_len;
+ ssl->handshake->cookie_len = cookie_len;
/* Start over at ClientHello */
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
@@ -1284,7 +1289,7 @@
/* We made it through the verification process */
mbedtls_free( ssl->handshake->cookie );
ssl->handshake->cookie = NULL;
- ssl->handshake->verify_cookie_len = 0;
+ ssl->handshake->cookie_len = 0;
}
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index eeb579a..5cdbcc0 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -1274,12 +1274,12 @@
ssl->cli_id, ssl->cli_id_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification failed" ) );
- ssl->handshake->verify_cookie_len = 1;
+ ssl->handshake->cookie_verify_result = 1;
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification passed" ) );
- ssl->handshake->verify_cookie_len = 0;
+ ssl->handshake->cookie_verify_result = 0;
}
}
else
@@ -2244,7 +2244,7 @@
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake->verify_cookie_len != 0 )
+ ssl->handshake->cookie_verify_result != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 0109f77..839b954 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -553,7 +553,7 @@
MBEDTLS_SSL_DEBUG_BUF( 3, "cookie extension", p, cookie_len );
mbedtls_free( handshake->cookie );
- handshake->hrr_cookie_len = 0;
+ handshake->cookie_len = 0;
handshake->cookie = mbedtls_calloc( 1, cookie_len );
if( handshake->cookie == NULL )
{
@@ -564,7 +564,7 @@
}
memcpy( handshake->cookie, p, cookie_len );
- handshake->hrr_cookie_len = cookie_len;
+ handshake->cookie_len = cookie_len;
return( 0 );
}
@@ -587,21 +587,21 @@
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
handshake->cookie,
- handshake->hrr_cookie_len );
+ handshake->cookie_len );
- MBEDTLS_SSL_CHK_BUF_PTR( p, end, handshake->hrr_cookie_len + 6 );
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, handshake->cookie_len + 6 );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding cookie extension" ) );
MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_COOKIE, p, 0 );
- MBEDTLS_PUT_UINT16_BE( handshake->hrr_cookie_len + 2, p, 2 );
- MBEDTLS_PUT_UINT16_BE( handshake->hrr_cookie_len, p, 4 );
+ MBEDTLS_PUT_UINT16_BE( handshake->cookie_len + 2, p, 2 );
+ MBEDTLS_PUT_UINT16_BE( handshake->cookie_len, p, 4 );
p += 6;
/* Cookie */
- memcpy( p, handshake->cookie, handshake->hrr_cookie_len );
+ memcpy( p, handshake->cookie, handshake->cookie_len );
- *out_len = handshake->hrr_cookie_len + 6;
+ *out_len = handshake->cookie_len + 6;
mbedtls_ssl_tls13_set_hs_sent_ext_mask( ssl, MBEDTLS_TLS_EXT_COOKIE );
diff --git a/programs/fuzz/Makefile b/programs/fuzz/Makefile
index 59a2bb7..8477aa8 100644
--- a/programs/fuzz/Makefile
+++ b/programs/fuzz/Makefile
@@ -1,7 +1,9 @@
MBEDTLS_TEST_PATH:=../../tests/src
MBEDTLS_TEST_OBJS:=$(patsubst %.c,%.o,$(wildcard ${MBEDTLS_TEST_PATH}/*.c ${MBEDTLS_TEST_PATH}/drivers/*.c))
-LOCAL_CFLAGS = -I../../tests/include -I../../include -D_FILE_OFFSET_BITS=64
+CFLAGS ?= -O2
+WARNING_CFLAGS ?= -Wall -Wextra
+LOCAL_CFLAGS = $(WARNING_CFLAGS) -I../../tests/include -I../../include -D_FILE_OFFSET_BITS=64
LOCAL_LDFLAGS = ${MBEDTLS_TEST_OBJS} \
-L../../library \
-lmbedtls$(SHARED_SUFFIX) \
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 6aa295d..02ee7cf 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -68,6 +68,7 @@
#define DFL_PSK_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
+#define DFL_ECJPAKE_PW_OPAQUE 0
#define DFL_EC_MAX_OPS -1
#define DFL_FORCE_CIPHER 0
#define DFL_TLS1_3_KEX_MODES MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL
@@ -318,11 +319,17 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
#define USAGE_ECJPAKE \
- " ecjpake_pw=%%s default: none (disabled)\n"
-#else
+ " ecjpake_pw=%%s default: none (disabled)\n" \
+ " ecjpake_pw_opaque=%%d default: 0 (disabled)\n"
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+#define USAGE_ECJPAKE \
+ " ecjpake_pw=%%s default: none (disabled)\n"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#else /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#define USAGE_ECJPAKE ""
-#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_ECP_RESTARTABLE)
#define USAGE_ECRESTART \
@@ -492,6 +499,9 @@
const char *psk; /* the pre-shared key */
const char *psk_identity; /* the pre-shared key identity */
const char *ecjpake_pw; /* the EC J-PAKE password */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ int ecjpake_pw_opaque; /* set to 1 to use the opaque method for setting the password */
+#endif
int ec_max_ops; /* EC consecutive operations limit */
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
@@ -824,6 +834,10 @@
MBEDTLS_TLS_SRTP_UNSET
};
#endif /* MBEDTLS_SSL_DTLS_SRTP */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+ mbedtls_svc_key_id_t ecjpake_pw_slot = MBEDTLS_SVC_KEY_ID_INIT; /* ecjpake password key slot */
+#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
@@ -919,6 +933,9 @@
#endif
opt.psk_identity = DFL_PSK_IDENTITY;
opt.ecjpake_pw = DFL_ECJPAKE_PW;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ opt.ecjpake_pw_opaque = DFL_ECJPAKE_PW_OPAQUE;
+#endif
opt.ec_max_ops = DFL_EC_MAX_OPS;
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
@@ -1094,6 +1111,10 @@
opt.psk_identity = q;
else if( strcmp( p, "ecjpake_pw" ) == 0 )
opt.ecjpake_pw = q;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ else if( strcmp( p, "ecjpake_pw_opaque" ) == 0 )
+ opt.ecjpake_pw_opaque = atoi( q );
+#endif
else if( strcmp( p, "ec_max_ops" ) == 0 )
opt.ec_max_ops = atoi( q );
else if( strcmp( p, "force_ciphersuite" ) == 0 )
@@ -2166,16 +2187,46 @@
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
{
- if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
- (const unsigned char *) opt.ecjpake_pw,
- strlen( opt.ecjpake_pw ) ) ) != 0 )
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE )
{
- mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n",
- ret );
- goto exit;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
+ psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE );
+ psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD );
+
+ status = psa_import_key( &attributes,
+ (const unsigned char *) opt.ecjpake_pw,
+ strlen( opt.ecjpake_pw ),
+ &ecjpake_pw_slot );
+ if( status != PSA_SUCCESS )
+ {
+ mbedtls_printf( " failed\n ! psa_import_key returned %d\n\n",
+ status );
+ goto exit;
+ }
+ if( ( ret = mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl,
+ ecjpake_pw_slot ) ) != 0 )
+ {
+ mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password_opaque returned %d\n\n", ret );
+ goto exit;
+ }
+ mbedtls_printf( "using opaque password\n");
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+ if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
+ (const unsigned char *) opt.ecjpake_pw,
+ strlen( opt.ecjpake_pw ) ) ) != 0 )
+ {
+ mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
+ goto exit;
+ }
}
}
-#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
if( opt.context_crt_cb == 1 )
@@ -3276,6 +3327,31 @@
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED &&
MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+ /*
+ * In case opaque keys it's the user responsibility to keep the key valid
+ * for the duration of the handshake and destroy it at the end
+ */
+ if( ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) )
+ {
+ psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* Verify that the key is still valid before destroying it */
+ if( psa_get_key_attributes( ecjpake_pw_slot, &check_attributes ) !=
+ PSA_SUCCESS )
+ {
+ if( ret == 0 )
+ ret = 1;
+ mbedtls_printf( "The EC J-PAKE password key has unexpectedly been already destroyed\n" );
+ }
+ else
+ {
+ psa_destroy_key( ecjpake_pw_slot );
+ }
+ }
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
const char* message = mbedtls_test_helper_is_psa_leaking();
if( message )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 00624b5..802beb2 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -98,6 +98,7 @@
#define DFL_PSK_LIST_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL
+#define DFL_ECJPAKE_PW_OPAQUE 0
#define DFL_PSK_LIST NULL
#define DFL_FORCE_CIPHER 0
#define DFL_TLS1_3_KEX_MODES MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL
@@ -419,11 +420,17 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
#define USAGE_ECJPAKE \
- " ecjpake_pw=%%s default: none (disabled)\n"
-#else
+ " ecjpake_pw=%%s default: none (disabled)\n" \
+ " ecjpake_pw_opaque=%%d default: 0 (disabled)\n"
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+#define USAGE_ECJPAKE \
+ " ecjpake_pw=%%s default: none (disabled)\n"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#else /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#define USAGE_ECJPAKE ""
-#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_EARLY_DATA)
#define USAGE_EARLY_DATA \
@@ -631,6 +638,9 @@
const char *psk_identity; /* the pre-shared key identity */
char *psk_list; /* list of PSK id/key pairs for callback */
const char *ecjpake_pw; /* the EC J-PAKE password */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ int ecjpake_pw_opaque; /* set to 1 to use the opaque method for setting the password */
+#endif
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
int tls13_kex_modes; /* supported TLS 1.3 key exchange modes */
@@ -1517,6 +1527,10 @@
unsigned char *context_buf = NULL;
size_t context_buf_len = 0;
#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+ mbedtls_svc_key_id_t ecjpake_pw_slot = MBEDTLS_SVC_KEY_ID_INIT; /* ecjpake password key slot */
+#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
uint16_t sig_alg_list[SIG_ALG_LIST_SIZE];
@@ -1675,6 +1689,9 @@
opt.psk_identity = DFL_PSK_IDENTITY;
opt.psk_list = DFL_PSK_LIST;
opt.ecjpake_pw = DFL_ECJPAKE_PW;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ opt.ecjpake_pw_opaque = DFL_ECJPAKE_PW_OPAQUE;
+#endif
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
opt.tls13_kex_modes = DFL_TLS1_3_KEX_MODES;
@@ -1879,6 +1896,10 @@
opt.psk_list = q;
else if( strcmp( p, "ecjpake_pw" ) == 0 )
opt.ecjpake_pw = q;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ else if( strcmp( p, "ecjpake_pw_opaque" ) == 0 )
+ opt.ecjpake_pw_opaque = atoi( q );
+#endif
else if( strcmp( p, "force_ciphersuite" ) == 0 )
{
opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q );
@@ -3528,15 +3549,46 @@
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
{
- if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
- (const unsigned char *) opt.ecjpake_pw,
- strlen( opt.ecjpake_pw ) ) ) != 0 )
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE )
{
- mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
- goto exit;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
+ psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE );
+ psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD );
+
+ status = psa_import_key( &attributes,
+ (const unsigned char *) opt.ecjpake_pw,
+ strlen( opt.ecjpake_pw ),
+ &ecjpake_pw_slot );
+ if( status != PSA_SUCCESS )
+ {
+ mbedtls_printf( " failed\n ! psa_import_key returned %d\n\n",
+ status );
+ goto exit;
+ }
+ if( ( ret = mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl,
+ ecjpake_pw_slot ) ) != 0 )
+ {
+ mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password_opaque returned %d\n\n", ret );
+ goto exit;
+ }
+ mbedtls_printf( "using opaque password\n");
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+ if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
+ (const unsigned char *) opt.ecjpake_pw,
+ strlen( opt.ecjpake_pw ) ) ) != 0 )
+ {
+ mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
+ goto exit;
+ }
}
}
-#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
@@ -4422,6 +4474,31 @@
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED &&
MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+ /*
+ * In case opaque keys it's the user responsibility to keep the key valid
+ * for the duration of the handshake and destroy it at the end
+ */
+ if( ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) )
+ {
+ psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* Verify that the key is still valid before destroying it */
+ if( psa_get_key_attributes( ecjpake_pw_slot, &check_attributes ) !=
+ PSA_SUCCESS )
+ {
+ if( ret == 0 )
+ ret = 1;
+ mbedtls_printf( "The EC J-PAKE password key has unexpectedly been already destroyed\n" );
+ }
+ else
+ {
+ psa_destroy_key( ecjpake_pw_slot );
+ }
+ }
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
const char* message = mbedtls_test_helper_is_psa_leaking();
if( message )
diff --git a/programs/test/cmake_package_install/CMakeLists.txt b/programs/test/cmake_package_install/CMakeLists.txt
index 711a1e5..fb5ad51 100644
--- a/programs/test/cmake_package_install/CMakeLists.txt
+++ b/programs/test/cmake_package_install/CMakeLists.txt
@@ -26,7 +26,7 @@
# Locate the package.
#
-set(MbedTLS_DIR "${MbedTLS_INSTALL_DIR}/cmake")
+list(INSERT CMAKE_PREFIX_PATH 0 "${MbedTLS_INSTALL_DIR}")
find_package(MbedTLS REQUIRED)
#
diff --git a/scripts/config.py b/scripts/config.py
index 7e58acd..a53c470 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -194,7 +194,6 @@
'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options
'MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED', # influences the use of ECDH in TLS
'MBEDTLS_ECP_NO_FALLBACK', # removes internal ECP implementation
- 'MBEDTLS_ECP_RESTARTABLE', # incompatible with USE_PSA_CRYPTO
'MBEDTLS_ENTROPY_FORCE_SHA256', # interacts with CTR_DRBG_128_BIT_KEY
'MBEDTLS_HAVE_SSE2', # hardware dependency
'MBEDTLS_MEMORY_BACKTRACE', # depends on MEMORY_BUFFER_ALLOC_C
diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
index 3ad92aa..e716e40 100644
--- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
@@ -291,7 +291,7 @@
alg, hash, hash_length,
signature, signature_size, signature_length ) );
}
-#endif /* PSA_CRYPTO_SE_C */
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
@@ -375,7 +375,7 @@
alg, hash, hash_length,
signature, signature_length ) );
}
-#endif /* PSA_CRYPTO_SE_C */
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
@@ -647,7 +647,7 @@
return( PSA_SUCCESS );
}
-#endif /* PSA_CRYPTO_SE_C */
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
switch( location )
{
@@ -715,7 +715,7 @@
*( (psa_key_slot_number_t *)key_buffer ),
data, data_size, data_length ) );
}
-#endif /* PSA_CRYPTO_SE_C */
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
switch( location )
{
diff --git a/scripts/lcov.sh b/scripts/lcov.sh
new file mode 100755
index 0000000..8d141ee
--- /dev/null
+++ b/scripts/lcov.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+help () {
+ cat <<EOF
+Usage: $0 [-r]
+Collect coverage statistics of library code into an HTML report.
+
+General instructions:
+1. Build the library with CFLAGS="--coverage -O0 -g3" and link the test
+ programs with LDFLAGS="--coverage".
+ This can be an out-of-tree build.
+ For example (in-tree):
+ make CFLAGS="--coverage -O0 -g3" LDFLAGS="--coverage"
+ Or (out-of-tree):
+ mkdir build-coverage && cd build-coverage &&
+ cmake -D CMAKE_BUILD_TYPE=Coverage .. && make
+2. Run whatever tests you want.
+3. Run this script from the parent of the directory containing the library
+ object files and coverage statistics files.
+4. Browse the coverage report in Coverage/index.html.
+5. After rework, run "$0 -r", then re-test and run "$0" to get a fresh report.
+
+Options
+ -r Reset traces. Run this before re-testing to get fresh measurements.
+EOF
+}
+
+# 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.
+
+set -eu
+
+# Collect stats and build a HTML report.
+lcov_library_report () {
+ rm -rf Coverage
+ mkdir Coverage Coverage/tmp
+ lcov --capture --initial --directory library -o Coverage/tmp/files.info
+ lcov --rc lcov_branch_coverage=1 --capture --directory library -o Coverage/tmp/tests.info
+ lcov --rc lcov_branch_coverage=1 --add-tracefile Coverage/tmp/files.info --add-tracefile Coverage/tmp/tests.info -o Coverage/tmp/all.info
+ lcov --rc lcov_branch_coverage=1 --remove Coverage/tmp/all.info -o Coverage/tmp/final.info '*.h'
+ gendesc tests/Descriptions.txt -o Coverage/tmp/descriptions
+ genhtml --title "mbed TLS" --description-file Coverage/tmp/descriptions --keep-descriptions --legend --branch-coverage -o Coverage Coverage/tmp/final.info
+ rm -f Coverage/tmp/*.info Coverage/tmp/descriptions
+ echo "Coverage report in: Coverage/index.html"
+}
+
+# Reset the traces to 0.
+lcov_reset_traces () {
+ # Location with plain make
+ rm -f library/*.gcda
+ # Location with CMake
+ rm -f library/CMakeFiles/*.dir/*.gcda
+}
+
+if [ $# -gt 0 ] && [ "$1" = "--help" ]; then
+ help
+ exit
+fi
+
+main=lcov_library_report
+while getopts r OPTLET; do
+ case $OPTLET in
+ r) main=lcov_reset_traces;;
+ *) help 2>&1; exit 120;;
+ esac
+done
+shift $((OPTIND - 1))
+
+"$main" "$@"
diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py
index 118a659..158ada9 100644
--- a/scripts/mbedtls_dev/bignum_core.py
+++ b/scripts/mbedtls_dev/bignum_core.py
@@ -130,24 +130,20 @@
class BignumCoreSub(BignumCoreTarget, bignum_common.OperationCommon):
"""Test cases for bignum core sub."""
count = 0
+ input_style = "arch_split"
symbol = "-"
test_function = "mpi_core_sub"
test_name = "mbedtls_mpi_core_sub"
def result(self) -> List[str]:
if self.int_a >= self.int_b:
- result_4 = result_8 = self.int_a - self.int_b
+ result = self.int_a - self.int_b
carry = 0
else:
- bound_val = max(self.int_a, self.int_b)
- bound_4 = bignum_common.bound_mpi(bound_val, 32)
- result_4 = bound_4 + self.int_a - self.int_b
- bound_8 = bignum_common.bound_mpi(bound_val, 64)
- result_8 = bound_8 + self.int_a - self.int_b
+ result = self.limb_boundary + self.int_a - self.int_b
carry = 1
return [
- "\"{:x}\"".format(result_4),
- "\"{:x}\"".format(result_8),
+ self.format_result(result),
str(carry)
]
diff --git a/scripts/mbedtls_dev/bignum_mod.py b/scripts/mbedtls_dev/bignum_mod.py
index aa06fe8..a16699a 100644
--- a/scripts/mbedtls_dev/bignum_mod.py
+++ b/scripts/mbedtls_dev/bignum_mod.py
@@ -14,10 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Dict, List # pylint: disable=unused-import
+from typing import Dict, List
from . import test_data_generation
-from . import bignum_common # pylint: disable=unused-import
+from . import bignum_common
class BignumModTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
@@ -55,6 +55,20 @@
# END MERGE SLOT 4
# BEGIN MERGE SLOT 5
+class BignumModAdd(bignum_common.ModOperationCommon, BignumModTarget):
+ """Test cases for bignum mpi_mod_add()."""
+ count = 0
+ symbol = "+"
+ test_function = "mpi_mod_add"
+ test_name = "mbedtls_mpi_mod_add"
+ input_style = "fixed"
+
+ def result(self) -> List[str]:
+ result = (self.int_a + self.int_b) % self.int_n
+ # To make negative tests easier, append "0" for success to the
+ # generated cases
+ return [self.format_result(result), "0"]
+
# END MERGE SLOT 5
diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py
index 0486426..6fc4c91 100644
--- a/scripts/mbedtls_dev/bignum_mod_raw.py
+++ b/scripts/mbedtls_dev/bignum_mod_raw.py
@@ -137,7 +137,18 @@
result = self.from_montgomery(self.int_a)
return [self.format_result(result)]
+class BignumModRawModNegate(bignum_common.ModOperationCommon,
+ BignumModRawTarget):
+ """ Test cases for mpi_mod_raw_neg(). """
+ test_function = "mpi_mod_raw_neg"
+ test_name = "Modular negation: "
+ symbol = "-"
+ input_style = "arch_split"
+ arity = 1
+ def result(self) -> List[str]:
+ result = (self.int_n - self.int_a) % self.int_n
+ return [self.format_result(result)]
# END MERGE SLOT 7
# BEGIN MERGE SLOT 8
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 71dd70b..4a7de82 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -243,6 +243,7 @@
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/seedfile")
link_to_source(seedfile)
endif()
+ link_to_source(Descriptions.txt)
link_to_source(compat.sh)
link_to_source(context-info.sh)
link_to_source(data_files)
diff --git a/tests/Makefile b/tests/Makefile
index 2d2d70a..f037338 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -165,6 +165,7 @@
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $<
C_FILES := $(addsuffix .c,$(APPS))
+c: $(C_FILES)
# Wildcard target for test code generation:
# A .c file is generated for each .data file in the suites/ directory. Each .c
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index db46b03..584906a 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -872,12 +872,6 @@
fi
tests/scripts/check_test_cases.py $opt
unset opt
-
- # Check that no tests are explicitely disabled when USE_PSA_CRYPTO is set
- # as a matter of policy to ensure there is no missed testing
- msg "Check: explicitely disabled test with USE_PSA_CRYPTO" # < 1s
- not grep -n 'depends_on:.*!MBEDTLS_USE_PSA_CRYPTO' tests/suites/*.function tests/suites/*.data
- not grep -n '^ *requires_config_disabled.*MBEDTLS_USE_PSA_CRYPTO' tests/ssl-opt.sh tests/opt-testcases/*.sh
}
component_check_doxygen_warnings () {
@@ -1457,10 +1451,14 @@
make -C programs ssl/ssl_server2 ssl/ssl_client2
make -C programs test/udp_proxy test/query_compile_time_config
- msg "test: server w/o USE_PSA - client w/ USE_PSA"
- P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f ECJPAKE
- msg "test: client w/o USE_PSA - server w/ USE_PSA"
- P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f ECJPAKE
+ msg "test: server w/o USE_PSA - client w/ USE_PSA, text password"
+ P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS"
+ msg "test: server w/o USE_PSA - client w/ USE_PSA, opaque password"
+ P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: opaque password client only, working, TLS"
+ msg "test: client w/o USE_PSA - server w/ USE_PSA, text password"
+ P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS"
+ msg "test: client w/o USE_PSA - server w/ USE_PSA, opaque password"
+ P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: opaque password server only, working, TLS"
rm s2_no_use_psa c2_no_use_psa
}
@@ -1889,10 +1887,13 @@
component_build_module_alt () {
msg "build: MBEDTLS_XXX_ALT" # ~30s
scripts/config.py full
- # Disable options that are incompatible with some ALT implementations.
+
+ # Disable options that are incompatible with some ALT implementations:
# aesni.c and padlock.c reference mbedtls_aes_context fields directly.
scripts/config.py unset MBEDTLS_AESNI_C
scripts/config.py unset MBEDTLS_PADLOCK_C
+ # MBEDTLS_ECP_RESTARTABLE is documented as incompatible.
+ scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
# You can only have one threading implementation: alt or pthread, not both.
scripts/config.py unset MBEDTLS_THREADING_PTHREAD
# The SpecifiedECDomain parsing code accesses mbedtls_ecp_group fields
@@ -1904,10 +1905,12 @@
# MBEDTLS_SHA512_*ALT can't be used with MBEDTLS_SHA512_USE_A64_CRYPTO_*
scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
+
# Enable all MBEDTLS_XXX_ALT for whole modules. Do not enable
# MBEDTLS_XXX_YYY_ALT which are for single functions.
scripts/config.py set-all 'MBEDTLS_([A-Z0-9]*|NIST_KW)_ALT'
scripts/config.py unset MBEDTLS_DHM_ALT #incompatible with MBEDTLS_DEBUG_C
+
# We can only compile, not link, since we don't have any implementations
# suitable for testing with the dummy alt headers.
make CC=gcc CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy' lib
@@ -1928,7 +1931,6 @@
# full minus MBEDTLS_USE_PSA_CRYPTO: run the same set of tests as basic-build-test.sh
msg "build: cmake, full config minus MBEDTLS_USE_PSA_CRYPTO, ASan"
scripts/config.py full
- scripts/config.py set MBEDTLS_ECP_RESTARTABLE # not using PSA, so enable restartable ECC
scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
@@ -1943,6 +1945,9 @@
msg "test: main suites (full minus MBEDTLS_USE_PSA_CRYPTO)"
make test
+ # Note: ssl-opt.sh has some test cases that depend on
+ # MBEDTLS_ECP_RESTARTABLE && !MBEDTLS_USE_PSA_CRYPTO
+ # This is the only component where those tests are not skipped.
msg "test: ssl-opt.sh (full minus MBEDTLS_USE_PSA_CRYPTO)"
tests/ssl-opt.sh
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
index 920537e..13b6c2d 100755
--- a/tests/scripts/check_names.py
+++ b/tests/scripts/check_names.py
@@ -36,7 +36,7 @@
declared in the header files. This uses the nm command.
- All macros, constants, and identifiers (function names, struct names, etc)
follow the required regex pattern.
-- Typo checking: All words that begin with MBED exist as macros or constants.
+- Typo checking: All words that begin with MBED|PSA exist as macros or constants.
The script returns 0 on success, 1 on test failure, and 2 if there is a script
error. It must be run from Mbed TLS root.
@@ -191,11 +191,12 @@
class Typo(Problem): # pylint: disable=too-few-public-methods
"""
- A problem that occurs when a word using MBED doesn't appear to be defined as
- constants nor enum values. Created with NameCheck.check_for_typos()
+ A problem that occurs when a word using MBED or PSA doesn't
+ appear to be defined as constants nor enum values. Created with
+ NameCheck.check_for_typos()
Fields:
- * match: the Match object of the MBED name in question.
+ * match: the Match object of the MBED|PSA name in question.
"""
def __init__(self, match):
self.match = match
@@ -245,7 +246,7 @@
.format(str(self.excluded_files))
)
- all_macros = {"public": [], "internal": []}
+ all_macros = {"public": [], "internal": [], "private":[]}
all_macros["public"] = self.parse_macros([
"include/mbedtls/*.h",
"include/psa/*.h",
@@ -256,9 +257,14 @@
"library/*.h",
"tests/include/test/drivers/*.h",
])
+ all_macros["private"] = self.parse_macros([
+ "library/*.c",
+ ])
enum_consts = self.parse_enum_consts([
"include/mbedtls/*.h",
+ "include/psa/*.h",
"library/*.h",
+ "library/*.c",
"3rdparty/everest/include/everest/everest.h",
"3rdparty/everest/include/everest/x25519.h"
])
@@ -269,7 +275,7 @@
"3rdparty/everest/include/everest/everest.h",
"3rdparty/everest/include/everest/x25519.h"
])
- mbed_words = self.parse_mbed_words([
+ mbed_psa_words = self.parse_mbed_psa_words([
"include/mbedtls/*.h",
"include/psa/*.h",
"library/*.h",
@@ -302,10 +308,11 @@
return {
"public_macros": actual_macros["public"],
"internal_macros": actual_macros["internal"],
+ "private_macros": all_macros["private"],
"enum_consts": enum_consts,
"identifiers": identifiers,
"symbols": symbols,
- "mbed_words": mbed_words
+ "mbed_psa_words": mbed_psa_words
}
def is_file_excluded(self, path, exclude_wildcards):
@@ -373,25 +380,28 @@
return macros
- def parse_mbed_words(self, include, exclude=None):
+ def parse_mbed_psa_words(self, include, exclude=None):
"""
- Parse all words in the file that begin with MBED, in and out of macros,
- comments, anything.
+ Parse all words in the file that begin with MBED|PSA, in and out of
+ macros, comments, anything.
Args:
* include: A List of glob expressions to look for files through.
* exclude: A List of glob expressions for excluding files.
- Returns a List of Match objects for words beginning with MBED.
+ Returns a List of Match objects for words beginning with MBED|PSA.
"""
# Typos of TLS are common, hence the broader check below than MBEDTLS.
- mbed_regex = re.compile(r"\bMBED.+?_[A-Z0-9_]*")
+ mbed_regex = re.compile(r"\b(MBED.+?|PSA)_[A-Z0-9_]*")
exclusions = re.compile(r"// *no-check-names|#error")
files = self.get_files(include, exclude)
- self.log.debug("Looking for MBED words in {} files".format(len(files)))
+ self.log.debug(
+ "Looking for MBED|PSA words in {} files"
+ .format(len(files))
+ )
- mbed_words = []
+ mbed_psa_words = []
for filename in files:
with open(filename, "r", encoding="utf-8") as fp:
for line_no, line in enumerate(fp):
@@ -399,14 +409,14 @@
continue
for name in mbed_regex.finditer(line):
- mbed_words.append(Match(
+ mbed_psa_words.append(Match(
filename,
line,
line_no,
name.span(0),
name.group(0)))
- return mbed_words
+ return mbed_psa_words
def parse_enum_consts(self, include, exclude=None):
"""
@@ -832,12 +842,14 @@
for match
in self.parse_result["public_macros"] +
self.parse_result["internal_macros"] +
+ self.parse_result["private_macros"] +
self.parse_result["enum_consts"]
}
typo_exclusion = re.compile(r"XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$|"
- r"MBEDTLS_TEST_LIBTESTDRIVER*")
+ r"MBEDTLS_TEST_LIBTESTDRIVER*|"
+ r"PSA_CRYPTO_DRIVER_TEST")
- for name_match in self.parse_result["mbed_words"]:
+ for name_match in self.parse_result["mbed_psa_words"]:
found = name_match.name in all_caps_names
# Since MBEDTLS_PSA_ACCEL_XXX defines are defined by the
diff --git a/tests/scripts/depends.py b/tests/scripts/depends.py
index 0d6ec94..d09b732 100755
--- a/tests/scripts/depends.py
+++ b/tests/scripts/depends.py
@@ -234,6 +234,7 @@
'MBEDTLS_ECP_C': ['MBEDTLS_ECDSA_C',
'MBEDTLS_ECDH_C',
'MBEDTLS_ECJPAKE_C',
+ 'MBEDTLS_ECP_RESTARTABLE',
'MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED',
diff --git a/tests/scripts/generate_test_code.py b/tests/scripts/generate_test_code.py
index 938f24c..f19d30b 100755
--- a/tests/scripts/generate_test_code.py
+++ b/tests/scripts/generate_test_code.py
@@ -220,25 +220,17 @@
:param file_name: File path to open.
"""
- super(FileWrapper, self).__init__(file_name, 'r')
+ super().__init__(file_name, 'r')
self._line_no = 0
- def next(self):
+ def __next__(self):
"""
- Python 2 iterator method. This method overrides base class's
- next method and extends the next method to count the line
- numbers as each line is read.
-
- It works for both Python 2 and Python 3 by checking iterator
- method name in the base iterator object.
+ This method overrides base class's __next__ method and extends it
+ method to count the line numbers as each line is read.
:return: Line read from file.
"""
- parent = super(FileWrapper, self)
- if hasattr(parent, '__next__'):
- line = parent.__next__() # Python 3
- else:
- line = parent.next() # Python 2 # pylint: disable=no-member
+ line = super().__next__()
if line is not None:
self._line_no += 1
# Convert byte array to string with correct encoding and
@@ -246,9 +238,6 @@
return line.decode(sys.getdefaultencoding()).rstrip() + '\n'
return None
- # Python 3 iterator method
- __next__ = next
-
def get_line_no(self):
"""
Gives current line number.
@@ -530,6 +519,50 @@
gen_dependencies(dependencies)
return preprocessor_check_start + code + preprocessor_check_end
+COMMENT_START_REGEX = re.compile(r'/[*/]')
+
+def skip_comments(line, stream):
+ """Remove comments in line.
+
+ If the line contains an unfinished comment, read more lines from stream
+ until the line that contains the comment.
+
+ :return: The original line with inner comments replaced by spaces.
+ Trailing comments and whitespace may be removed completely.
+ """
+ pos = 0
+ while True:
+ opening = COMMENT_START_REGEX.search(line, pos)
+ if not opening:
+ break
+ if line[opening.start(0) + 1] == '/': # //...
+ continuation = line
+ # Count the number of line breaks, to keep line numbers aligned
+ # in the output.
+ line_count = 1
+ while continuation.endswith('\\\n'):
+ # This errors out if the file ends with an unfinished line
+ # comment. That's acceptable to not complicate the code further.
+ continuation = next(stream)
+ line_count += 1
+ return line[:opening.start(0)].rstrip() + '\n' * line_count
+ # Parsing /*...*/, looking for the end
+ closing = line.find('*/', opening.end(0))
+ while closing == -1:
+ # This errors out if the file ends with an unfinished block
+ # comment. That's acceptable to not complicate the code further.
+ line += next(stream)
+ closing = line.find('*/', opening.end(0))
+ pos = closing + 2
+ # Replace inner comment by spaces. There needs to be at least one space
+ # for things like 'int/*ihatespaces*/foo'. Go further and preserve the
+ # width of the comment and line breaks, this way positions in error
+ # messages remain correct.
+ line = (line[:opening.start(0)] +
+ re.sub(r'.', r' ', line[opening.start(0):pos]) +
+ line[pos:])
+ # Strip whitespace at the end of lines (it's irrelevant to error messages).
+ return re.sub(r' +(\n|\Z)', r'\1', line)
def parse_function_code(funcs_f, dependencies, suite_dependencies):
"""
@@ -549,6 +582,7 @@
# across multiple lines. Here we try to find the start of
# arguments list, then remove '\n's and apply the regex to
# detect function start.
+ line = skip_comments(line, funcs_f)
up_to_arg_list_start = code + line[:line.find('(') + 1]
match = re.match(TEST_FUNCTION_VALIDATION_REGEX,
up_to_arg_list_start.replace('\n', ' '), re.I)
@@ -557,7 +591,7 @@
name = match.group('func_name')
if not re.match(FUNCTION_ARG_LIST_END_REGEX, line):
for lin in funcs_f:
- line += lin
+ line += skip_comments(lin, funcs_f)
if re.search(FUNCTION_ARG_LIST_END_REGEX, line):
break
args, local_vars, args_dispatch = parse_function_arguments(
diff --git a/tests/scripts/test_generate_test_code.py b/tests/scripts/test_generate_test_code.py
index 9bf66f1..d23d742 100755
--- a/tests/scripts/test_generate_test_code.py
+++ b/tests/scripts/test_generate_test_code.py
@@ -682,12 +682,12 @@
@patch("generate_test_code.gen_dependencies")
@patch("generate_test_code.gen_function_wrapper")
@patch("generate_test_code.parse_function_arguments")
- def test_functio_name_on_newline(self, parse_function_arguments_mock,
- gen_function_wrapper_mock,
- gen_dependencies_mock,
- gen_dispatch_mock):
+ def test_function_name_on_newline(self, parse_function_arguments_mock,
+ gen_function_wrapper_mock,
+ gen_dependencies_mock,
+ gen_dispatch_mock):
"""
- Test when exit label is present.
+ Test with line break before the function name.
:return:
"""
parse_function_arguments_mock.return_value = ([], '', [])
@@ -727,6 +727,194 @@
'''
self.assertEqual(code, expected)
+ @patch("generate_test_code.gen_dispatch")
+ @patch("generate_test_code.gen_dependencies")
+ @patch("generate_test_code.gen_function_wrapper")
+ @patch("generate_test_code.parse_function_arguments")
+ def test_case_starting_with_comment(self, parse_function_arguments_mock,
+ gen_function_wrapper_mock,
+ gen_dependencies_mock,
+ gen_dispatch_mock):
+ """
+ Test with comments before the function signature
+ :return:
+ """
+ parse_function_arguments_mock.return_value = ([], '', [])
+ gen_function_wrapper_mock.return_value = ''
+ gen_dependencies_mock.side_effect = gen_dependencies
+ gen_dispatch_mock.side_effect = gen_dispatch
+ data = '''/* comment */
+/* more
+ * comment */
+// this is\\
+still \\
+a comment
+void func()
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ _, _, code, _ = parse_function_code(stream, [], [])
+
+ expected = '''#line 1 "test_suite_ut.function"
+
+
+
+
+
+
+void test_func()
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+'''
+ self.assertEqual(code, expected)
+
+ @patch("generate_test_code.gen_dispatch")
+ @patch("generate_test_code.gen_dependencies")
+ @patch("generate_test_code.gen_function_wrapper")
+ @patch("generate_test_code.parse_function_arguments")
+ def test_comment_in_prototype(self, parse_function_arguments_mock,
+ gen_function_wrapper_mock,
+ gen_dependencies_mock,
+ gen_dispatch_mock):
+ """
+ Test with comments in the function prototype
+ :return:
+ """
+ parse_function_arguments_mock.return_value = ([], '', [])
+ gen_function_wrapper_mock.return_value = ''
+ gen_dependencies_mock.side_effect = gen_dependencies
+ gen_dispatch_mock.side_effect = gen_dispatch
+ data = '''
+void func( int x, // (line \\
+ comment)
+ int y /* lone closing parenthesis) */ )
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ _, _, code, _ = parse_function_code(stream, [], [])
+
+ expected = '''#line 1 "test_suite_ut.function"
+
+void test_func( int x,
+
+ int y )
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+'''
+ self.assertEqual(code, expected)
+
+ @patch("generate_test_code.gen_dispatch")
+ @patch("generate_test_code.gen_dependencies")
+ @patch("generate_test_code.gen_function_wrapper")
+ @patch("generate_test_code.parse_function_arguments")
+ def test_line_comment_in_block_comment(self, parse_function_arguments_mock,
+ gen_function_wrapper_mock,
+ gen_dependencies_mock,
+ gen_dispatch_mock):
+ """
+ Test with line comment in block comment.
+ :return:
+ """
+ parse_function_arguments_mock.return_value = ([], '', [])
+ gen_function_wrapper_mock.return_value = ''
+ gen_dependencies_mock.side_effect = gen_dependencies
+ gen_dispatch_mock.side_effect = gen_dispatch
+ data = '''
+void func( int x /* // */ )
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ _, _, code, _ = parse_function_code(stream, [], [])
+
+ expected = '''#line 1 "test_suite_ut.function"
+
+void test_func( int x )
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+'''
+ self.assertEqual(code, expected)
+
+ @patch("generate_test_code.gen_dispatch")
+ @patch("generate_test_code.gen_dependencies")
+ @patch("generate_test_code.gen_function_wrapper")
+ @patch("generate_test_code.parse_function_arguments")
+ def test_block_comment_in_line_comment(self, parse_function_arguments_mock,
+ gen_function_wrapper_mock,
+ gen_dependencies_mock,
+ gen_dispatch_mock):
+ """
+ Test with block comment in line comment.
+ :return:
+ """
+ parse_function_arguments_mock.return_value = ([], '', [])
+ gen_function_wrapper_mock.return_value = ''
+ gen_dependencies_mock.side_effect = gen_dependencies
+ gen_dispatch_mock.side_effect = gen_dispatch
+ data = '''
+// /*
+void func( int x )
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+/* END_CASE */
+'''
+ stream = StringIOWrapper('test_suite_ut.function', data)
+ _, _, code, _ = parse_function_code(stream, [], [])
+
+ expected = '''#line 1 "test_suite_ut.function"
+
+
+void test_func( int x )
+{
+ ba ba black sheep
+ have you any wool
+exit:
+ yes sir yes sir
+ 3 bags full
+}
+'''
+ self.assertEqual(code, expected)
+
class ParseFunction(TestCase):
"""
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 1fe8bae..0d4ce6e 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -7986,6 +7986,8 @@
-C "found ecjpake_kkpp extension" \
-s "SSL - The handshake negotiation failed"
+# Note: if the name of this test is changed, then please adjust the corresponding
+# filtering label in "test_tls1_2_ecjpake_compatibility" (in "all.sh")
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "ECJPAKE: working, TLS" \
@@ -8004,6 +8006,73 @@
-S "SSL - The handshake negotiation failed" \
-S "SSL - Verification of the message MAC failed"
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test "ECJPAKE: opaque password client+server, working, TLS" \
+ "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \
+ "$P_CLI debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1\
+ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
+ 0 \
+ -c "add ciphersuite: c0ff" \
+ -c "adding ecjpake_kkpp extension" \
+ -c "using opaque password" \
+ -s "using opaque password" \
+ -C "re-using cached ecjpake parameters" \
+ -s "found ecjpake kkpp extension" \
+ -S "skip ecjpake kkpp extension" \
+ -S "ciphersuite mismatch: ecjpake not configured" \
+ -s "server hello, ecjpake kkpp extension" \
+ -c "found ecjpake_kkpp extension" \
+ -S "SSL - The handshake negotiation failed" \
+ -S "SSL - Verification of the message MAC failed"
+
+# Note: if the name of this test is changed, then please adjust the corresponding
+# filtering label in "test_tls1_2_ecjpake_compatibility" (in "all.sh")
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test "ECJPAKE: opaque password client only, working, TLS" \
+ "$P_SRV debug_level=3 ecjpake_pw=bla" \
+ "$P_CLI debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1\
+ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
+ 0 \
+ -c "add ciphersuite: c0ff" \
+ -c "adding ecjpake_kkpp extension" \
+ -c "using opaque password" \
+ -S "using opaque password" \
+ -C "re-using cached ecjpake parameters" \
+ -s "found ecjpake kkpp extension" \
+ -S "skip ecjpake kkpp extension" \
+ -S "ciphersuite mismatch: ecjpake not configured" \
+ -s "server hello, ecjpake kkpp extension" \
+ -c "found ecjpake_kkpp extension" \
+ -S "SSL - The handshake negotiation failed" \
+ -S "SSL - Verification of the message MAC failed"
+
+# Note: if the name of this test is changed, then please adjust the corresponding
+# filtering label in "test_tls1_2_ecjpake_compatibility" (in "all.sh")
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test "ECJPAKE: opaque password server only, working, TLS" \
+ "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \
+ "$P_CLI debug_level=3 ecjpake_pw=bla\
+ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
+ 0 \
+ -c "add ciphersuite: c0ff" \
+ -c "adding ecjpake_kkpp extension" \
+ -C "using opaque password" \
+ -s "using opaque password" \
+ -C "re-using cached ecjpake parameters" \
+ -s "found ecjpake kkpp extension" \
+ -S "skip ecjpake kkpp extension" \
+ -S "ciphersuite mismatch: ecjpake not configured" \
+ -s "server hello, ecjpake kkpp extension" \
+ -c "found ecjpake_kkpp extension" \
+ -S "SSL - The handshake negotiation failed" \
+ -S "SSL - Verification of the message MAC failed"
+
server_needs_more_time 1
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
@@ -8015,6 +8084,20 @@
-C "re-using cached ecjpake parameters" \
-s "SSL - Verification of the message MAC failed"
+server_needs_more_time 1
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test "ECJPAKE_OPAQUE_PW: opaque password mismatch, TLS" \
+ "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \
+ "$P_CLI debug_level=3 ecjpake_pw=bad ecjpake_pw_opaque=1 \
+ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \
+ 1 \
+ -c "using opaque password" \
+ -s "using opaque password" \
+ -C "re-using cached ecjpake parameters" \
+ -s "SSL - Verification of the message MAC failed"
+
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "ECJPAKE: working, DTLS" \
@@ -8395,10 +8478,12 @@
-C "mbedtls_ecdh_make_public.*4b00" \
-C "mbedtls_pk_sign.*4b00"
+# With USE_PSA disabled we expect full restartable behaviour.
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000" \
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000 (no USE_PSA)" \
"$P_SRV curves=secp256r1 auth_mode=required" \
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
key_file=data_files/server5.key crt_file=data_files/server5.crt \
@@ -8409,6 +8494,25 @@
-c "mbedtls_ecdh_make_public.*4b00" \
-c "mbedtls_pk_sign.*4b00"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000 (USE_PSA)" \
+ "$P_SRV curves=secp256r1 auth_mode=required" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ debug_level=1 ec_max_ops=1000" \
+ 0 \
+ -c "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -c "mbedtls_pk_sign.*4b00"
+
+# This works the same with & without USE_PSA as we never get to ECDH:
+# we abort as soon as we determined the cert is bad.
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
@@ -8428,10 +8532,12 @@
-c "! mbedtls_ssl_handshake returned" \
-c "X509 - Certificate verification failed"
+# With USE_PSA disabled we expect full restartable behaviour.
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000, auth_mode=optional badsign" \
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000, auth_mode=optional badsign (no USE_PSA)" \
"$P_SRV curves=secp256r1 auth_mode=required \
crt_file=data_files/server5-badsign.crt \
key_file=data_files/server5.key" \
@@ -8447,10 +8553,34 @@
-C "! mbedtls_ssl_handshake returned" \
-C "X509 - Certificate verification failed"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000, auth_mode=none badsign" \
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000, auth_mode=optional badsign (USE_PSA)" \
+ "$P_SRV curves=secp256r1 auth_mode=required \
+ crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ debug_level=1 ec_max_ops=1000 auth_mode=optional" \
+ 0 \
+ -c "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -c "mbedtls_pk_sign.*4b00" \
+ -c "! The certificate is not correctly signed by the trusted CA" \
+ -C "! mbedtls_ssl_handshake returned" \
+ -C "X509 - Certificate verification failed"
+
+# With USE_PSA disabled we expect full restartable behaviour.
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000, auth_mode=none badsign (no USE_PSA)" \
"$P_SRV curves=secp256r1 auth_mode=required \
crt_file=data_files/server5-badsign.crt \
key_file=data_files/server5.key" \
@@ -8466,10 +8596,34 @@
-C "! mbedtls_ssl_handshake returned" \
-C "X509 - Certificate verification failed"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: DTLS, max_ops=1000" \
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000, auth_mode=none badsign (USE_PSA)" \
+ "$P_SRV curves=secp256r1 auth_mode=required \
+ crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ debug_level=1 ec_max_ops=1000 auth_mode=none" \
+ 0 \
+ -C "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -c "mbedtls_pk_sign.*4b00" \
+ -C "! The certificate is not correctly signed by the trusted CA" \
+ -C "! mbedtls_ssl_handshake returned" \
+ -C "X509 - Certificate verification failed"
+
+# With USE_PSA disabled we expect full restartable behaviour.
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: DTLS, max_ops=1000 (no USE_PSA)" \
"$P_SRV curves=secp256r1 auth_mode=required dtls=1" \
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
key_file=data_files/server5.key crt_file=data_files/server5.crt \
@@ -8480,10 +8634,29 @@
-c "mbedtls_ecdh_make_public.*4b00" \
-c "mbedtls_pk_sign.*4b00"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000 no client auth" \
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: DTLS, max_ops=1000 (USE_PSA)" \
+ "$P_SRV curves=secp256r1 auth_mode=required dtls=1" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ dtls=1 debug_level=1 ec_max_ops=1000" \
+ 0 \
+ -c "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -c "mbedtls_pk_sign.*4b00"
+
+# With USE_PSA disabled we expect full restartable behaviour.
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000 no client auth (no USE_PSA)" \
"$P_SRV curves=secp256r1" \
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
debug_level=1 ec_max_ops=1000" \
@@ -8493,13 +8666,35 @@
-c "mbedtls_ecdh_make_public.*4b00" \
-C "mbedtls_pk_sign.*4b00"
+
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000, ECDHE-PSK" \
- "$P_SRV curves=secp256r1 psk=abc123" \
- "$P_CLI force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256 \
- psk=abc123 debug_level=1 ec_max_ops=1000" \
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000 no client auth (USE_PSA)" \
+ "$P_SRV curves=secp256r1" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ debug_level=1 ec_max_ops=1000" \
+ 0 \
+ -c "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -C "mbedtls_pk_sign.*4b00"
+
+# Restartable is only for ECDHE-ECDSA, with another ciphersuite we expect no
+# restartable behaviour at all (not even client auth).
+# This is the same as "EC restart: TLS, max_ops=1000" except with ECDHE-RSA,
+# and all 4 assertions negated.
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+run_test "EC restart: TLS, max_ops=1000, ECDHE-RSA" \
+ "$P_SRV curves=secp256r1 auth_mode=required" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ debug_level=1 ec_max_ops=1000" \
0 \
-C "x509_verify_cert.*4b00" \
-C "mbedtls_pk_verify.*4b00" \
diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function
index 55bb2f5..01af2ff 100644
--- a/tests/suites/test_suite_bignum.function
+++ b/tests/suites/test_suite_bignum.function
@@ -2,6 +2,7 @@
#include "mbedtls/bignum.h"
#include "mbedtls/entropy.h"
#include "constant_time_internal.h"
+#include "bignum_core.h"
#include "test/constant_flow.h"
#if MBEDTLS_MPI_MAX_BITS > 792
@@ -89,50 +90,6 @@
return( 0 );
}
-/* Test whether bytes represents (in big-endian base 256) a number b that
- * is significantly above a power of 2. That is, b must not have a long run
- * of unset bits after the most significant bit.
- *
- * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
- * This function returns 1 if, when drawing a number between 0 and b,
- * the probability that this number is at least 2^n is not negligible.
- * This probability is (b - 2^n) / b and this function checks that this
- * number is above some threshold A. The threshold value is heuristic and
- * based on the needs of mpi_random_many().
- */
-static int is_significantly_above_a_power_of_2( data_t *bytes )
-{
- const uint8_t *p = bytes->x;
- size_t len = bytes->len;
- unsigned x;
-
- /* Skip leading null bytes */
- while( len > 0 && p[0] == 0 )
- {
- ++p;
- --len;
- }
- /* 0 is not significantly above a power of 2 */
- if( len == 0 )
- return( 0 );
- /* Extract the (up to) 2 most significant bytes */
- if( len == 1 )
- x = p[0];
- else
- x = ( p[0] << 8 ) | p[1];
-
- /* Shift the most significant bit of x to position 8 and mask it out */
- while( ( x & 0xfe00 ) != 0 )
- x >>= 1;
- x &= 0x00ff;
-
- /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
- * a power of 2 iff x is significantly above 0 compared to 2^8.
- * Testing x >= 2^4 amounts to picking A = 1/16 in the function
- * description above. */
- return( x >= 0x10 );
-}
-
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -1295,170 +1252,6 @@
/* END_CASE */
/* BEGIN_CASE */
-void mpi_random_many( int min, data_t *bound_bytes, int iterations )
-{
- /* Generate numbers in the range 1..bound-1. Do it iterations times.
- * This function assumes that the value of bound is at least 2 and
- * that iterations is large enough that a one-in-2^iterations chance
- * effectively never occurs.
- */
-
- mbedtls_mpi upper_bound;
- size_t n_bits;
- mbedtls_mpi result;
- size_t b;
- /* If upper_bound is small, stats[b] is the number of times the value b
- * has been generated. Otherwise stats[b] is the number of times a
- * value with bit b set has been generated. */
- size_t *stats = NULL;
- size_t stats_len;
- int full_stats;
- size_t i;
-
- mbedtls_mpi_init( &upper_bound );
- mbedtls_mpi_init( &result );
-
- TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
- bound_bytes->x, bound_bytes->len ) );
- n_bits = mbedtls_mpi_bitlen( &upper_bound );
- /* Consider a bound "small" if it's less than 2^5. This value is chosen
- * to be small enough that the probability of missing one value is
- * negligible given the number of iterations. It must be less than
- * 256 because some of the code below assumes that "small" values
- * fit in a byte. */
- if( n_bits <= 5 )
- {
- full_stats = 1;
- stats_len = bound_bytes->x[bound_bytes->len - 1];
- }
- else
- {
- full_stats = 0;
- stats_len = n_bits;
- }
- ASSERT_ALLOC( stats, stats_len );
-
- for( i = 0; i < (size_t) iterations; i++ )
- {
- mbedtls_test_set_step( i );
- TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
- mbedtls_test_rnd_std_rand, NULL ) );
-
- TEST_ASSERT( sign_is_valid( &result ) );
- TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
- TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
- if( full_stats )
- {
- uint8_t value;
- TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
- TEST_ASSERT( value < stats_len );
- ++stats[value];
- }
- else
- {
- for( b = 0; b < n_bits; b++ )
- stats[b] += mbedtls_mpi_get_bit( &result, b );
- }
- }
-
- if( full_stats )
- {
- for( b = min; b < stats_len; b++ )
- {
- mbedtls_test_set_step( 1000000 + b );
- /* Assert that each value has been reached at least once.
- * This is almost guaranteed if the iteration count is large
- * enough. This is a very crude way of checking the distribution.
- */
- TEST_ASSERT( stats[b] > 0 );
- }
- }
- else
- {
- int statistically_safe_all_the_way =
- is_significantly_above_a_power_of_2( bound_bytes );
- for( b = 0; b < n_bits; b++ )
- {
- mbedtls_test_set_step( 1000000 + b );
- /* Assert that each bit has been set in at least one result and
- * clear in at least one result. Provided that iterations is not
- * too small, it would be extremely unlikely for this not to be
- * the case if the results are uniformly distributed.
- *
- * As an exception, the top bit may legitimately never be set
- * if bound is a power of 2 or only slightly above.
- */
- if( statistically_safe_all_the_way || b != n_bits - 1 )
- {
- TEST_ASSERT( stats[b] > 0 );
- }
- TEST_ASSERT( stats[b] < (size_t) iterations );
- }
- }
-
-exit:
- mbedtls_mpi_free( &upper_bound );
- mbedtls_mpi_free( &result );
- mbedtls_free( stats );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
-{
- mbedtls_mpi upper_bound;
- mbedtls_mpi result;
-
- mbedtls_mpi_init( &upper_bound );
- mbedtls_mpi_init( &result );
-
- if( before != 0 )
- {
- /* Set result to sign(before) * 2^(|before|-1) */
- TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
- if( before < 0 )
- before = - before;
- TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
- }
-
- TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
- TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
- bound_bytes->x, bound_bytes->len ) );
- TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
- mbedtls_test_rnd_std_rand, NULL ) );
- TEST_ASSERT( sign_is_valid( &result ) );
- TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
- TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
-
-exit:
- mbedtls_mpi_free( &upper_bound );
- mbedtls_mpi_free( &result );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
-{
- mbedtls_mpi upper_bound;
- mbedtls_mpi result;
- int actual_ret;
-
- mbedtls_mpi_init( &upper_bound );
- mbedtls_mpi_init( &result );
-
- TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
- bound_bytes->x, bound_bytes->len ) );
- actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
- mbedtls_test_rnd_std_rand, NULL );
- TEST_EQUAL( expected_ret, actual_ret );
-
-exit:
- mbedtls_mpi_free( &upper_bound );
- mbedtls_mpi_free( &result );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
void most_negative_mpi_sint( )
{
/* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
@@ -1481,7 +1274,6 @@
mbedtls_mpi_init( &R );
mbedtls_mpi_init( &X );
- const size_t biL = 8 * sizeof( mbedtls_mpi_sint );
mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << ( biL - 1 );
const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
const mbedtls_mpi_sint most_negative = - most_positive - 1;
diff --git a/tests/suites/test_suite_bignum.misc.data b/tests/suites/test_suite_bignum.misc.data
index dc6830e..5eda4c1 100644
--- a/tests/suites/test_suite_bignum.misc.data
+++ b/tests/suites/test_suite_bignum.misc.data
@@ -1788,176 +1788,6 @@
Fill random: MAX_SIZE bytes, RNG failure after MAX_SIZE-1 bytes
mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE-1:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
-MPI random in range: 1..2
-mpi_random_many:1:"02":1000
-
-MPI random in range: 1..3
-mpi_random_many:1:"03":1000
-
-MPI random in range: 1..4
-mpi_random_many:1:"04":1000
-
-MPI random in range: 1..5
-mpi_random_many:1:"05":1000
-
-MPI random in range: 1..6
-mpi_random_many:1:"06":1000
-
-MPI random in range: 1..7
-mpi_random_many:1:"07":1000
-
-MPI random in range: 1..8
-mpi_random_many:1:"08":1000
-
-MPI random in range: 1..9
-mpi_random_many:1:"09":1000
-
-MPI random in range: 1..10
-mpi_random_many:1:"0a":1000
-
-MPI random in range: 1..11
-mpi_random_many:1:"0b":1000
-
-MPI random in range: 1..12
-mpi_random_many:1:"0c":1000
-
-MPI random in range: 1..255
-mpi_random_many:1:"ff":200
-
-MPI random in range: 1..256
-mpi_random_many:1:"0100":200
-
-MPI random in range: 1..257
-mpi_random_many:1:"0101":200
-
-MPI random in range: 1..272
-mpi_random_many:1:"0110":200
-
-MPI random in range: 1..2^64-1
-mpi_random_many:1:"ffffffffffffffff":100
-
-MPI random in range: 1..2^64
-mpi_random_many:1:"010000000000000000":100
-
-MPI random in range: 1..2^64+1
-mpi_random_many:1:"010000000000000001":100
-
-MPI random in range: 1..2^64+2^63
-mpi_random_many:1:"018000000000000000":100
-
-MPI random in range: 1..2^65-1
-mpi_random_many:1:"01ffffffffffffffff":100
-
-MPI random in range: 1..2^65
-mpi_random_many:1:"020000000000000000":100
-
-MPI random in range: 1..2^65+1
-mpi_random_many:1:"020000000000000001":100
-
-MPI random in range: 1..2^65+2^64
-mpi_random_many:1:"030000000000000000":100
-
-MPI random in range: 1..2^66+2^65
-mpi_random_many:1:"060000000000000000":100
-
-MPI random in range: 1..2^71-1
-mpi_random_many:1:"7fffffffffffffffff":100
-
-MPI random in range: 1..2^71
-mpi_random_many:1:"800000000000000000":100
-
-MPI random in range: 1..2^71+1
-mpi_random_many:1:"800000000000000001":100
-
-MPI random in range: 1..2^71+2^70
-mpi_random_many:1:"c00000000000000000":100
-
-MPI random in range: 1..2^72-1
-mpi_random_many:1:"ffffffffffffffffff":100
-
-MPI random in range: 1..2^72
-mpi_random_many:1:"01000000000000000000":100
-
-MPI random in range: 1..2^72+1
-mpi_random_many:1:"01000000000000000001":100
-
-MPI random in range: 1..2^72+2^71
-mpi_random_many:1:"01800000000000000000":100
-
-MPI random in range: 0..1
-mpi_random_many:0:"04":10000
-
-MPI random in range: 0..4
-mpi_random_many:0:"04":10000
-
-MPI random in range: 2..4
-mpi_random_many:2:"04":10000
-
-MPI random in range: 3..4
-mpi_random_many:3:"04":10000
-
-MPI random in range: smaller result
-mpi_random_sizes:1:"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb":1:0
-
-MPI random in range: same size result (32-bit limbs)
-mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":2:0
-
-MPI random in range: same size result (64-bit limbs)
-mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":1:0
-
-MPI random in range: larger result
-mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":3:0
-
-## The "0 limb in upper bound" tests rely on the fact that
-## mbedtls_mpi_read_binary() bases the size of the MPI on the size of
-## the input, without first checking for leading zeros. If this was
-## not the case, the tests would still pass, but would not exercise
-## the advertised behavior.
-MPI random in range: leading 0 limb in upper bound #0
-mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":0:0
-
-MPI random in range: leading 0 limb in upper bound #1
-mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":1:0
-
-MPI random in range: leading 0 limb in upper bound #2
-mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":2:0
-
-MPI random in range: leading 0 limb in upper bound #3
-mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":3:0
-
-MPI random in range: leading 0 limb in upper bound #4
-mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":4:0
-
-MPI random in range: previously small >0
-mpi_random_sizes:1:"1234567890":4:1
-
-MPI random in range: previously small <0
-mpi_random_sizes:1:"1234567890":4:-1
-
-MPI random in range: previously large >0
-mpi_random_sizes:1:"1234":4:65
-
-MPI random in range: previously large <0
-mpi_random_sizes:1:"1234":4:-65
-
-MPI random bad arguments: min < 0
-mpi_random_fail:-1:"04":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
-
-MPI random bad arguments: min = N = 0
-mpi_random_fail:0:"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
-
-MPI random bad arguments: min = N = 1
-mpi_random_fail:1:"01":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
-
-MPI random bad arguments: min > N = 0
-mpi_random_fail:1:"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
-
-MPI random bad arguments: min > N = 1
-mpi_random_fail:2:"01":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
-
-MPI random bad arguments: min > N = 1, 0 limb in upper bound
-mpi_random_fail:2:"000000000000000001":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
-
Most negative mbedtls_mpi_sint
most_negative_mpi_sint:
diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function
index 7bf03fb..9cb314b 100644
--- a/tests/suites/test_suite_bignum_core.function
+++ b/tests/suites/test_suite_bignum_core.function
@@ -345,6 +345,56 @@
/* END_CASE */
/* BEGIN_CASE */
+void mpi_core_uint_le_mpi( char *input_A )
+{
+ mbedtls_mpi_uint *A = NULL;
+ size_t A_limbs = 0;
+
+ TEST_EQUAL( mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ), 0 );
+
+ int is_large = 0; /* nonzero limbs beyond the lowest-order one? */
+ for( size_t i = 1; i < A_limbs; i++ )
+ {
+ if( A[i] != 0 )
+ {
+ is_large = 1;
+ break;
+ }
+ }
+
+ TEST_CF_SECRET( A, A_limbs * sizeof( *A ) );
+
+ TEST_EQUAL( mbedtls_mpi_core_uint_le_mpi( 0, A, A_limbs ), 1 );
+ TEST_EQUAL( mbedtls_mpi_core_uint_le_mpi( A[0], A, A_limbs ), 1 );
+
+ if( is_large )
+ {
+ TEST_EQUAL( mbedtls_mpi_core_uint_le_mpi( A[0] + 1,
+ A, A_limbs ), 1 );
+ TEST_EQUAL( mbedtls_mpi_core_uint_le_mpi( (mbedtls_mpi_uint)( -1 ) >> 1,
+ A, A_limbs ), 1 );
+ TEST_EQUAL( mbedtls_mpi_core_uint_le_mpi( (mbedtls_mpi_uint)( -1 ),
+ A, A_limbs ), 1 );
+ }
+ else
+ {
+ TEST_EQUAL( mbedtls_mpi_core_uint_le_mpi( A[0] + 1,
+ A, A_limbs ),
+ A[0] + 1 <= A[0] );
+ TEST_EQUAL( mbedtls_mpi_core_uint_le_mpi( (mbedtls_mpi_uint)( -1 ) >> 1,
+ A, A_limbs ),
+ (mbedtls_mpi_uint)( -1 ) >> 1 <= A[0] );
+ TEST_EQUAL( mbedtls_mpi_core_uint_le_mpi( (mbedtls_mpi_uint)( -1 ),
+ A, A_limbs ),
+ (mbedtls_mpi_uint)( -1 ) <= A[0] );
+ }
+
+exit:
+ mbedtls_free( A );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mpi_core_cond_assign( char * input_X,
char * input_Y,
int input_bytes )
@@ -533,10 +583,9 @@
/* BEGIN_CASE */
void mpi_core_sub( char * input_A, char * input_B,
- char * input_X4, char * input_X8,
- int carry )
+ char * input_X, int carry )
{
- mbedtls_mpi A, B, X4, X8;
+ mbedtls_mpi A, B, X;
mbedtls_mpi_uint *a = NULL;
mbedtls_mpi_uint *b = NULL;
mbedtls_mpi_uint *x = NULL; /* expected */
@@ -544,29 +593,23 @@
mbedtls_mpi_init( &A );
mbedtls_mpi_init( &B );
- mbedtls_mpi_init( &X4 );
- mbedtls_mpi_init( &X8 );
+ mbedtls_mpi_init( &X );
TEST_EQUAL( 0, mbedtls_test_read_mpi( &A, input_A ) );
TEST_EQUAL( 0, mbedtls_test_read_mpi( &B, input_B ) );
- TEST_EQUAL( 0, mbedtls_test_read_mpi( &X4, input_X4 ) );
- TEST_EQUAL( 0, mbedtls_test_read_mpi( &X8, input_X8 ) );
+ TEST_EQUAL( 0, mbedtls_test_read_mpi( &X, input_X ) );
/* All of the inputs are +ve (or zero) */
TEST_EQUAL( 1, A.s );
TEST_EQUAL( 1, B.s );
- TEST_EQUAL( 1, X4.s );
- TEST_EQUAL( 1, X8.s );
+ TEST_EQUAL( 1, X.s );
/* Get the number of limbs we will need */
size_t limbs = MAX( A.n, B.n );
size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
- /* We only need to work with X4 or X8, depending on sizeof(mbedtls_mpi_uint) */
- mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &X4 : &X8;
-
/* The result shouldn't have more limbs than the longest input */
- TEST_LE_U( X->n, limbs );
+ TEST_LE_U( X.n, limbs );
/* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
@@ -582,7 +625,7 @@
*/
memcpy( a, A.p, A.n * sizeof(mbedtls_mpi_uint) );
memcpy( b, B.p, B.n * sizeof(mbedtls_mpi_uint) );
- memcpy( x, X->p, X->n * sizeof(mbedtls_mpi_uint) );
+ memcpy( x, X.p, X.n * sizeof(mbedtls_mpi_uint) );
/* 1a) r = a - b => we should get the correct carry */
TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, a, b, limbs ) );
@@ -621,8 +664,7 @@
mbedtls_mpi_free( &A );
mbedtls_mpi_free( &B );
- mbedtls_mpi_free( &X4 );
- mbedtls_mpi_free( &X8 );
+ mbedtls_mpi_free( &X );
}
/* END_CASE */
diff --git a/tests/suites/test_suite_bignum_core.misc.data b/tests/suites/test_suite_bignum_core.misc.data
index 62480e4..81a767a 100644
--- a/tests/suites/test_suite_bignum_core.misc.data
+++ b/tests/suites/test_suite_bignum_core.misc.data
@@ -242,6 +242,69 @@
mbedtls_mpi_core_lt_ct: x>y (alternating limbs)
mpi_core_lt_ct:"FF1111111111111111":"11FFFFFFFFFFFFFFFF":0
+Test mbedtls_mpi_core_uint_le_mpi: 0 (1 limb)
+mpi_core_uint_le_mpi:"00"
+
+Test mbedtls_mpi_core_uint_le_mpi: 0 (>=2 limbs)
+mpi_core_uint_le_mpi:"000000000000000000"
+
+Test mbedtls_mpi_core_uint_le_mpi: 1 (1 limb)
+mpi_core_uint_le_mpi:"01"
+
+Test mbedtls_mpi_core_uint_le_mpi: 1 (>=2 limbs)
+mpi_core_uint_le_mpi:"000000000000000001"
+
+Test mbedtls_mpi_core_uint_le_mpi: 42 (1 limb)
+mpi_core_uint_le_mpi:"2a"
+
+Test mbedtls_mpi_core_uint_le_mpi: 42 (>=2 limbs)
+mpi_core_uint_le_mpi:"000000000000000042"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^31-1
+mpi_core_uint_le_mpi:"7fffffff"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^31-1 with leading zero limb
+mpi_core_uint_le_mpi:"00000000007fffffff"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^32-1
+mpi_core_uint_le_mpi:"ffffffff"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^32-1 with leading zero limb
+mpi_core_uint_le_mpi:"0000000000ffffffff"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^32
+mpi_core_uint_le_mpi:"10000000"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^32 with leading zero limb
+mpi_core_uint_le_mpi:"000000000010000000"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^32+1
+mpi_core_uint_le_mpi:"10000001"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^32+1 with leading zero limb
+mpi_core_uint_le_mpi:"000000000010000001"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^63-1
+mpi_core_uint_le_mpi:"7fffffffffffffff"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^63-1 with leading zero limb
+mpi_core_uint_le_mpi:"007fffffffffffffff"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^64-1
+mpi_core_uint_le_mpi:"ffffffffffffffff"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^64-1 with leading zero limb
+mpi_core_uint_le_mpi:"00ffffffffffffffff"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^64
+mpi_core_uint_le_mpi:"010000000000000000"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^64+1
+mpi_core_uint_le_mpi:"010000000000000001"
+
+Test mbedtls_mpi_core_uint_le_mpi: 2^64+2
+mpi_core_uint_le_mpi:"010000000000000002"
+
mbedtls_mpi_core_cond_assign: 1 limb
mpi_core_cond_assign:"FFFFFFFF":"11111111":4
diff --git a/tests/suites/test_suite_bignum_mod.function b/tests/suites/test_suite_bignum_mod.function
index 0d2e232..1e64255 100644
--- a/tests/suites/test_suite_bignum_mod.function
+++ b/tests/suites/test_suite_bignum_mod.function
@@ -108,7 +108,7 @@
/* BEGIN_CASE */
void mpi_mod_sub( char * input_N,
char * input_A, char * input_B,
- char * input_D, int oret )
+ char * input_D, int expected_ret )
{
mbedtls_mpi_mod_residue a = { NULL, 0 };
mbedtls_mpi_mod_residue b = { NULL, 0 };
@@ -125,46 +125,51 @@
/* test_read_residue() normally checks that inputs have the same number of
* limbs as the modulus. For negative testing we can ask it to skip this
* with a non-zero final parameter. */
- TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, oret != 0 ) );
- TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, oret != 0 ) );
- TEST_EQUAL( 0, test_read_residue( &d, &m, input_D, oret != 0 ) );
+ TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, expected_ret != 0 ) );
+ TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, expected_ret != 0 ) );
+ TEST_EQUAL( 0, test_read_residue( &d, &m, input_D, expected_ret != 0 ) );
size_t limbs = m.limbs;
size_t bytes = limbs * sizeof( *X_raw );
- /* One spare limb for negative testing */
- ASSERT_ALLOC( X_raw, limbs + 1 );
-
- if( oret == 0 )
+ if( expected_ret == 0 )
{
- /* Sneak in a couple of negative tests on known-good data */
+ /* Negative test with too many limbs in output */
+ ASSERT_ALLOC( X_raw, limbs + 1 );
- /* First, negative test with too many limbs in output */
x.p = X_raw;
x.limbs = limbs + 1;
TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
- /* Then negative test with too few limbs in output */
+ mbedtls_free( X_raw );
+ X_raw = NULL;
+
+ /* Negative test with too few limbs in output */
if( limbs > 1 )
{
+ ASSERT_ALLOC( X_raw, limbs - 1 );
+
x.p = X_raw;
x.limbs = limbs - 1;
TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
+
+ mbedtls_free( X_raw );
+ X_raw = NULL;
}
/* Negative testing with too many/too few limbs in a and b is covered by
- * manually-written test cases with oret != 0. */
-
- /* Back to the normally-scheduled programme */
+ * manually-written test cases with expected_ret != 0. */
}
+ ASSERT_ALLOC( X_raw, limbs );
+
TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
/* a - b => Correct result, or expected error */
- TEST_EQUAL( oret, mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
- if( oret != 0 )
+ TEST_EQUAL( expected_ret, mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
+ if( expected_ret != 0 )
goto exit;
TEST_COMPARE_MPI_RESIDUES( x, d );
@@ -210,7 +215,110 @@
/* END MERGE SLOT 4 */
/* BEGIN MERGE SLOT 5 */
+/* BEGIN_CASE */
+void mpi_mod_add( char * input_N,
+ char * input_A, char * input_B,
+ char * input_S, int expected_ret )
+{
+ mbedtls_mpi_mod_residue a = { NULL, 0 };
+ mbedtls_mpi_mod_residue b = { NULL, 0 };
+ mbedtls_mpi_mod_residue s = { NULL, 0 };
+ mbedtls_mpi_mod_residue x = { NULL, 0 };
+ mbedtls_mpi_uint *X_raw = NULL;
+ mbedtls_mpi_mod_modulus m;
+ mbedtls_mpi_mod_modulus_init( &m );
+
+ TEST_EQUAL( 0,
+ test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
+
+ /* test_read_residue() normally checks that inputs have the same number of
+ * limbs as the modulus. For negative testing we can ask it to skip this
+ * with a non-zero final parameter. */
+ TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, expected_ret != 0 ) );
+ TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, expected_ret != 0 ) );
+ TEST_EQUAL( 0, test_read_residue( &s, &m, input_S, expected_ret != 0 ) );
+
+ size_t limbs = m.limbs;
+ size_t bytes = limbs * sizeof( *X_raw );
+
+ if( expected_ret == 0 )
+ {
+ /* Negative test with too many limbs in output */
+ ASSERT_ALLOC( X_raw, limbs + 1 );
+
+ x.p = X_raw;
+ x.limbs = limbs + 1;
+ TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+ mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
+
+ mbedtls_free( X_raw );
+ X_raw = NULL;
+
+ /* Negative test with too few limbs in output */
+ if( limbs > 1 )
+ {
+ ASSERT_ALLOC( X_raw, limbs - 1 );
+
+ x.p = X_raw;
+ x.limbs = limbs - 1;
+ TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+ mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
+
+ mbedtls_free( X_raw );
+ X_raw = NULL;
+ }
+
+ /* Negative testing with too many/too few limbs in a and b is covered by
+ * manually-written test cases with oret != 0. */
+ }
+
+ /* Allocate correct number of limbs for X_raw */
+ ASSERT_ALLOC( X_raw, limbs );
+
+ TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
+
+ /* A + B => Correct result or expected error */
+ TEST_EQUAL( expected_ret, mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
+ if( expected_ret != 0 )
+ goto exit;
+
+ TEST_COMPARE_MPI_RESIDUES( x, s );
+
+ /* a + b: alias x to a => Correct result */
+ memcpy( x.p, a.p, bytes );
+ TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &x, &b, &m ) );
+ TEST_COMPARE_MPI_RESIDUES( x, s );
+
+ /* a + b: alias x to b => Correct result */
+ memcpy( x.p, b.p, bytes );
+ TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &a, &x, &m ) );
+ TEST_COMPARE_MPI_RESIDUES( x, s );
+
+ if ( memcmp( a.p, b.p, bytes ) == 0 )
+ {
+ /* a == b: alias a and b */
+
+ /* a + a => Correct result */
+ TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &a, &a, &m ) );
+ TEST_COMPARE_MPI_RESIDUES( x, s );
+
+ /* a + a: x, a, b all aliased together => Correct result */
+ memcpy( x.p, a.p, bytes );
+ TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &x, &x, &m ) );
+ TEST_COMPARE_MPI_RESIDUES( x, s );
+ }
+
+exit:
+ mbedtls_free( (void *)m.p ); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
+ mbedtls_mpi_mod_modulus_free( &m );
+
+ mbedtls_free( a.p );
+ mbedtls_free( b.p );
+ mbedtls_free( s.p );
+ mbedtls_free( X_raw );
+}
+/* END_CASE */
/* END MERGE SLOT 5 */
/* BEGIN MERGE SLOT 6 */
diff --git a/tests/suites/test_suite_bignum_mod.data b/tests/suites/test_suite_bignum_mod.misc.data
similarity index 97%
rename from tests/suites/test_suite_bignum_mod.data
rename to tests/suites/test_suite_bignum_mod.misc.data
index 501d9d7..7b1c85f 100644
--- a/tests/suites/test_suite_bignum_mod.data
+++ b/tests/suites/test_suite_bignum_mod.misc.data
@@ -45,7 +45,26 @@
# END MERGE SLOT 4
# BEGIN MERGE SLOT 5
+mpi_mod_add base case for negative testing (N, a, b all >= 1 limb)
+mpi_mod_add:"014320a022ccb75bdf470ddf25":"000000025a55a46e5da99c71c7":"00033b2e3c9fd0803ce8000f93":"00033b3096f574ee9a919c815a":0
+mpi_mod_add with modulus too long/both inputs too short
+mpi_mod_add:"0000000014320a022ccb75bdf470ddf25":"000000025a55a46e5da99c71c7":"00033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_add with first input too long
+mpi_mod_add:"014320a022ccb75bdf470ddf25":"0000000000000025a55a46e5da99c71c7":"00033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_add with second input too long
+mpi_mod_add:"014320a022ccb75bdf470ddf25":"000000025a55a46e5da99c71c7":"000000000033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_add with both inputs too long
+mpi_mod_add:"014320a022ccb75bdf470ddf25":"0000000000000025a55a46e5da99c71c7":"000000000033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_add with first input too short
+mpi_mod_add:"014320a022ccb75bdf470ddf25":"a99c71c7":"00033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_add with second input too short
+mpi_mod_add:"014320a022ccb75bdf470ddf25":"000000025a55a46e5da99c71c7":"e8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
# END MERGE SLOT 5
# BEGIN MERGE SLOT 6
diff --git a/tests/suites/test_suite_bignum_mod_raw.function b/tests/suites/test_suite_bignum_mod_raw.function
index 5d23707..83e1f54 100644
--- a/tests/suites/test_suite_bignum_mod_raw.function
+++ b/tests/suites/test_suite_bignum_mod_raw.function
@@ -595,6 +595,60 @@
mbedtls_free( X );
}
/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_mod_raw_neg( char * input_N, char * input_A, char * input_X )
+{
+ mbedtls_mpi_uint *N = NULL;
+ mbedtls_mpi_uint *A = NULL;
+ mbedtls_mpi_uint *X = NULL;
+ mbedtls_mpi_uint *R = NULL;
+ mbedtls_mpi_uint *Z = NULL;
+ size_t n_limbs, a_limbs, x_limbs, bytes;
+
+ mbedtls_mpi_mod_modulus m;
+ mbedtls_mpi_mod_modulus_init( &m );
+
+ /* Read inputs */
+ TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
+ TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &a_limbs, input_A ) );
+ TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &x_limbs, input_X ) );
+
+ TEST_EQUAL( a_limbs, n_limbs );
+ TEST_EQUAL( x_limbs, n_limbs );
+ bytes = n_limbs * sizeof( mbedtls_mpi_uint );
+
+ ASSERT_ALLOC( R, n_limbs );
+ ASSERT_ALLOC( Z, n_limbs );
+
+ TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
+ MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
+
+ /* Neg( A == 0 ) => Zero result */
+ mbedtls_mpi_mod_raw_neg( R, Z, &m );
+ ASSERT_COMPARE( R, bytes, Z, bytes );
+
+ /* Neg( A == N ) => Zero result */
+ mbedtls_mpi_mod_raw_neg( R, N, &m );
+ ASSERT_COMPARE( R, bytes, Z, bytes );
+
+ /* Neg( A ) => Correct result */
+ mbedtls_mpi_mod_raw_neg( R, A, &m );
+ ASSERT_COMPARE( R, bytes, X, bytes );
+
+ /* Neg( A ): alias A to R => Correct result */
+ mbedtls_mpi_mod_raw_neg( A, A, &m );
+ ASSERT_COMPARE( A, bytes, X, bytes );
+exit:
+ mbedtls_mpi_mod_modulus_free( &m );
+ mbedtls_free( N );
+ mbedtls_free( A );
+ mbedtls_free( X );
+ mbedtls_free( R );
+ mbedtls_free( Z );
+}
+/* END_CASE */
+
/* END MERGE SLOT 7 */
/* BEGIN MERGE SLOT 8 */
diff --git a/tests/suites/test_suite_bignum_random.data b/tests/suites/test_suite_bignum_random.data
new file mode 100644
index 0000000..fe29053
--- /dev/null
+++ b/tests/suites/test_suite_bignum_random.data
@@ -0,0 +1,235 @@
+MPI core random basic: 0..1
+mpi_core_random_basic:0:"01":0
+
+MPI core random basic: 0..2
+mpi_core_random_basic:0:"02":0
+
+MPI core random basic: 1..2
+mpi_core_random_basic:1:"02":0
+
+MPI core random basic: 2^30..2^31
+mpi_core_random_basic:0x40000000:"80000000":0
+
+MPI core random basic: 0..2^128
+mpi_core_random_basic:0x40000000:"0100000000000000000000000000000000":0
+
+MPI core random basic: 2^30..2^129
+mpi_core_random_basic:0x40000000:"0200000000000000000000000000000000":0
+
+# Use the same data values for mpi_core_random_basic->NOT_ACCEPTABLE
+# and for mpi_random_values where we want to return NOT_ACCEPTABLE but
+# this isn't checked at runtime.
+MPI core random basic: 2^28-1..2^28 (NOT_ACCEPTABLE)
+mpi_core_random_basic:0x0fffffff:"10000000":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+
+MPI random legacy=core: 2^28-1..2^28 (NOT_ACCEPTABLE)
+mpi_random_values:0x0fffffff:"10000000"
+
+MPI core random basic: 2^29-1..2^29 (NOT_ACCEPTABLE)
+mpi_core_random_basic:0x1fffffff:"20000000":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+
+MPI random legacy=core: 2^29-1..2^29 (NOT_ACCEPTABLE)
+mpi_random_values:0x1fffffff:"20000000"
+
+MPI core random basic: 2^30-1..2^30 (NOT_ACCEPTABLE)
+mpi_core_random_basic:0x3fffffff:"40000000":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+
+MPI random legacy=core: 2^30-1..2^30 (NOT_ACCEPTABLE)
+mpi_random_values:0x3fffffff:"40000000"
+
+MPI core random basic: 2^31-1..2^31 (NOT_ACCEPTABLE)
+mpi_core_random_basic:0x7fffffff:"80000000":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+
+MPI random legacy=core: 2^31-1..2^31 (NOT_ACCEPTABLE)
+mpi_random_values:0x7fffffff:"80000000"
+
+MPI random in range: 1..2
+mpi_random_many:1:"02":1000
+
+MPI random in range: 1..3
+mpi_random_many:1:"03":1000
+
+MPI random in range: 1..4
+mpi_random_many:1:"04":1000
+
+MPI random in range: 1..5
+mpi_random_many:1:"05":1000
+
+MPI random in range: 1..6
+mpi_random_many:1:"06":1000
+
+MPI random in range: 1..7
+mpi_random_many:1:"07":1000
+
+MPI random in range: 1..8
+mpi_random_many:1:"08":1000
+
+MPI random in range: 1..9
+mpi_random_many:1:"09":1000
+
+MPI random in range: 1..10
+mpi_random_many:1:"0a":1000
+
+MPI random in range: 1..11
+mpi_random_many:1:"0b":1000
+
+MPI random in range: 1..12
+mpi_random_many:1:"0c":1000
+
+MPI random in range: 1..255
+mpi_random_many:1:"ff":200
+
+MPI random in range: 1..256
+mpi_random_many:1:"0100":200
+
+MPI random in range: 1..257
+mpi_random_many:1:"0101":200
+
+MPI random in range: 1..272
+mpi_random_many:1:"0110":200
+
+MPI random in range: 1..2^64-1
+mpi_random_many:1:"ffffffffffffffff":100
+
+MPI random in range: 1..2^64
+mpi_random_many:1:"010000000000000000":100
+
+MPI random in range: 1..2^64+1
+mpi_random_many:1:"010000000000000001":100
+
+MPI random in range: 1..2^64+2^63
+mpi_random_many:1:"018000000000000000":100
+
+MPI random in range: 1..2^65-1
+mpi_random_many:1:"01ffffffffffffffff":100
+
+MPI random in range: 1..2^65
+mpi_random_many:1:"020000000000000000":100
+
+MPI random in range: 1..2^65+1
+mpi_random_many:1:"020000000000000001":100
+
+MPI random in range: 1..2^65+2^64
+mpi_random_many:1:"030000000000000000":100
+
+MPI random in range: 1..2^66+2^65
+mpi_random_many:1:"060000000000000000":100
+
+MPI random in range: 1..2^71-1
+mpi_random_many:1:"7fffffffffffffffff":100
+
+MPI random in range: 1..2^71
+mpi_random_many:1:"800000000000000000":100
+
+MPI random in range: 1..2^71+1
+mpi_random_many:1:"800000000000000001":100
+
+MPI random in range: 1..2^71+2^70
+mpi_random_many:1:"c00000000000000000":100
+
+MPI random in range: 1..2^72-1
+mpi_random_many:1:"ffffffffffffffffff":100
+
+MPI random in range: 1..2^72
+mpi_random_many:1:"01000000000000000000":100
+
+MPI random in range: 1..2^72+1
+mpi_random_many:1:"01000000000000000001":100
+
+MPI random in range: 1..2^72+2^71
+mpi_random_many:1:"01800000000000000000":100
+
+MPI random in range: 0..1
+mpi_random_many:0:"04":10000
+
+MPI random in range: 0..4
+mpi_random_many:0:"04":10000
+
+MPI random in range: 2..4
+mpi_random_many:2:"04":10000
+
+MPI random in range: 3..4
+mpi_random_many:3:"04":10000
+
+MPI random in range: smaller result
+mpi_random_sizes:1:"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb":1:0
+
+MPI random in range: same size result (32-bit limbs)
+mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":2:0
+
+MPI random in range: same size result (64-bit limbs)
+mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":1:0
+
+MPI random in range: larger result
+mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":3:0
+
+## The "0 limb in upper bound" tests rely on the fact that
+## mbedtls_mpi_read_binary() bases the size of the MPI on the size of
+## the input, without first checking for leading zeros. If this was
+## not the case, the tests would still pass, but would not exercise
+## the advertised behavior.
+MPI random in range: leading 0 limb in upper bound #0
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":0:0
+
+MPI random in range: leading 0 limb in upper bound #1
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":1:0
+
+MPI random in range: leading 0 limb in upper bound #2
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":2:0
+
+MPI random in range: leading 0 limb in upper bound #3
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":3:0
+
+MPI random in range: leading 0 limb in upper bound #4
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":4:0
+
+MPI random in range: previously small >0
+mpi_random_sizes:1:"1234567890":4:1
+
+MPI random in range: previously small <0
+mpi_random_sizes:1:"1234567890":4:-1
+
+MPI random in range: previously large >0
+mpi_random_sizes:1:"1234":4:65
+
+MPI random in range: previously large <0
+mpi_random_sizes:1:"1234":4:-65
+
+MPI random bad arguments: min < 0
+mpi_random_fail:-1:"04":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+MPI random bad arguments: min = N = 0
+mpi_random_fail:0:"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+MPI random bad arguments: min = N = 1
+mpi_random_fail:1:"01":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+MPI random bad arguments: min > N = 0
+mpi_random_fail:1:"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+MPI random bad arguments: min > N = 1
+mpi_random_fail:2:"01":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+MPI random bad arguments: min > N = 1, 0 limb in upper bound
+mpi_random_fail:2:"000000000000000001":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+MPI random legacy=core: 0..1
+mpi_random_values:0:"01"
+
+MPI random legacy=core: 0..2
+mpi_random_values:0:"02"
+
+MPI random legacy=core: 1..2
+mpi_random_values:1:"02"
+
+MPI random legacy=core: 2^30..2^31
+mpi_random_values:0x40000000:"80000000"
+
+MPI random legacy=core: 2^31-1..2^32-1
+mpi_random_values:0x7fffffff:"ffffffff"
+
+MPI random legacy=core: 0..2^256
+mpi_random_values:0:"010000000000000000000000000000000000000000000000000000000000000000"
+
+MPI random legacy=core: 0..2^256+1
+mpi_random_values:0:"010000000000000000000000000000000000000000000000000000000000000001"
diff --git a/tests/suites/test_suite_bignum_random.function b/tests/suites/test_suite_bignum_random.function
new file mode 100644
index 0000000..184de5a
--- /dev/null
+++ b/tests/suites/test_suite_bignum_random.function
@@ -0,0 +1,334 @@
+/* BEGIN_HEADER */
+/* Dedicated test suite for mbedtls_mpi_core_random() and the upper-layer
+ * functions. Due to the complexity of how these functions are tested,
+ * we test all the layers in a single test suite, unlike the way other
+ * functions are tested with each layer in its own test suite.
+ */
+
+#include "mbedtls/bignum.h"
+#include "mbedtls/entropy.h"
+#include "bignum_core.h"
+#include "constant_time_internal.h"
+
+/* This test suite only manipulates non-negative bignums. */
+static int sign_is_valid( const mbedtls_mpi *X )
+{
+ return( X->s == 1 );
+}
+
+/* A common initializer for test functions that should generate the same
+ * sequences for reproducibility and good coverage. */
+const mbedtls_test_rnd_pseudo_info rnd_pseudo_seed = {
+ /* 16-word key */
+ {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
+ 'a', ' ', 's', 'e', 'e', 'd', '!', 0},
+ /* 2-word initial state, should be zero */
+ 0, 0};
+
+/* Test whether bytes represents (in big-endian base 256) a number b that
+ * is significantly above a power of 2. That is, b must not have a long run
+ * of unset bits after the most significant bit.
+ *
+ * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
+ * This function returns 1 if, when drawing a number between 0 and b,
+ * the probability that this number is at least 2^n is not negligible.
+ * This probability is (b - 2^n) / b and this function checks that this
+ * number is above some threshold A. The threshold value is heuristic and
+ * based on the needs of mpi_random_many().
+ */
+static int is_significantly_above_a_power_of_2( data_t *bytes )
+{
+ const uint8_t *p = bytes->x;
+ size_t len = bytes->len;
+ unsigned x;
+
+ /* Skip leading null bytes */
+ while( len > 0 && p[0] == 0 )
+ {
+ ++p;
+ --len;
+ }
+ /* 0 is not significantly above a power of 2 */
+ if( len == 0 )
+ return( 0 );
+ /* Extract the (up to) 2 most significant bytes */
+ if( len == 1 )
+ x = p[0];
+ else
+ x = ( p[0] << 8 ) | p[1];
+
+ /* Shift the most significant bit of x to position 8 and mask it out */
+ while( ( x & 0xfe00 ) != 0 )
+ x >>= 1;
+ x &= 0x00ff;
+
+ /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
+ * a power of 2 iff x is significantly above 0 compared to 2^8.
+ * Testing x >= 2^4 amounts to picking A = 1/16 in the function
+ * description above. */
+ return( x >= 0x10 );
+}
+
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_BIGNUM_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void mpi_core_random_basic( int min, char *bound_bytes, int expected_ret )
+{
+ /* Same RNG as in mpi_random_values */
+ mbedtls_test_rnd_pseudo_info rnd = rnd_pseudo_seed;
+ size_t limbs;
+ mbedtls_mpi_uint *lower_bound = NULL;
+ mbedtls_mpi_uint *upper_bound = NULL;
+ mbedtls_mpi_uint *result = NULL;
+
+ TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &upper_bound, &limbs,
+ bound_bytes ) );
+ ASSERT_ALLOC( lower_bound, limbs );
+ lower_bound[0] = min;
+ ASSERT_ALLOC( result, limbs );
+
+ TEST_EQUAL( expected_ret,
+ mbedtls_mpi_core_random( result, min, upper_bound, limbs,
+ mbedtls_test_rnd_pseudo_rand, &rnd ) );
+
+ if( expected_ret == 0 )
+ {
+ TEST_EQUAL( 0, mbedtls_mpi_core_lt_ct( result, lower_bound, limbs ) );
+ TEST_EQUAL( 1, mbedtls_mpi_core_lt_ct( result, upper_bound, limbs ) );
+ }
+
+exit:
+ mbedtls_free( lower_bound );
+ mbedtls_free( upper_bound );
+ mbedtls_free( result );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_random_values( int min, char *max_hex )
+{
+ /* Same RNG as in mpi_core_random_basic */
+ mbedtls_test_rnd_pseudo_info rnd_core = rnd_pseudo_seed;
+ mbedtls_test_rnd_pseudo_info rnd_legacy;
+ memcpy( &rnd_legacy, &rnd_core, sizeof( rnd_core ) );
+ mbedtls_mpi max_legacy;
+ mbedtls_mpi_init( &max_legacy );
+ mbedtls_mpi_uint *R_core = NULL;
+ mbedtls_mpi R_legacy;
+ mbedtls_mpi_init( &R_legacy );
+
+ TEST_EQUAL( 0, mbedtls_test_read_mpi( &max_legacy, max_hex ) );
+ size_t limbs = max_legacy.n;
+ ASSERT_ALLOC( R_core, limbs );
+
+ /* Call the legacy function and the core function with the same random
+ * stream. */
+ int core_ret = mbedtls_mpi_core_random( R_core, min, max_legacy.p, limbs,
+ mbedtls_test_rnd_pseudo_rand,
+ &rnd_core );
+ int legacy_ret = mbedtls_mpi_random( &R_legacy, min, &max_legacy,
+ mbedtls_test_rnd_pseudo_rand,
+ &rnd_legacy );
+
+ /* They must return the same status, and, on success, output the
+ * same number, with the same limb count. */
+ TEST_EQUAL( core_ret, legacy_ret );
+ if( core_ret == 0 )
+ {
+ ASSERT_COMPARE( R_core, limbs * ciL,
+ R_legacy.p, R_legacy.n * ciL );
+ }
+
+ /* Also check that they have consumed the RNG in the same way. */
+ /* This may theoretically fail on rare platforms with padding in
+ * the structure! If this is a problem in practice, change to a
+ * field-by-field comparison. */
+ ASSERT_COMPARE( &rnd_core, sizeof( rnd_core ),
+ &rnd_legacy, sizeof( rnd_legacy ) );
+
+exit:
+ mbedtls_mpi_free( &max_legacy );
+ mbedtls_free( R_core );
+ mbedtls_mpi_free( &R_legacy );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_random_many( int min, char *bound_hex, int iterations )
+{
+ /* Generate numbers in the range 1..bound-1. Do it iterations times.
+ * This function assumes that the value of bound is at least 2 and
+ * that iterations is large enough that a one-in-2^iterations chance
+ * effectively never occurs.
+ */
+
+ data_t bound_bytes = {NULL, 0};
+ mbedtls_mpi_uint *upper_bound = NULL;
+ size_t limbs;
+ size_t n_bits;
+ mbedtls_mpi_uint *result = NULL;
+ size_t b;
+ /* If upper_bound is small, stats[b] is the number of times the value b
+ * has been generated. Otherwise stats[b] is the number of times a
+ * value with bit b set has been generated. */
+ size_t *stats = NULL;
+ size_t stats_len;
+ int full_stats;
+ size_t i;
+
+ TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &upper_bound, &limbs,
+ bound_hex ) );
+ ASSERT_ALLOC( result, limbs );
+
+ n_bits = mbedtls_mpi_core_bitlen( upper_bound, limbs );
+ /* Consider a bound "small" if it's less than 2^5. This value is chosen
+ * to be small enough that the probability of missing one value is
+ * negligible given the number of iterations. It must be less than
+ * 256 because some of the code below assumes that "small" values
+ * fit in a byte. */
+ if( n_bits <= 5 )
+ {
+ full_stats = 1;
+ stats_len = (uint8_t) upper_bound[0];
+ }
+ else
+ {
+ full_stats = 0;
+ stats_len = n_bits;
+ }
+ ASSERT_ALLOC( stats, stats_len );
+
+ for( i = 0; i < (size_t) iterations; i++ )
+ {
+ mbedtls_test_set_step( i );
+ TEST_EQUAL( 0, mbedtls_mpi_core_random( result,
+ min, upper_bound, limbs,
+ mbedtls_test_rnd_std_rand, NULL ) );
+
+ /* Temporarily use a legacy MPI for analysis, because the
+ * necessary auxiliary functions don't exist yet in core. */
+ mbedtls_mpi B = {1, limbs, upper_bound};
+ mbedtls_mpi R = {1, limbs, result};
+
+ TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) < 0 );
+ TEST_ASSERT( mbedtls_mpi_cmp_int( &R, min ) >= 0 );
+ if( full_stats )
+ {
+ uint8_t value;
+ TEST_EQUAL( 0, mbedtls_mpi_write_binary( &R, &value, 1 ) );
+ TEST_ASSERT( value < stats_len );
+ ++stats[value];
+ }
+ else
+ {
+ for( b = 0; b < n_bits; b++ )
+ stats[b] += mbedtls_mpi_get_bit( &R, b );
+ }
+ }
+
+ if( full_stats )
+ {
+ for( b = min; b < stats_len; b++ )
+ {
+ mbedtls_test_set_step( 1000000 + b );
+ /* Assert that each value has been reached at least once.
+ * This is almost guaranteed if the iteration count is large
+ * enough. This is a very crude way of checking the distribution.
+ */
+ TEST_ASSERT( stats[b] > 0 );
+ }
+ }
+ else
+ {
+ bound_bytes.len = limbs * sizeof( mbedtls_mpi_uint );
+ ASSERT_ALLOC( bound_bytes.x, bound_bytes.len );
+ mbedtls_mpi_core_write_be( upper_bound, limbs,
+ bound_bytes.x, bound_bytes.len );
+ int statistically_safe_all_the_way =
+ is_significantly_above_a_power_of_2( &bound_bytes );
+ for( b = 0; b < n_bits; b++ )
+ {
+ mbedtls_test_set_step( 1000000 + b );
+ /* Assert that each bit has been set in at least one result and
+ * clear in at least one result. Provided that iterations is not
+ * too small, it would be extremely unlikely for this not to be
+ * the case if the results are uniformly distributed.
+ *
+ * As an exception, the top bit may legitimately never be set
+ * if bound is a power of 2 or only slightly above.
+ */
+ if( statistically_safe_all_the_way || b != n_bits - 1 )
+ {
+ TEST_ASSERT( stats[b] > 0 );
+ }
+ TEST_ASSERT( stats[b] < (size_t) iterations );
+ }
+ }
+
+exit:
+ mbedtls_free( bound_bytes.x );
+ mbedtls_free( upper_bound );
+ mbedtls_free( result );
+ mbedtls_free( stats );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
+{
+ mbedtls_mpi upper_bound;
+ mbedtls_mpi result;
+
+ mbedtls_mpi_init( &upper_bound );
+ mbedtls_mpi_init( &result );
+
+ if( before != 0 )
+ {
+ /* Set result to sign(before) * 2^(|before|-1) */
+ TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
+ if( before < 0 )
+ before = - before;
+ TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
+ }
+
+ TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
+ TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
+ bound_bytes->x, bound_bytes->len ) );
+ TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
+ mbedtls_test_rnd_std_rand, NULL ) );
+ TEST_ASSERT( sign_is_valid( &result ) );
+ TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
+ TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
+
+exit:
+ mbedtls_mpi_free( &upper_bound );
+ mbedtls_mpi_free( &result );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
+{
+ mbedtls_mpi upper_bound;
+ mbedtls_mpi result;
+ int actual_ret;
+
+ mbedtls_mpi_init( &upper_bound );
+ mbedtls_mpi_init( &result );
+
+ TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
+ bound_bytes->x, bound_bytes->len ) );
+ actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
+ mbedtls_test_rnd_std_rand, NULL );
+ TEST_EQUAL( expected_ret, actual_ret );
+
+exit:
+ mbedtls_mpi_free( &upper_bound );
+ mbedtls_mpi_free( &result );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 7d29e52..2971c57 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -237,7 +237,7 @@
}
/* END_CASE */
-/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
+/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
void ecp_muladd_restart( int id, char *xR_str, char *yR_str,
char *u1_str, char *u2_str,
char *xQ_str, char *yQ_str,
diff --git a/tests/suites/test_suite_pkcs7.data b/tests/suites/test_suite_pkcs7.data
index f3cbb62..571d5ad 100644
--- a/tests/suites/test_suite_pkcs7.data
+++ b/tests/suites/test_suite_pkcs7.data
@@ -68,7 +68,7 @@
pkcs7_get_signers_info_set error handling (4541044530479104)
depends_on:MBEDTLS_RIPEMD160_C
-pkcs7_parse:"data_files/pkcs7_get_signers_info_set-missing_free-fuzz_pkcs7-6213931373035520.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+pkcs7_parse:"data_files/pkcs7_get_signers_info_set-leak-fuzz_pkcs7-4541044530479104.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO
PKCS7 Only Signed Data Parse Pass #15
depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index dbbac76..a4c19b8 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -1452,6 +1452,7 @@
/* END_CASE */
/* BEGIN_CASE */
+/* Construct and attempt to import a large unstructured key. */
void import_large_key( int type_arg, int byte_size_arg,
int expected_status_arg )
{
@@ -1508,6 +1509,9 @@
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ASN1_WRITE_C */
+/* Import an RSA key with a valid structure (but not valid numbers
+ * inside, beyond having sensible size and parity). This is expected to
+ * fail for large keys. */
void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg )
{
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
@@ -1553,6 +1557,7 @@
int expected_bits,
int export_size_delta,
int expected_export_status_arg,
+ /*whether reexport must give the original input exactly*/
int canonical_input )
{
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
@@ -1657,7 +1662,7 @@
/* BEGIN_CASE */
void import_export_public_key( data_t *data,
- int type_arg,
+ int type_arg, // key pair or public key
int alg_arg,
int lifetime_arg,
int export_size_delta,
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index a7f0501..1b5e44b 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -3539,3 +3539,11 @@
TLS 1.3 srv Certificate msg - wrong vector lengths
tls13_server_certificate_msg_invalid_vector_len
+
+EC-JPAKE set password
+depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+ssl_ecjpake_set_password:0
+
+EC-JPAKE set opaque password
+depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO
+ssl_ecjpake_set_password:1
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 674e649..95fa8ef 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -2582,6 +2582,21 @@
return( 0 );
}
#endif /* MBEDTLS_TEST_HOOKS */
+
+#define ECJPAKE_TEST_PWD "bla"
+
+#if defined( MBEDTLS_USE_PSA_CRYPTO )
+#define ECJPAKE_TEST_SET_PASSWORD( exp_ret_val ) \
+ ret = ( use_opaque_arg ) ? \
+ mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl, pwd_slot ) : \
+ mbedtls_ssl_set_hs_ecjpake_password( &ssl, pwd_string, pwd_len ); \
+ TEST_EQUAL( ret, exp_ret_val )
+#else
+#define ECJPAKE_TEST_SET_PASSWORD( exp_ret_val ) \
+ ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, \
+ pwd_string, pwd_len ); \
+ TEST_EQUAL( ret, exp_ret_val )
+#endif
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -5997,3 +6012,85 @@
USE_PSA_DONE( );
}
/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+void ssl_ecjpake_set_password( int use_opaque_arg )
+{
+ mbedtls_ssl_context ssl;
+ mbedtls_ssl_config conf;
+#if defined( MBEDTLS_USE_PSA_CRYPTO )
+ mbedtls_svc_key_id_t pwd_slot = MBEDTLS_SVC_KEY_ID_INIT;
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+ (void) use_opaque_arg;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ unsigned char pwd_string[ sizeof(ECJPAKE_TEST_PWD) ] = "";
+ size_t pwd_len = 0;
+ int ret;
+
+ USE_PSA_INIT( );
+
+ mbedtls_ssl_init( &ssl );
+
+ /* test with uninitalized SSL context */
+ ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ mbedtls_ssl_config_init( &conf );
+
+ TEST_EQUAL( mbedtls_ssl_config_defaults( &conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT ), 0 );
+
+ TEST_EQUAL( mbedtls_ssl_setup( &ssl, &conf ), 0 );
+
+ /* test with empty password or unitialized password key (depending on use_opaque_arg) */
+ ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ pwd_len = strlen( ECJPAKE_TEST_PWD );
+ memcpy( pwd_string, ECJPAKE_TEST_PWD, pwd_len );
+
+#if defined( MBEDTLS_USE_PSA_CRYPTO )
+ if( use_opaque_arg )
+ {
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* First try with an invalid usage */
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
+ psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE );
+ psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD );
+
+ PSA_ASSERT( psa_import_key( &attributes, pwd_string,
+ pwd_len, &pwd_slot ) );
+
+ ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ /* check that the opaque key is still valid after failure */
+ TEST_EQUAL( psa_get_key_attributes( pwd_slot, &check_attributes ),
+ PSA_SUCCESS );
+
+ psa_destroy_key( pwd_slot );
+
+ /* Then set the correct usage */
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
+
+ PSA_ASSERT( psa_import_key( &attributes, pwd_string,
+ pwd_len, &pwd_slot ) );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ /* final check which should work without errors */
+ ECJPAKE_TEST_SET_PASSWORD( 0 );
+
+#if defined( MBEDTLS_USE_PSA_CRYPTO )
+ if( use_opaque_arg )
+ {
+ psa_destroy_key( pwd_slot );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ mbedtls_ssl_free( &ssl );
+ mbedtls_ssl_config_free( &conf );
+
+ USE_PSA_DONE( );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index f131029..ea6fc62 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
Check compile time library version
-check_compiletime_version:"3.2.1"
+check_compiletime_version:"3.3.0"
Check runtime library version
-check_runtime_version:"3.2.1"
+check_runtime_version:"3.3.0"
Check for MBEDTLS_VERSION_C
check_feature:"MBEDTLS_VERSION_C":0
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 2585720..dc36b81 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -579,6 +579,8 @@
mbedtls_x509_crt_init( &crt );
mbedtls_x509_crt_init( &ca );
+ USE_PSA_INIT( );
+
TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
@@ -607,6 +609,7 @@
mbedtls_x509_crt_restart_free( &rs_ctx );
mbedtls_x509_crt_free( &crt );
mbedtls_x509_crt_free( &ca );
+ USE_PSA_DONE( );
}
/* END_CASE */