Merge remote-tracking branch 'restricted/development-restricted' into mbedtls-3.0.0rc0-pr
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index b9f1468..c203112 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -15,7 +15,7 @@
 
 Mbed TLS version (number or commit id): 
 Operating system and version: 
-Configuration (if not default, please attach `config.h`): 
+Configuration (if not default, please attach `mbedtls_config.h`): 
 Compiler and options (if you used a pre-built binary, please indicate how you obtained it): 
 Additional environment information: 
 
diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt
index 18945e5..e81ff51 100644
--- a/3rdparty/CMakeLists.txt
+++ b/3rdparty/CMakeLists.txt
@@ -1,17 +1,5 @@
-list (APPEND thirdparty_src)
-list (APPEND thirdparty_lib)
-list (APPEND thirdparty_inc_public)
-list (APPEND thirdparty_inc)
-list (APPEND thirdparty_def)
-
-execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls/config.h get MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED RESULT_VARIABLE result)
+execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls/mbedtls_config.h get MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED RESULT_VARIABLE result)
 
 if(${result} EQUAL 0)
     add_subdirectory(everest)
 endif()
-
-set(thirdparty_src ${thirdparty_src} PARENT_SCOPE)
-set(thirdparty_lib ${thirdparty_lib} PARENT_SCOPE)
-set(thirdparty_inc_public ${thirdparty_inc_public} PARENT_SCOPE)
-set(thirdparty_inc ${thirdparty_inc} PARENT_SCOPE)
-set(thirdparty_def ${thirdparty_def} PARENT_SCOPE)
diff --git a/3rdparty/everest/CMakeLists.txt b/3rdparty/everest/CMakeLists.txt
index d81d995..ff9da7a 100644
--- a/3rdparty/everest/CMakeLists.txt
+++ b/3rdparty/everest/CMakeLists.txt
@@ -1,16 +1,15 @@
-list (APPEND everest_src)
-list (APPEND everest_inc_public)
-list (APPEND everest_inc)
-list (APPEND everest_def)
+add_library(everest
+  library/everest.c
+  library/x25519.c
+  library/Hacl_Curve25519_joined.c)
 
-set(everest_src
-  ${CMAKE_CURRENT_SOURCE_DIR}/library/everest.c
-  ${CMAKE_CURRENT_SOURCE_DIR}/library/x25519.c
-  ${CMAKE_CURRENT_SOURCE_DIR}/library/Hacl_Curve25519_joined.c
-)
-
-list(APPEND everest_inc_public ${CMAKE_CURRENT_SOURCE_DIR}/include)
-list(APPEND everest_inc ${CMAKE_CURRENT_SOURCE_DIR}/include/everest ${CMAKE_CURRENT_SOURCE_DIR}/include/everest/kremlib)
+target_include_directories(everest
+  PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+         $<BUILD_INTERFACE:${MBEDTLS_DIR}/include>
+         $<INSTALL_INTERFACE:include>
+  PRIVATE include/everest
+          include/everest/kremlib
+          ${MBEDTLS_DIR}/library/)
 
 if(INSTALL_MBEDTLS_HEADERS)
 
@@ -22,7 +21,7 @@
 
 endif(INSTALL_MBEDTLS_HEADERS)
 
-set(thirdparty_src ${thirdparty_src} ${everest_src} PARENT_SCOPE)
-set(thirdparty_inc_public ${thirdparty_inc_public} ${everest_inc_public} PARENT_SCOPE)
-set(thirdparty_inc ${thirdparty_inc} ${everest_inc} PARENT_SCOPE)
-set(thirdparty_def ${thirdparty_def} ${everest_def} PARENT_SCOPE)
+install(TARGETS everest
+  EXPORT MbedTLSTargets
+  DESTINATION ${LIB_INSTALL_DIR}
+  PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index efe3cab..b92e0bb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,6 +20,8 @@
 # until our infrastructure catches up.
 cmake_minimum_required(VERSION 3.5.1)
 
+include(CMakePackageConfigHelpers)
+
 # https://cmake.org/cmake/help/latest/policy/CMP0011.html
 # Setting this policy is required in CMake >= 3.18.0, otherwise a warning is generated. The OLD
 # policy setting is deprecated, and will be removed in future versions.
@@ -84,7 +86,7 @@
 if(MBEDTLS_PYTHON_EXECUTABLE)
 
     # If 128-bit keys are configured for CTR_DRBG, display an appropriate warning
-    execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/include/mbedtls/config.h get MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+    execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/include/mbedtls/mbedtls_config.h get MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
                         RESULT_VARIABLE result)
     if(${result} EQUAL 0)
         message(WARNING ${CTR_DRBG_128_BIT_KEY_WARNING})
@@ -223,7 +225,6 @@
 add_subdirectory(include)
 
 add_subdirectory(3rdparty)
-list(APPEND libs ${thirdparty_lib})
 
 add_subdirectory(library)
 
@@ -302,3 +303,37 @@
                     ${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
     endif()
 endif()
+
+configure_package_config_file(
+    "cmake/MbedTLSConfig.cmake.in"
+    "cmake/MbedTLSConfig.cmake"
+        INSTALL_DESTINATION "cmake")
+
+write_basic_package_version_file(
+    "cmake/MbedTLSConfigVersion.cmake"
+        COMPATIBILITY SameMajorVersion
+        VERSION 2.26.0)
+
+install(
+    FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"
+          "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfigVersion.cmake"
+    DESTINATION "cmake")
+
+export(
+    EXPORT MbedTLSTargets
+    NAMESPACE MbedTLS::
+    FILE "cmake/MbedTLSTargets.cmake")
+
+install(
+    EXPORT MbedTLSTargets
+    NAMESPACE MbedTLS::
+    DESTINATION "cmake"
+    FILE "MbedTLSTargets.cmake")
+
+if(CMAKE_VERSION VERSION_GREATER 3.14)
+    # Do not export the package by default
+    cmake_policy(SET CMP0090 NEW)
+
+    # Make this package visible to the system
+    export(PACKAGE MbedTLS)
+endif()
diff --git a/ChangeLog b/ChangeLog
index 565ce1c..fcd8427 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -81,8 +81,12 @@
      in line with version 1.0.0 of the specification. Fix #4162.
    * Fix a bug in ECDSA that would cause it to fail when the hash is all-bits
      zero. Fixes #1792
-   * mbedtls_mpi_read_string on "-0" produced an MPI object that was not treated
-     as equal to 0 in all cases. Fix it to produce the same object as "0".
+   * Fix some cases in the bignum module where the library constructed an
+     unintended representation of the value 0 which was not processed
+     correctly by some bignum operations. This could happen when
+     mbedtls_mpi_read_string() was called on "-0", or when
+     mbedtls_mpi_mul_mpi() and mbedtls_mpi_mul_int() was called with one of
+     the arguments being negative and the other being 0. Fixes #4643.
 
 Changes
    * Fix the setting of the read timeout in the DTLS sample programs.
diff --git a/ChangeLog.d/add-cmake-package-config.txt b/ChangeLog.d/add-cmake-package-config.txt
new file mode 100644
index 0000000..3b73816
--- /dev/null
+++ b/ChangeLog.d/add-cmake-package-config.txt
@@ -0,0 +1,2 @@
+Changes
+   * Add CMake package config generation for CMake projects consuming Mbed TLS.
diff --git a/ChangeLog.d/fix_tls_alert_codes.txt b/ChangeLog.d/fix_tls_alert_codes.txt
new file mode 100644
index 0000000..10235d7
--- /dev/null
+++ b/ChangeLog.d/fix_tls_alert_codes.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix which alert is sent in some cases to conform to the
+     applicable RFC: on an invalid Finished message value, an
+     invalid max_fragment_length extension, or an
+     unsupported extension used by the server.
diff --git a/ChangeLog.d/gcm-update.txt b/ChangeLog.d/gcm-update.txt
index 0fffd09..858bd0a 100644
--- a/ChangeLog.d/gcm-update.txt
+++ b/ChangeLog.d/gcm-update.txt
@@ -15,3 +15,5 @@
    * The multi-part GCM interface (mbedtls_gcm_update() or
      mbedtls_cipher_update()) no longer requires the size of partial inputs to
      be a multiple of 16.
+   * The multi-part GCM interface now supports chunked associated data through
+     multiple calls to mbedtls_gcm_update_ad().
diff --git a/ChangeLog.d/implicit_key_usage_policy.txt b/ChangeLog.d/implicit_key_usage_policy.txt
new file mode 100644
index 0000000..ee33ecb
--- /dev/null
+++ b/ChangeLog.d/implicit_key_usage_policy.txt
@@ -0,0 +1,5 @@
+Changes
+   * Implicitly add PSA_KEY_USAGE_SIGN_MESSAGE key usage policy flag when
+     PSA_KEY_USAGE_SIGN_HASH flag is set and PSA_KEY_USAGE_VERIFY_MESSAGE flag
+     when PSA_KEY_USAGE_VERIFY_HASH flag is set. This usage flag extension
+     is also applied when loading a key from storage.
diff --git a/ChangeLog.d/mpi_exp_mod-zero.txt b/ChangeLog.d/mpi_exp_mod-zero.txt
new file mode 100644
index 0000000..9df9031
--- /dev/null
+++ b/ChangeLog.d/mpi_exp_mod-zero.txt
@@ -0,0 +1,7 @@
+Bugfix
+   * Fix a null pointer dereference when mbedtls_mpi_exp_mod() was called with
+     A=0 represented with 0 limbs. Up to and including Mbed TLS 2.26, this bug
+     could not be triggered by code that constructed A with one of the
+     mbedtls_mpi_read_xxx functions (including in particular TLS code) since
+     those always built an mpi object with at least one limb.
+     Credit to OSS-Fuzz. Fixes #4641.
diff --git a/ChangeLog.d/mpi_gcd-0.txt b/ChangeLog.d/mpi_gcd-0.txt
new file mode 100644
index 0000000..41e11e1
--- /dev/null
+++ b/ChangeLog.d/mpi_gcd-0.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix mbedtls_mpi_gcd(G,A,B) when the value of B is zero. This had no
+     effect on Mbed TLS's internal use of mbedtls_mpi_gcd(), but may affect
+     applications that call mbedtls_mpi_gcd() directly. Fixes #4642.
diff --git a/ChangeLog.d/mpi_read_zero.txt b/ChangeLog.d/mpi_read_zero.txt
new file mode 100644
index 0000000..0c25159
--- /dev/null
+++ b/ChangeLog.d/mpi_read_zero.txt
@@ -0,0 +1,9 @@
+Changes
+   * mbedtls_mpi_read_binary(), mbedtls_mpi_read_binary_le() and
+     mbedtls_mpi_read_string() now construct an mbedtls_mpi object with 0 limbs
+     when their input has length 0. Note that this is an implementation detail
+     and can change at any time, so this change should be transparent, but it
+     may result in mbedtls_mpi_write_binary() or mbedtls_mpi_write_string()
+     now writing an empty string where it previously wrote one or more
+     zero digits when operating from values constructed with an mpi_read
+     function and some mpi operations.
diff --git a/ChangeLog.d/one-shot_cipher_functions.txt b/ChangeLog.d/one-shot_cipher_functions.txt
new file mode 100644
index 0000000..3bb85e1
--- /dev/null
+++ b/ChangeLog.d/one-shot_cipher_functions.txt
@@ -0,0 +1,4 @@
+API changes
+   * Implement one-shot cipher functions, psa_cipher_encrypt and
+     psa_cipher_decrypt, according to the PSA Crypto API 1.0.0
+     specification.
diff --git a/ChangeLog.d/out_size.txt b/ChangeLog.d/out_size.txt
new file mode 100644
index 0000000..721bf6a
--- /dev/null
+++ b/ChangeLog.d/out_size.txt
@@ -0,0 +1,5 @@
+API changes
+   * The functions mbedtls_pk_sign(), mbedtls_pk_sign_restartable(),
+     mbedtls_ecdsa_write_signature() and
+     mbedtls_ecdsa_write_signature_restartable() now take an extra parameter
+     indicating the size of the output buffer for the signature.
diff --git a/ChangeLog.d/private-fields.txt b/ChangeLog.d/private-fields.txt
new file mode 100644
index 0000000..10b9a59
--- /dev/null
+++ b/ChangeLog.d/private-fields.txt
@@ -0,0 +1,5 @@
+API changes
+   * Direct access to fields of structures declared in public headers is no
+     longer supported except for fields that are documented public. Use accessor
+     functions instead. For more information, see the migration guide entry
+     "Most structure fields are now private".
diff --git a/ChangeLog.d/psa-read-only-keys.txt b/ChangeLog.d/psa-read-only-keys.txt
new file mode 100644
index 0000000..a4a2823
--- /dev/null
+++ b/ChangeLog.d/psa-read-only-keys.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * The PSA API no longer allows the creation or destruction of keys with a
+     read-only lifetime. The persistence level PSA_KEY_PERSISTENCE_READ_ONLY
+     can now only be used as intended, for keys that cannot be modified through
+     normal use of the API.
diff --git a/ChangeLog.d/psa-rsa-verify-alt-fix.txt b/ChangeLog.d/psa-rsa-verify-alt-fix.txt
new file mode 100644
index 0000000..74804ca
--- /dev/null
+++ b/ChangeLog.d/psa-rsa-verify-alt-fix.txt
@@ -0,0 +1,7 @@
+Bugfix
+   * psa_verify_hash() was relying on implementation-specific behavior of
+     mbedtls_rsa_rsassa_pss_verify() and was causing failures in some _ALT
+     implementations. This reliance is now removed. Fixes #3990.
+   * Disallow inputs of length different from the corresponding hash when
+     signing or verifying with PSA_ALG_RSA_PSS (The PSA Crypto API mandates
+     that PSA_ALG_RSA_PSS uses the same hash throughout the algorithm.)
diff --git a/ChangeLog.d/require-matching-hashlen-rsa.txt b/ChangeLog.d/require-matching-hashlen-rsa.txt
new file mode 100644
index 0000000..096b577
--- /dev/null
+++ b/ChangeLog.d/require-matching-hashlen-rsa.txt
@@ -0,0 +1,5 @@
+API changes
+   * Signature functions in the RSA and PK modules now require the hash
+     length parameter to be the size of the hash input. For RSA signatures
+     other than raw PKCS#1 v1.5, this must match the output size of the
+     specified hash algorithm.
diff --git a/ChangeLog.d/split-config.txt b/ChangeLog.d/split-config.txt
new file mode 100644
index 0000000..f66dc93
--- /dev/null
+++ b/ChangeLog.d/split-config.txt
@@ -0,0 +1,13 @@
+Changes
+   * config.h has been split into build_info.h and mbedtls_config.h
+     build_info.h is intended to be included from C code directly, while
+     mbedtls_config.h is intended to be edited by end users wishing to
+     change the build configuration, and should generally only be included from
+     build_info.h.
+   * The handling of MBEDTLS_CONFIG_FILE has been moved into build_info.h.
+   * A config file version symbol, MBEDTLS_CONFIG_VERSION was introduced.
+     Defining it to a particular value will ensure that Mbed TLS interprets
+     the config file in a way that's compatible with the config file format
+     used by the Mbed TLS release whose MBEDTLS_VERSION_NUMBER has the same
+     value.
+     The only value supported by Mbed TLS 3.0.0 is 0x03000000.
diff --git a/ChangeLog.d/spm_build.txt b/ChangeLog.d/spm_build.txt
new file mode 100644
index 0000000..6016d84
--- /dev/null
+++ b/ChangeLog.d/spm_build.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * When MBEDTLS_PSA_CRYPTO_SPM is enabled, crypto_spe.h was not included
+     in all the right places. Include it from crypto_platform.h, which is
+     the natural place. Fixes #4649.
diff --git a/ChangeLog.d/update_ssl_error_codes.txt b/ChangeLog.d/update_ssl_error_codes.txt
new file mode 100644
index 0000000..0630b54
--- /dev/null
+++ b/ChangeLog.d/update_ssl_error_codes.txt
@@ -0,0 +1,3 @@
+Changes
+   * Various changes to which alert and/or error code may be returned
+   * during the TLS handshake.
diff --git a/README.md b/README.md
index 78d3c30..a469f8f 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
 Configuration
 -------------
 
-Mbed TLS should build out of the box on most systems. Some platform specific options are available in the fully documented configuration file `include/mbedtls/config.h`, which is also the place where features can be selected. This file can be edited manually, or in a more programmatic way using the Python 3 script `scripts/config.py` (use `--help` for usage instructions).
+Mbed TLS should build out of the box on most systems. Some platform specific options are available in the fully documented configuration file `include/mbedtls/mbedtls_config.h`, which is also the place where features can be selected. This file can be edited manually, or in a more programmatic way using the Python 3 script `scripts/config.py` (use `--help` for usage instructions).
 
 Compiler options can be set using conventional environment variables such as `CC` and `CFLAGS` when using the Make and CMake build system (see below).
 
@@ -184,6 +184,33 @@
 your value of CFLAGS doesn't override the content provided by cmake (depending
 on the build mode as seen above), it's merely prepended to it.
 
+#### Consuming Mbed TLS
+
+Mbed TLS provides a package config file for consumption as a dependency in other
+CMake projects. You can include Mbed TLS's CMake targets yourself with:
+
+    find_package(MbedTLS)
+
+If prompted, set `MbedTLS_DIR` to `${YOUR_MBEDTLS_INSTALL_DIR}/cmake`. This
+creates the following targets:
+
+- `MbedTLS::mbedcrypto` (Crypto library)
+- `MbedTLS::mbedtls` (TLS library)
+- `MbedTLS::mbedx509` (X509 library)
+
+You can then use these directly through `target_link_libraries()`:
+
+    add_executable(xyz)
+
+    target_link_libraries(xyz
+        PUBLIC MbedTLS::mbedtls
+               MbedTLS::mbedcrypto
+               MbedTLS::mbedx509)
+
+This will link the Mbed TLS libraries to your library or application, and add
+its include directories to your target (transitively, in the case of `PUBLIC` or
+`INTERFACE` link libraries).
+
 #### Mbed TLS as a subproject
 
 Mbed TLS supports being built as a CMake subproject. One can
@@ -215,7 +242,7 @@
 -   `tests/compat.sh` tests interoperability of every ciphersuite with other implementations.
 -   `tests/scripts/test-ref-configs.pl` test builds in various reduced configurations.
 -   `tests/scripts/key-exchanges.pl` test builds in configurations with a single key exchange enabled
--   `tests/scripts/all.sh` runs a combination of the above tests, plus some more, with various build options (such as ASan, full `config.h`, etc).
+-   `tests/scripts/all.sh` runs a combination of the above tests, plus some more, with various build options (such as ASan, full `mbedtls_config.h`, etc).
 
 Porting Mbed TLS
 ----------------
@@ -254,7 +281,7 @@
 Mbed TLS includes a reference implementation of the PSA Cryptography API.
 This implementation is not yet as mature as the rest of the library. Some parts of the code have not been reviewed as thoroughly, and some parts of the PSA implementation are not yet well optimized for code size.
 
-The X.509 and TLS code can use PSA cryptography for a limited subset of operations. To enable this support, activate the compilation option `MBEDTLS_USE_PSA_CRYPTO` in `config.h`.
+The X.509 and TLS code can use PSA cryptography for a limited subset of operations. To enable this support, activate the compilation option `MBEDTLS_USE_PSA_CRYPTO` in `mbedtls_config.h`.
 
 There are currently a few deviations where the library does not yet implement the latest version of the specification. Please refer to the [compliance issues on Github](https://github.com/ARMmbed/mbed-crypto/labels/compliance) for an up-to-date list.
 
diff --git a/cmake/MbedTLSConfig.cmake.in b/cmake/MbedTLSConfig.cmake.in
new file mode 100644
index 0000000..b65bbab
--- /dev/null
+++ b/cmake/MbedTLSConfig.cmake.in
@@ -0,0 +1,3 @@
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/MbedTLSTargets.cmake")
diff --git a/configs/README.txt b/configs/README.txt
index 933fa7f..9e5a243 100644
--- a/configs/README.txt
+++ b/configs/README.txt
@@ -4,12 +4,10 @@
 a restricted number of ciphersuites) and aim at minimizing resource usage for
 this target. They can be used as a basis for custom configurations.
 
-These files are complete replacements for the default config.h. To use one of
+These files are complete replacements for the default mbedtls_config.h. To use one of
 them, you can pick one of the following methods:
 
-1. Replace the default file include/mbedtls/config.h with the chosen one.
-   (Depending on your compiler, you may need to adjust the line with
-   #include "mbedtls/check_config.h" then.)
+1. Replace the default file include/mbedtls/mbedtls_config.h with the chosen one.
 
 2. Define MBEDTLS_CONFIG_FILE and adjust the include path accordingly.
    For example, using make:
diff --git a/configs/config-ccm-psk-tls1_2.h b/configs/config-ccm-psk-tls1_2.h
index a829501..51bb962 100644
--- a/configs/config-ccm-psk-tls1_2.h
+++ b/configs/config-ccm-psk-tls1_2.h
@@ -29,8 +29,6 @@
  *
  * See README.txt for usage instructions.
  */
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
 
 /* System support */
 //#define MBEDTLS_HAVE_TIME /* Optionally used in Hello messages */
@@ -85,7 +83,3 @@
  */
 #define MBEDTLS_SSL_IN_CONTENT_LEN             1024
 #define MBEDTLS_SSL_OUT_CONTENT_LEN             1024
-
-#include "mbedtls/check_config.h"
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/configs/config-no-entropy.h b/configs/config-no-entropy.h
index 7ca33c3..edba4a0 100644
--- a/configs/config-no-entropy.h
+++ b/configs/config-no-entropy.h
@@ -29,9 +29,6 @@
  * See README.txt for usage instructions.
  */
 
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
 /* System support */
 #define MBEDTLS_HAVE_ASM
 #define MBEDTLS_HAVE_TIME
@@ -86,7 +83,3 @@
 
 /* Miscellaneous options */
 #define MBEDTLS_AES_ROM_TABLES
-
-#include "mbedtls/check_config.h"
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/configs/config-suite-b.h b/configs/config-suite-b.h
index b62bdfa..c70773d 100644
--- a/configs/config-suite-b.h
+++ b/configs/config-suite-b.h
@@ -33,9 +33,6 @@
  * See README.txt for usage instructions.
  */
 
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
 /* System support */
 #define MBEDTLS_HAVE_ASM
 #define MBEDTLS_HAVE_TIME
@@ -113,7 +110,3 @@
  */
 #define MBEDTLS_SSL_IN_CONTENT_LEN             1024
 #define MBEDTLS_SSL_OUT_CONTENT_LEN             1024
-
-#include "mbedtls/check_config.h"
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/configs/config-symmetric-only.h b/configs/config-symmetric-only.h
index 5b10063..6aff42f 100644
--- a/configs/config-symmetric-only.h
+++ b/configs/config-symmetric-only.h
@@ -20,9 +20,6 @@
  *  limitations under the License.
  */
 
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
 /* System support */
 //#define MBEDTLS_HAVE_ASM
 #define MBEDTLS_HAVE_TIME
@@ -90,9 +87,3 @@
 //#define MBEDTLS_THREADING_C
 #define MBEDTLS_TIMING_C
 #define MBEDTLS_VERSION_C
-
-#include "mbedtls/config_psa.h"
-
-#include "check_config.h"
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/configs/config-thread.h b/configs/config-thread.h
index c1937de..be889a1 100644
--- a/configs/config-thread.h
+++ b/configs/config-thread.h
@@ -32,9 +32,6 @@
  * See README.txt for usage instructions.
  */
 
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
 /* System support */
 #define MBEDTLS_HAVE_ASM
 
@@ -89,7 +86,3 @@
 
 /* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
 #define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
-
-#include "mbedtls/check_config.h"
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/docs/3.0-migration-guide.d/00README b/docs/3.0-migration-guide.d/00README
deleted file mode 100644
index a41733e..0000000
--- a/docs/3.0-migration-guide.d/00README
+++ /dev/null
@@ -1,27 +0,0 @@
-Please add your migration guide entries here. Until 3.0 is released, each PR
-that makes backwards-incompatible changes should add a file here, with the
-extension .md, a descriptive name and the following format:
-
----%<------%<------%<------%<------%<------%<------%<------%<---
-
-The change that was made
-------------------------
-
-Who exactly is affected: does this affect users of the default config, of a
-particular feature? Remember to contextualise.
-
-If I'm affected, what's my migration path? How should I change my code if this
-is an API change; if a feature was removed what are my alternatives?
-
----%<------%<------%<------%<------%<------%<------%<------%<---
-
-PRs that make multiple independent changes should include one entry for each
-changes or logical groups of changes. You can either add multiple files or put
-multiple entries in the same file.
-
-For examples, have a look a docs/3.0-migration-guide.md (which includes the
-top-level header and an intro before the list of entries).
-
-As part of release preparation, the entries in this directory will be appended
-to docs/3.0-migration-guide.md and then re-ordered and reviewed one last time.
-The file is then going to be moved to the version-independent docs repo.
diff --git a/docs/3.0-migration-guide.d/Remove_3DES_ciphersuites.md b/docs/3.0-migration-guide.d/Remove_3DES_ciphersuites.md
deleted file mode 100644
index 85a85b9..0000000
--- a/docs/3.0-migration-guide.d/Remove_3DES_ciphersuites.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Remove 3DES ciphersuites
---
-
-This change does not affect users using default settings for 3DES in `config.h`
-because the 3DES ciphersuites were disabled by that.
-
-3DES has weaknesses/limitations and there are better alternatives, and more and
-more standard bodies are recommending against its use in TLS.
-
-The migration path here is to chose from the recomended in literature alternatives.
diff --git a/docs/3.0-migration-guide.d/ccm-alt.md b/docs/3.0-migration-guide.d/ccm-alt.md
deleted file mode 100644
index 1abac7a..0000000
--- a/docs/3.0-migration-guide.d/ccm-alt.md
+++ /dev/null
@@ -1,9 +0,0 @@
-CCM interface changes: impact for alternative implementations
--------------------------------------------------------------
-
-The CCM interface has changed with the addition of support for
-multi-part operations. Five new API functions have been defined:
-mbedtls_ccm_starts(), mbedtls_ccm_set_lengths(),
-mbedtls_ccm_update_ad(), mbedtls_ccm_update() and mbedtls_ccm_finish().
-Alternative implementations of CCM (`MBEDTLS_CCM_ALT`) have now to
-implement those additional five API functions.
diff --git a/docs/3.0-migration-guide.d/cipher-delayed-output.md b/docs/3.0-migration-guide.d/cipher-delayed-output.md
deleted file mode 100644
index 18d3271..0000000
--- a/docs/3.0-migration-guide.d/cipher-delayed-output.md
+++ /dev/null
@@ -1,15 +0,0 @@
-Calling `mbedtls_cipher_finish()` is mandatory for all multi-part operations
-----------------------------------------------------------------------------
-
-This only affects people who use the cipher module to perform AEAD operations
-using the multi-part API.
-
-Previously, the documentation didn't state explicitly if it was OK to call
-`mbedtls_cipher_check_tag()` or `mbedtls_cipher_write_tag()` directly after
-the last call to `mbedtls_cipher_update()` - that is, without calling
-`mbedtls_cipher_finish()` in-between. If you code was missing that call,
-please add it and be prepared to get as much as 15 bytes of output.
-
-Currently the output is always 0 bytes, but it may be more when alternative
-implementations of the underlying primitives are in use, or with future
-versions of the library.
diff --git a/docs/3.0-migration-guide.d/combine_SSL_CID-TLS1_3_PADDING_GRANULARITY_options.md b/docs/3.0-migration-guide.d/combine_SSL_CID-TLS1_3_PADDING_GRANULARITY_options.md
deleted file mode 100644
index bc3fa68..0000000
--- a/docs/3.0-migration-guide.d/combine_SSL_CID-TLS1_3_PADDING_GRANULARITY_options.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Combine the `MBEDTLS_SSL_CID_PADDING_GRANULARITY` and `MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY` options
---
-
-This change affects users who modified the default `config.h` padding granularity
-settings, i.e. enabled at least one of the options.
-
-The `config.h` options `MBEDTLS_SSL_CID_PADDING_GRANULARITY` and
-`MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY` were combined into one option because
-they used exactly the same padding mechanism and hence their respective padding
-granularities can be used in exactly the same way. This change simplifies the
-code maintenance.
-
-The new single option `MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY` can be used
-for both DTLS-CID and TLS 1.3.
diff --git a/docs/3.0-migration-guide.d/csr-add-critical-extension.md b/docs/3.0-migration-guide.d/csr-add-critical-extension.md
deleted file mode 100644
index ebcb343..0000000
--- a/docs/3.0-migration-guide.d/csr-add-critical-extension.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Change the API to allow adding critical extensions to CSRs
-------------------------------------------------------------------
-
-This affects applications that call the `mbedtls_x509write_csr_set_extension`
-function.
-
-The API is changed to include the parameter `critical` which allow to mark an
-extension included in a CSR as critical. To get the previous behaviour pass
-`0`.
diff --git a/docs/3.0-migration-guide.d/default-curves.md b/docs/3.0-migration-guide.d/default-curves.md
deleted file mode 100644
index 928130d..0000000
--- a/docs/3.0-migration-guide.d/default-curves.md
+++ /dev/null
@@ -1,25 +0,0 @@
-Strengthen default algorithm selection for X.509 and TLS
---------------------------------------------------------
-
-The default X.509 verification profile (`mbedtls_x509_crt_profile_default`) and the default curve and hash selection in TLS have changed. They are now aligned, except that the X.509 profile only lists curves that support signature verification.
-
-Hashes and curves weaker than 255 bits (security strength less than 128 bits) are no longer accepted by default. The following hashes have been removed: SHA-1 (formerly only accepted for key exchanges but not for certificate signatures), SHA-224 (weaker hashes were already not accepted). The following curves have been removed: secp192r1, secp224r1, secp192k1, secp224k1.
-
-The compile-time options `MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES` and `MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE` are no longer available.
-
-The curve secp256k1 has also been removed from the default X.509 and TLS profiles. [RFC 8422](https://datatracker.ietf.org/doc/html/rfc8422#section-5.1.1) deprecates it in TLS, and it is very rarely used, although it is not known to be weak at the time of writing.
-
-If you still need to accept certificates signed with algorithms that have been removed from the default profile, call `mbedtls_x509_crt_verify_with_profile` instead of `mbedtls_x509_crt_verify` and pass a profile that allows the curves and hashes you want. For example, to allow SHA-224:
-```
-mbedtls_x509_crt_profile my_profile = mbedtls_x509_crt_profile_default;
-my_profile.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 );
-```
-
-If you still need to allow hashes and curves in TLS that have been removed from the default configuration, call `mbedtls_ssl_conf_sig_hashes()` and `mbedtls_ssl_conf_curves()` with the desired lists.
-
-TLS now favors faster curves over larger curves
------------------------------------------------
-
-The default preference order for curves in TLS now favors resource usage (performance and memory consumption) over size. The exact order is unspecified and may change, but generally you can expect 256-bit curves to be preferred over larger curves.
-
-If you prefer a different order, call `mbedtls_ssl_conf_curves()` when configuring a TLS connection.
diff --git a/docs/3.0-migration-guide.d/gcm-alt.md b/docs/3.0-migration-guide.d/gcm-alt.md
deleted file mode 100644
index 388e2be..0000000
--- a/docs/3.0-migration-guide.d/gcm-alt.md
+++ /dev/null
@@ -1,10 +0,0 @@
-GCM interface changes: impact for alternative implementations
--------------------------------------------------------------
-
-The GCM multipart interface has changed as described in [“GCM multipart interface: application changes”](#gcm-multipart-interface:-application-changes). The consequences for an alternative implementation of GCM (`MBEDTLS_GCM_ALT`) are as follows:
-
-* `mbedtls_gcm_starts()` now only sets the mode and the nonce (IV). The new function `mbedtls_gcm_update_ad()` receives the associated data. It may be called multiple times.
-* `mbedtls_gcm_update()` now allows arbitrary-length inputs, takes an extra parameter to indicate the actual output length. Alternative implementations may choose between two modes:
-    * Always return the partial output immediately, even if it does not consist of a whole number of blocks.
-    * Buffer the data for the last partial block, to be returned in the next call to `mbedtls_gcm_update()` or `mbedtls_gcm_finish()`.
-* `mbedtls_gcm_finish()` now takes an extra output buffer for the last partial block if needed.
diff --git a/docs/3.0-migration-guide.d/gcm-multipart.md b/docs/3.0-migration-guide.d/gcm-multipart.md
deleted file mode 100644
index 98e9fad..0000000
--- a/docs/3.0-migration-guide.d/gcm-multipart.md
+++ /dev/null
@@ -1,13 +0,0 @@
-GCM multipart interface: application changes
---------------------------------------------
-
-The GCM module now supports arbitrary chunked input in the multipart interface.
-This changes the interface for applications using the GCM module directly for multipart operations.
-Applications using one-shot GCM or using GCM via the `mbedtls_cipher_xxx` or `psa_aead_xxx` interfaces do not require any changes.
-
-* `mbedtls_gcm_starts()` now only sets the mode and the nonce (IV). Call the new function `mbedtls_gcm_update_ad()` to pass the associated data.
-* The current implementation has a limitation that `mbedtls_gcm_update_ad()` may only be called once. This limitation will be lifted shortly; watch https://github.com/ARMmbed/mbedtls/issues/4351 for updates.
-* `mbedtls_gcm_update()` now takes an extra parameter to indicate the actual output length. In Mbed TLS 2.x, applications had to pass inputs consisting of whole 16-byte blocks except for the last block (this limitation has been lifted). In this case:
-    * As long as the input remains block-aligned, the output length is exactly the input length, as before.
-    * If the length of the last input is not a multiple of 16, alternative implementations may return the last partial block in the call to `mbedtls_gcm_finish()` instead of returning it in the last call to `mbedtls_gcm_update()`.
-* `mbedtls_gcm_finish()` now takes an extra output buffer for the last partial block. This is needed for alternative implementations that can only process a whole block at a time.
diff --git a/docs/3.0-migration-guide.d/key-export.md b/docs/3.0-migration-guide.d/key-export.md
deleted file mode 100644
index f8b3505..0000000
--- a/docs/3.0-migration-guide.d/key-export.md
+++ /dev/null
@@ -1,36 +0,0 @@
-SSL key export interface change
--------------------------------
-
-This affects users of the SSL key export APIs:
-```
-    mbedtls_ssl_conf_export_keys_cb()
-    mbedtls_ssl_conf_export_keys_ext_cb()
-```
-
-Those APIs have been removed and replaced by the new API
-`mbedtls_ssl_set_export_keys_cb()`. This API differs from
-the previous key export API in the following ways:
-
-- It is no longer bound to an SSL configuration, but to an
-  SSL context. This allows users to more easily identify the
-  connection an exported key belongs to.
-- It no longer exports raw keys and IV.
-- A secret type parameter has been added to identify which key
-  is being exported. For TLS 1.2, only the master secret is
-  exported, but upcoming TLS 1.3 support will add other kinds of keys.
-- The callback now specifies a void return type, rather than
-  returning an error code. It is the responsibility of the application
-  to handle failures in the key export callback, for example by
-  shutting down the TLS connection.
-
-For users which do not rely on raw keys and IV, adjusting to the new
-callback type should be straightforward - see the example programs
-programs/ssl/ssl_client2 and programs/ssl/ssl_server2 for callbacks
-for NSSKeylog, EAP-TLS and DTLS-SRTP.
-
-Users which require access to the raw keys used to secure application
-traffic may derive those by hand based on the master secret and the
-handshake transcript hashes which can be obtained from the raw data
-on the wire. Such users are also encouraged to reach out to the
-Mbed TLS team on the mailing list, to let the team know about their
-use case.
diff --git a/docs/3.0-migration-guide.d/mandatory-rng-param.md b/docs/3.0-migration-guide.d/mandatory-rng-param.md
deleted file mode 100644
index f6aba08..0000000
--- a/docs/3.0-migration-guide.d/mandatory-rng-param.md
+++ /dev/null
@@ -1,40 +0,0 @@
-The RNG parameter is now mandatory for all functions that accept one
---------------------------------------------------------------------
-
-This change affects all users who called a function accepting a `f_rng`
-parameter with `NULL` as the value of this argument; this is no longer
-supported.
-
-The changed functions are: the X.509 CRT and CSR writing functions; the PK and
-RSA sign and decrypt functions; `mbedtls_rsa_private()`; the functions in DHM
-and ECDH that compute the shared secret; the scalar multiplication functions in
-ECP.
-
-You now need to pass a properly seeded, cryptographically secure RNG to all
-functions that accept a `f_rng` parameter. It is of course still possible to
-pass `NULL` as the context pointer `p_rng` if your RNG function doesn't need a
-context.
-
-Alternative implementations of a module (enabled with the `MBEDTLS_module_ALT`
-configuration options) may have their own internal and are free to ignore the
-`f_rng` argument but must allow users to pass one anyway.
-
-Some functions gained an RNG parameter
---------------------------------------
-
-This affects users of the following functions: `mbedtls_ecp_check_pub_priv()`,
-`mbedtls_pk_check_pair()`, `mbedtls_pk_parse_key()`, and
-`mbedtls_pk_parse_keyfile()`.
-
-You now need to pass a properly seeded, cryptographically secure RNG when
-calling these functions. It is used for blinding, a counter-measure against
-side-channel attacks.
-
-The configuration option `MBEDTLS_ECP_NO_INTERNAL_RNG` was removed
-------------------------------------------------------------------
-
-This doesn't affect users of the default configuration; it only affects people
-who were explicitly setting this option.
-
-This was a trade-off between code size and counter-measures; it is no longer
-relevant as the counter-measure is now always on at no cost in code size.
diff --git a/docs/3.0-migration-guide.d/max-record-payload-api.md b/docs/3.0-migration-guide.d/max-record-payload-api.md
deleted file mode 100644
index 0b34915..0000000
--- a/docs/3.0-migration-guide.d/max-record-payload-api.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Remove MaximumFragmentLength (MFL) query API
------------------------------------------------------------------
-
-This affects users which use the MFL query APIs
-`mbedtls_ssl_get_{input,output}_max_frag_len()` to
-infer upper bounds on the plaintext size of incoming and
-outgoing record.
-
-Users should switch to `mbedtls_ssl_get_max_{in,out}_record_payload()`
-instead, which also provides such upper bounds but takes more factors
-than just the MFL configuration into account.
diff --git a/docs/3.0-migration-guide.d/modify_MBEDTLS_ECP_FIXED_POINT_OPTIM_behaviour.md b/docs/3.0-migration-guide.d/modify_MBEDTLS_ECP_FIXED_POINT_OPTIM_behaviour.md
deleted file mode 100644
index 91bec72..0000000
--- a/docs/3.0-migration-guide.d/modify_MBEDTLS_ECP_FIXED_POINT_OPTIM_behaviour.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Change MBEDTLS_ECP_FIXED_POINT_OPTIM behaviour
-------------------------------------------------------
-
-The option `MBEDTLS_ECP_FIXED_POINT_OPTIM` now increase code size and it does
-not increase peak RAM usage anymore.
-
-If you are limited by code size, you can define `MBEDTLS_ECP_FIXED_POINT_OPTIM`
-to `0` in your config file. The impact depends on the number and size of
-enabled curves. For example, for P-256 the difference is 1KB; see the documentation
-of this option for details.
-
diff --git a/docs/3.0-migration-guide.d/modify_SHA384_option_behaviour.md b/docs/3.0-migration-guide.d/modify_SHA384_option_behaviour.md
deleted file mode 100644
index fe6c75e..0000000
--- a/docs/3.0-migration-guide.d/modify_SHA384_option_behaviour.md
+++ /dev/null
@@ -1,12 +0,0 @@
-Replaced MBEDTLS_SHA512_NO_SHA384 with MBEDTLS_SHA384_C
-------------------------------------------------------
-
-This does not affect users who use the default `config.h`.
-MBEDTLS_SHA512_NO_SHA384 was disabled by default, now MBEDTLS_SHA384_C is
-enabled by default.
-
-If you were using a config file with both MBEDTLS_SHA512_C and
-MBEDTLS_SHA512_NO_SHA384, then just remove the MBEDTLS_SHA512_NO_SHA384.
-If you were using a config file with MBEDTLS_SHA512_C and without
-MBEDTLS_SHA512_NO_SHA384 and you need the SHA-384 algorithm, then add
-`#define MBEDTLS_SHA384_C` to your config file.
diff --git a/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md b/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md
deleted file mode 100644
index fa61e27..0000000
--- a/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Move part of timing module out of the library
---
-
-The change affects users who use any of the following functions:
-`mbedtls_timing_self_test()`, `mbedtls_hardclock_poll()`,
-`mbedtls_timing_hardclock()` and `mbedtls_set_alarm()`.
-
-If you were relying on these functions, you'll now need to change to using your
-platform's corresponding functions directly.
diff --git a/docs/3.0-migration-guide.d/relaxed-psk-semantics.md b/docs/3.0-migration-guide.d/relaxed-psk-semantics.md
deleted file mode 100644
index 6b0e794..0000000
--- a/docs/3.0-migration-guide.d/relaxed-psk-semantics.md
+++ /dev/null
@@ -1,18 +0,0 @@
-Relaxed semantics for PSK configuration
------------------------------------------------------------------
-
-This affects users which call the PSK configuration APIs
-`mbedtlsl_ssl_conf_psk()` and `mbedtls_ssl_conf_psk_opaque()`
-multiple times on the same SSL configuration.
-
-In Mbed TLS 2.x, users would observe later calls overwriting
-the effect of earlier calls, with the prevailing PSK being
-the one that has been configured last. In Mbed TLS 3.0,
-calling `mbedtls_ssl_conf_[opaque_]psk()` multiple times
-will return an error, leaving the first PSK intact.
-
-To achieve equivalent functionality when migrating to Mbed TLS 3.0,
-users calling `mbedtls_ssl_conf_[opaque_]psk()` multiple times should
-remove all but the last call, so that only one call to _either_
-`mbedtls_ssl_conf_psk()` _or_ `mbedtls_ssl_conf_psk_opaque()`
-remains.
diff --git a/docs/3.0-migration-guide.d/remove-enable-weak-ciphersuites.md b/docs/3.0-migration-guide.d/remove-enable-weak-ciphersuites.md
deleted file mode 100644
index c3c3306..0000000
--- a/docs/3.0-migration-guide.d/remove-enable-weak-ciphersuites.md
+++ /dev/null
@@ -1,12 +0,0 @@
-Remove the configuration to enable weak ciphersuites in SSL / TLS
------------------------------------------------------------------
-
-This does not affect users who use the default `config.h`, as this option was
-already off by default.
-
-If you were using a weak cipher, please switch to any of the modern,
-recommended ciphersuites (based on AES-GCM, AES-CCM or ChachaPoly for example)
-and if your peer doesn't support any, encourage them to upgrade their software.
-
-If you were using a ciphersuite without encryption, you just have to
-enable MBEDTLS_CIPHER_NULL_CIPHER now.
diff --git a/docs/3.0-migration-guide.d/remove-max-content-len.md b/docs/3.0-migration-guide.d/remove-max-content-len.md
deleted file mode 100644
index 40c7d53..0000000
--- a/docs/3.0-migration-guide.d/remove-max-content-len.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Remove the `MBEDTLS_SSL_MAX_CONTENT_LEN` configuration option
--------------------------------------------------------------
-
-This affects users who use the `MBEDTLS_SSL_MAX_CONTENT_LEN` option to
-set the maximum length of incoming and outgoing plaintext fragments,
-which can save memory by reducing the size of the TLS I/O buffers.
-
-This option is replaced by the more fine-grained options
-`MBEDTLS_SSL_IN_CONTENT_LEN` and `MBEDTLS_SSL_OUT_CONTENT_LEN` that set
-the maximum incoming and outgoing plaintext fragment lengths, respectively.
diff --git a/docs/3.0-migration-guide.d/remove-null-entropy.md b/docs/3.0-migration-guide.d/remove-null-entropy.md
deleted file mode 100644
index 50e024a..0000000
--- a/docs/3.0-migration-guide.d/remove-null-entropy.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Remove the option to build the library without any entropy sources
-------------------------------------------------------------------
-
-This does not affect users who use the default `config.h`, as this option was
-already off by default.
-
-If you were using the `MBEDTLS_TEST_NULL_ENTROPY` option and your platform
-doesn't have any entropy source, you should use `MBEDTLS_ENTROPY_NV_SEED`
-and make sure your device is provisioned with a strong random seed.
-Alternatively, for testing purposes only, you can create and register a fake
-entropy function.
diff --git a/docs/3.0-migration-guide.d/remove-rsa-mode-parameter.md b/docs/3.0-migration-guide.d/remove-rsa-mode-parameter.md
deleted file mode 100644
index d21d5ed..0000000
--- a/docs/3.0-migration-guide.d/remove-rsa-mode-parameter.md
+++ /dev/null
@@ -1,21 +0,0 @@
-Remove the mode parameter from RSA functions
---------------------------------------------
-
-This affects all users who use the RSA encryption, decryption, sign and
-verify APIs.
-
-The RSA module no longer supports private-key operations with the public key or
-vice versa. As a consequence, RSA operation functions no longer have a mode
-parameter. If you were calling RSA operations with the normal mode (public key
-for verification or encryption, private key for signature or decryption), remove
-the `MBEDTLS_MODE_PUBLIC` or `MBEDTLS_MODE_PRIVATE` argument. If you were calling
-RSA operations with the wrong mode, which rarely makes sense from a security
-perspective, this is no longer supported.
-
-Remove the RNG parameter from RSA verify functions
---------------------------------------------------
-
-RSA verification functions also no longer take random generator arguments (this
-was only needed when using a private key). This affects all applications using
-the RSA verify functions.
-
diff --git a/docs/3.0-migration-guide.d/remove-ssl-get-session_pointer.md b/docs/3.0-migration-guide.d/remove-ssl-get-session_pointer.md
deleted file mode 100644
index a4a4895..0000000
--- a/docs/3.0-migration-guide.d/remove-ssl-get-session_pointer.md
+++ /dev/null
@@ -1,23 +0,0 @@
-Remove the SSL API mbedtls_ssl_get_session_pointer()
------------------------------------------------------------------
-
-This affects two classes of users:
-
-1. Users who manually inspect parts of the current session through
-   direct structure field access.
-
-2. Users of session resumption who query the current session
-   via `mbedtls_ssl_get_session_pointer()` prior to saving or exporting
-   it via `mbedtls_ssl_session_copy()` or `mbedtls_ssl_session_save()`,
-   respectively.
-
-Migration paths:
-
-1. Mbed TLS 3.0 does not offer a migration path for the usecase 1: Like many
-   other Mbed TLS structures, the structure of `mbedtls_ssl_session` is no
-   longer part of the public API in Mbed TLS 3.0, and direct structure field
-   access is no longer supported. Please see the corresponding migration guide.
-
-2. Users should replace calls to `mbedtls_ssl_get_session_pointer()` by
-   calls to `mbedtls_ssl_get_session()` as demonstrated in the example
-   program `programs/ssl/ssl_client2.c`.
diff --git a/docs/3.0-migration-guide.d/remove_MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION.md b/docs/3.0-migration-guide.d/remove_MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION.md
deleted file mode 100644
index 738fa81..0000000
--- a/docs/3.0-migration-guide.d/remove_MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION.md
+++ /dev/null
@@ -1,17 +0,0 @@
-Remove the config option MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
---------------------------------------------------------------------------
-
-This change does not affect users of the default configuration; it only affect
-users who enable this option.
-
-The X.509 standard says that implementations must reject critical extensions that
-they don't recognize, and this is what Mbed TLS does by default. This option
-allowed to continue parsing those certificates but didn't provide a convenient
-way to handle those extensions.
-
-The migration path from that option is to use the
-`mbedtls_x509_crt_parse_der_with_ext_cb()` function which is functionally
-equivalent to `mbedtls_x509_crt_parse_der()`, and/or
-`mbedtls_x509_crt_parse_der_nocopy()` but it calls the callback with every
-unsupported certificate extension and additionally the "certificate policies"
-extension if it contains any unsupported certificate policies.
diff --git a/docs/3.0-migration-guide.d/remove_MBEDTLS_X509_CHECK_x_KEY_USAGE_options.md b/docs/3.0-migration-guide.d/remove_MBEDTLS_X509_CHECK_x_KEY_USAGE_options.md
deleted file mode 100644
index 2acb3bf..0000000
--- a/docs/3.0-migration-guide.d/remove_MBEDTLS_X509_CHECK_x_KEY_USAGE_options.md
+++ /dev/null
@@ -1,18 +0,0 @@
-Remove `MBEDTLS_X509_CHECK_*_KEY_USAGE` options from `config.h`
--------------------------------------------------------------------
-
-This change affects users who have chosen the configuration options to disable the
-library's verification of the `keyUsage` and `extendedKeyUsage` fields of x509
-certificates.
-
-The `MBEDTLS_X509_CHECK_KEY_USAGE` and `MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE`
-configuration options are removed and the X509 code now behaves as if they were
-always enabled. It is consequently not possible anymore to disable at compile
-time the verification of the `keyUsage` and `extendedKeyUsage` fields of X509
-certificates.
-
-The verification of the `keyUsage` and `extendedKeyUsage` fields is important,
-disabling it can cause security issues and it is thus not recommended. If the
-verification is for some reason undesirable, it can still be disabled by means
-of the verification callback function passed to `mbedtls_x509_crt_verify()` (see
-the documentation of this function for more information).
diff --git a/docs/3.0-migration-guide.d/remove_MD2_MD4_RC4_Blowfish_XTEA.md b/docs/3.0-migration-guide.d/remove_MD2_MD4_RC4_Blowfish_XTEA.md
deleted file mode 100644
index d199f2f..0000000
--- a/docs/3.0-migration-guide.d/remove_MD2_MD4_RC4_Blowfish_XTEA.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Remove MD2, MD4, RC4, Blowfish and XTEA algorithms
---
-
-This change affects users of the MD2, MD4, RC4, Blowfish and XTEA algorithms.
-
-They are already niche or obsolete and most of them are weak or broken. For
-those reasons possible users should consider switching to modern and safe
-alternatives to be found in literature.
diff --git a/docs/3.0-migration-guide.d/remove_SSL_DTLS_BADMAC_LIMIT_option.md b/docs/3.0-migration-guide.d/remove_SSL_DTLS_BADMAC_LIMIT_option.md
deleted file mode 100644
index f81bdad..0000000
--- a/docs/3.0-migration-guide.d/remove_SSL_DTLS_BADMAC_LIMIT_option.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Remove MBEDTLS_SSL_DTLS_BADMAC_LIMIT option
--------------------------------------------
-
-This change does not affect users who used the default `config.h`, as the option
-MBEDTLS_SSL_DTLS_BADMAC_LIMIT was already on by default.
-
-This option was a trade-off between functionality and code size: it allowed
-users who didn't need that feature to avoid paying the cost in code size, by
-disabling it.
-
-This option is no longer present, but its functionality is now always enabled.
diff --git a/docs/3.0-migration-guide.d/remove_deprecated_functions_and_constants.md b/docs/3.0-migration-guide.d/remove_deprecated_functions_and_constants.md
deleted file mode 100644
index 31c2ce8..0000000
--- a/docs/3.0-migration-guide.d/remove_deprecated_functions_and_constants.md
+++ /dev/null
@@ -1,74 +0,0 @@
-Deprecated functions were removed from AES
-------------------------------------------
-
-The functions `mbedtls_aes_encrypt()` and `mbedtls_aes_decrypt()` were
-removed.
-
-If you're simply using the AES module, you should be calling the higher-level
-functions `mbedtls_aes_crypt_xxx()`.
-
-If you're providing an alternative implementation using
-`MBEDTLS_AES_ENCRYPT_ALT` or `MBEDTLS_AES_DECRYPT_ALT`, you should be
-replacing the removed functions with `mbedtls_internal_aes_encrypt()` and
-`mbedtls_internal_aes_decrypt()` respectively.
-
-Deprecated functions were removed from bignum
----------------------------------------------
-
-The function `mbedtls_mpi_is_prime()` was removed. Please use
-`mbedtls_mpi_is_prime_ext()` instead which additionally allows specifying the
-number of Miller-Rabin rounds.
-
-Deprecated functions were removed from cipher
----------------------------------------------
-
-The functions `mbedtls_cipher_auth_encrypt()` and
-`mbedtls_cipher_auth_decrypt()` were removed. They were superseded by
-`mbedtls_cipher_auth_encrypt_ext()` and `mbedtls_cipher_auth_decrypt_ext()`
-respectively which additionally support key wrapping algorithms such as
-NIST_KW.
-
-Deprecated functions were removed from DRBGs
---------------------------------------------
-
-The functions `mbedtls_ctr_drbg_update()` and `mbedtls_hmac_drbg_update()`
-were removed. They were superseded by `mbedtls_ctr_drbg_update_ret()` and
-`mbedtls_hmac_drbg_update_ret()` respectively.
-
-Deprecated functions were removed from ECDSA
---------------------------------------------
-
-The functions `mbedtls_ecdsa_write_signature_det()` and
-`mbedtls_ecdsa_sign_det()` were removed. They were superseded by
-`mbedtls_ecdsa_write_signature()` and `mbedtls_ecdsa_sign_det_ext()`
-respectively.
-
-Deprecated functions were removed from SSL
-------------------------------------------
-
-The function `mbedtls_ssl_conf_dh_param()` was removed. Please use
-`mbedtls_ssl_conf_dh_param_bin()` or `mbedtls_ssl_conf_dh_param_ctx()` instead.
-
-The function `mbedtls_ssl_get_max_frag_len()` was removed. Please use
-`mbedtls_ssl_get_max_out_record_payload()` and
-`mbedtls_ssl_get_max_in_record_payload()`
-instead.
-
-Deprecated hex-encoded primes were removed from DHM
----------------------------------------------------
-
-The macros `MBEDTLS_DHM_RFC5114_MODP_2048_P`, `MBEDTLS_DHM_RFC5114_MODP_2048_G`,
-`MBEDTLS_DHM_RFC3526_MODP_2048_P`, `MBEDTLS_DHM_RFC3526_MODP_2048_G`,
-`MBEDTLS_DHM_RFC3526_MODP_3072_P`, `MBEDTLS_DHM_RFC3526_MODP_3072_G`,
-`MBEDTLS_DHM_RFC3526_MODP_4096_P `and `MBEDTLS_DHM_RFC3526_MODP_4096_G` were
-removed. The primes from RFC 5114 are deprecated because their derivation is not
-documented and therefore their usage constitutes a security risk; they are fully
-removed from the library. Please use parameters from RFC3526 (still in the
-library, only in binary form) or RFC 7919 (also available in the library) or
-other trusted sources instead.
-
-Deprecated net.h file was removed
----------------------------------
-
-The file `include/mbedtls/net.h` was removed because its only function was to
-include `mbedtls/net_sockets.h` which now should be included directly.
diff --git a/docs/3.0-migration-guide.d/remove_mbedtls_check_params_option.md b/docs/3.0-migration-guide.d/remove_mbedtls_check_params_option.md
deleted file mode 100644
index 6f43aa3..0000000
--- a/docs/3.0-migration-guide.d/remove_mbedtls_check_params_option.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Remove MBEDTLS_CHECK_PARAMS option
-----------------------------------
-
-This change does not affect users who use the default configuration; it only
-affects users who enabled that option.
-
-The option `MBEDTLS_CHECK_PARAMS` (disabled by default) enabled certain kinds
-of “parameter validation”. It covered two kinds of validations:
-
-- In some functions that require a valid pointer, “parameter validation” checks
-that the pointer is non-null. With the feature disabled, a null pointer is not
-treated differently from any other invalid pointer, and typically leads to a
-runtime crash. 90% of the uses of the feature are of this kind.
-- In some functions that take an enum-like argument, “parameter validation”
-checks that the value is a valid one. With the feature disabled, an invalid
-value causes a silent default to one of the valid values.
-
-The default reaction to a failed check was to call a function
-`mbedtls_param_failed()` which the application had to provide. If this function
-returned, its caller returned an error `MBEDTLS_ERR_xxx_BAD_INPUT_DATA`.
-
-This feature was only used in some classic (non-PSA) cryptography modules. It was
-not used in X.509, TLS or in PSA crypto, and it was not implemented in all
-classic crypto modules.
-
-This feature has been removed. The library no longer checks for NULL pointers;
-checks for enum-like arguments will be kept or re-introduced on a case-by-case
-basis, but their presence will no longer be dependent on a compile-time option.
-
-Validation of enum-like values is somewhat useful, but not extremely important,
-because the parameters concerned are usually constants in applications.
-
-For more information see issue #4313.
diff --git a/docs/3.0-migration-guide.d/remove_ssl_record_checking.md b/docs/3.0-migration-guide.d/remove_ssl_record_checking.md
deleted file mode 100644
index 7550f7b..0000000
--- a/docs/3.0-migration-guide.d/remove_ssl_record_checking.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Remove MBEDTLS_SSL_RECORD_CHECKING option and enable its action by default
---------------------------------------------------------------------------
-
-This change does not affect users who use the default config.h, as the
-option MBEDTLS_SSL_RECORD_CHECKING was already on by default.
-
-This option was added only to control compilation of one function,
-mbedtls_ssl_check_record(), which is only useful in some specific cases, so it
-was made optional to allow users who don't need it to save some code space.
-However, the same effect can be achieve by using link-time garbage collection.
-
-Users who changed the default setting of the option need to change the config/
-build system to remove that change.
diff --git a/docs/3.0-migration-guide.d/remove_supp_for_extensions_in_pre-v3_X_509_certs.md b/docs/3.0-migration-guide.d/remove_supp_for_extensions_in_pre-v3_X_509_certs.md
deleted file mode 100644
index 4c87f03..0000000
--- a/docs/3.0-migration-guide.d/remove_supp_for_extensions_in_pre-v3_X_509_certs.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Remove the `MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3` option
---
-
-This change does not affect users who were using the default configuration, as
-this option was already disabled by default. Also, it does not affect users who
-are working with current V3 X.509 certificates.
-
-Extensions were added in V3 of the X.509 specification, so pre-V3 certificates
-containing extensions were never compliant. Mbed TLS now rejects them with a
-parsing error in all configurations, as it did previously in the default
-configuration.
-
-If you are working with the pre-V3 certificates you need to switch to the
-current ones.
diff --git a/docs/3.0-migration-guide.d/remove_support_for_tls_1.0_1.1_and_dtls_1.0.md b/docs/3.0-migration-guide.d/remove_support_for_tls_1.0_1.1_and_dtls_1.0.md
deleted file mode 100644
index 73d621f..0000000
--- a/docs/3.0-migration-guide.d/remove_support_for_tls_1.0_1.1_and_dtls_1.0.md
+++ /dev/null
@@ -1,27 +0,0 @@
-Remove suport for TLS 1.0, 1.1 and DTLS 1.0
--------------------------------------------
-
-This change affects users of the TLS 1.0, 1.1 and DTLS 1.0 protocols.
-
-These versions have been deprecated by RFC 8996.
-Keeping them in the library creates opportunities for misconfiguration
-and possibly downgrade attacks. More generally, more code means a larger attack
-surface, even if the code is supposedly not used.
-
-The migration path is to adopt the latest versions of the protocol.
-
-As a consequence of removing TLS 1.0, support for CBC record splitting was
-also removed, as it was a work-around for a weakness in this particular
-version. There is no migration path since the feature is no longer relevant.
-
-As a consequence of currently supporting only one version of (D)TLS (and in the
-future 1.3 which will have a different version negociation mechanism), support
-for fallback SCSV (RFC 7507) was also removed. There is no migration path as
-it's no longer useful with TLS 1.2 and later.
-
-As a consequence of currently supporting only one version of (D)TLS (and in the
-future 1.3 which will have a different concept of ciphersuites), support for
-configuring ciphersuites separately for each version via
-`mbedtls_ssl_conf_ciphersuites_for_version()` was removed. Use
-`mbedtls_ssl_conf_ciphersuites()` to configure ciphersuites to use with (D)TLS
-1.2; in the future a different API will be added for (D)TLS 1.3.
diff --git a/docs/3.0-migration-guide.d/rename_the__ret_functions.md b/docs/3.0-migration-guide.d/rename_the__ret_functions.md
deleted file mode 100644
index 875164b..0000000
--- a/docs/3.0-migration-guide.d/rename_the__ret_functions.md
+++ /dev/null
@@ -1,43 +0,0 @@
-Rename mbedtls_*_ret() cryptography functions whose deprecated variants
-have been removed
------------------
-
-This change affects users who were using the `mbedtls_*_ret()` cryptography
-functions.
-
-Those functions were created based on now-deprecated functions according to a
-requirement that a function needs to return a value. This change brings back the
-original names of those functions. The renamed functions are:
-
-| name before this change      | after the change         |
-|------------------------------|--------------------------|
-| mbedtls_ctr_drbg_update_ret  | mbedtls_ctr_drbg_update  |
-| mbedtls_hmac_drbg_update_ret | mbedtls_hmac_drbg_update |
-| mbedtls_md5_starts_ret       | mbedtls_md5_starts       |
-| mbedtls_md5_update_ret       | mbedtls_md5_update       |
-| mbedtls_md5_finish_ret       | mbedtls_md5_finish       |
-| mbedtls_md5_ret              | mbedtls_md5              |
-| mbedtls_ripemd160_starts_ret | mbedtls_ripemd160_starts |
-| mbedtls_ripemd160_update_ret | mbedtls_ripemd160_update |
-| mbedtls_ripemd160_finish_ret | mbedtls_ripemd160_finish |
-| mbedtls_ripemd160_ret        | mbedtls_ripemd160        |
-| mbedtls_sha1_starts_ret      | mbedtls_sha1_starts      |
-| mbedtls_sha1_update_ret      | mbedtls_sha1_update      |
-| mbedtls_sha1_finish_ret      | mbedtls_sha1_finish      |
-| mbedtls_sha1_ret             | mbedtls_sha1             |
-| mbedtls_sha256_starts_ret    | mbedtls_sha256_starts    |
-| mbedtls_sha256_update_ret    | mbedtls_sha256_update    |
-| mbedtls_sha256_finish_ret    | mbedtls_sha256_finish    |
-| mbedtls_sha256_ret           | mbedtls_sha256           |
-| mbedtls_sha512_starts_ret    | mbedtls_sha512_starts    |
-| mbedtls_sha512_update_ret    | mbedtls_sha512_update    |
-| mbedtls_sha512_finish_ret    | mbedtls_sha512_finish    |
-| mbedtls_sha512_ret           | mbedtls_sha512           |
-
-To migrate to the this change the user can keep the `*_ret` names in their code
-and include the `compat_2.x.h` header file which holds macros with proper
-renaming or to rename those function in their code according to the list from
-mentioned header file.
-
-
-
diff --git a/docs/3.0-migration-guide.d/rsa-padding.md b/docs/3.0-migration-guide.d/rsa-padding.md
deleted file mode 100644
index f10ece6..0000000
--- a/docs/3.0-migration-guide.d/rsa-padding.md
+++ /dev/null
@@ -1,29 +0,0 @@
-Remove the padding parameters from mbedtls_rsa_init()
------------------------------------------------------
-
-This affects all users who use the RSA encryption, decryption, sign and
-verify APIs.
-
-The function mbedtls_rsa_init() no longer supports selecting the PKCS#1 v2.1
-encoding and its hash. It just selects the PKCS#1 v1.5 encoding by default. If
-you were using the PKCS#1 v2.1 encoding you now need, subsequently to the call
-to mbedtls_rsa_init(), to call mbedtls_rsa_set_padding() to set it.
-
-To choose the padding type when initializing a context, instead of
-```C
-    mbedtls_rsa_init(ctx, padding, hash_id);
-```
-, use
-```C
-    mbedtls_rsa_init(ctx);
-    mbedtls_rsa_set_padding(ctx, padding, hash_id);
-```
-
-To use PKCS#1 v1.5 padding, instead of
-```C
-    mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, <ignored>);
-```
-, just use
-```C
-    mbedtls_rsa_init(ctx);
-```
diff --git a/docs/3.0-migration-guide.d/separate_SHA224_from_SHA256.md b/docs/3.0-migration-guide.d/separate_SHA224_from_SHA256.md
deleted file mode 100644
index 96a38e0..0000000
--- a/docs/3.0-migration-guide.d/separate_SHA224_from_SHA256.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Separated MBEDTLS_SHA224_C and MBEDTLS_SHA256_C
------------------------------------------------------------------
-
-This does not affect users who use the default `config.h`. MBEDTLS_SHA256_C
-was enabled by default. Now both MBEDTLS_SHA256_C and MBEDTLS_SHA224_C are
-enabled.
-
-If you were using custom config file with MBEDTLS_SHA256_C enabled, then
-you will need to add `#define MBEDTLS_SHA224_C` option your config.
-Current version of the library does not support enabling MBEDTLS_SHA256_C
-without MBEDTLS_SHA224_C.
diff --git a/docs/3.0-migration-guide.d/session-cache-api.md b/docs/3.0-migration-guide.d/session-cache-api.md
deleted file mode 100644
index b28ce19..0000000
--- a/docs/3.0-migration-guide.d/session-cache-api.md
+++ /dev/null
@@ -1,28 +0,0 @@
-Session Cache API Change
------------------------------------------------------------------
-
-This affects users who use `mbedtls_ssl_conf_session_cache()`
-to configure a custom session cache implementation different
-from the one Mbed TLS implements in `library/ssl_cache.c`.
-
-Those users will need to modify the API of their session cache
-implementation to that of a key-value store with keys being
-session IDs and values being instances of `mbedtls_ssl_session`:
-
-```
-typedef int mbedtls_ssl_cache_get_t( void *data,
-                                     unsigned char const *session_id,
-                                     size_t session_id_len,
-                                     mbedtls_ssl_session *session );
-typedef int mbedtls_ssl_cache_set_t( void *data,
-                                     unsigned char const *session_id,
-                                     size_t session_id_len,
-                                     const mbedtls_ssl_session *session );
-```
-
-Since the structure of `mbedtls_ssl_session` is no longer public from 3.0
-onwards, portable session cache implementations must not access fields of
-`mbedtls_ssl_session`. See the corresponding migration guide. Users that
-find themselves unable to migrate their session cache functionality without
-accessing fields of `mbedtls_ssl_session` should describe their usecase
-on the Mbed TLS mailing list.
diff --git a/docs/3.0-migration-guide.d/sha512-output-type.md b/docs/3.0-migration-guide.d/sha512-output-type.md
deleted file mode 100644
index c62a881..0000000
--- a/docs/3.0-migration-guide.d/sha512-output-type.md
+++ /dev/null
@@ -1,8 +0,0 @@
-SHA-512 and SHA-256 output type change
---------------------------
-
-The output parameter of `mbedtls_sha256_finish_ret()`, `mbedtls_sha256_ret()`, `mbedtls_sha512_finish_ret()`, `mbedtls_sha512_ret()` now has a pointer type rather than array type. This makes no difference in terms of C semantics, but removes spurious warnings in some compilers when outputting a SHA-384 hash into a 48-byte buffer or a SHA-224 hash into a 28-byte buffer.
-
-This makes no difference to a vast majority of applications. If your code takes a pointer to one of these functions, you may need to change the type of the pointer.
-
-Alternative implementations of the SHA256 and SHA512 modules must adjust their functions' prototype accordingly.
diff --git a/docs/3.0-migration-guide.d/ssl-error-code-cleanup.md b/docs/3.0-migration-guide.d/ssl-error-code-cleanup.md
deleted file mode 100644
index 49d1a0f..0000000
--- a/docs/3.0-migration-guide.d/ssl-error-code-cleanup.md
+++ /dev/null
@@ -1,20 +0,0 @@
-Removal of some SSL error codes
------------------------------------------------------------------
-
-This affects users manually checking for the following error codes:
-- `MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED`
-- `MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH`
-- `MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE`
-
-Migration paths:
-- `MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED` and `MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH`
-  should never be returned from Mbed TLS, and there is no need to check for it.
-  Users should simply remove manual checks for those codes, and let the Mbed TLS
-  team know if -- contrary to the team's understanding -- there is in fact a situation
-  where one of them was ever returned.
-- `MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE` has been removed, and
-  `MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL` is returned instead if the user's own certificate
-  is too large to fit into the output buffers. Users should check for
-  `MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL` instead, and potentially compare the size of their
-  own certificate against the configured size of the output buffer to understand if
-  the error is due to an overly large certificate.
diff --git a/docs/3.0-migration-guide.d/ssl-ticket-api.md b/docs/3.0-migration-guide.d/ssl-ticket-api.md
deleted file mode 100644
index 23c53d6..0000000
--- a/docs/3.0-migration-guide.d/ssl-ticket-api.md
+++ /dev/null
@@ -1,30 +0,0 @@
-Modified semantics of mbedtls_ssl_{get,set}_session()
------------------------------------------------------------------
-
-This affects users who call `mbedtls_ssl_get_session()` or
-`mbedtls_ssl_set_session()` multiple times on the same SSL context
-representing an established TLS 1.2 connection.
-Those users will now observe the second call to fail with
-`MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE`.
-
-Migration path:
-- Exporting the same TLS 1.2 connection multiple times via
-  `mbedtls_ssl_get_session()` leads to multiple copies of
-  the same session. This use of `mbedtls_ssl_get_session()`
-  is discouraged, and the following should be considered:
-  * If the various session copies are later loaded into
-    fresh SSL contexts via `mbedtls_ssl_set_session()`,
-    export via `mbedtls_ssl_get_session()` only once and
-    load the same session into different contexts via
-    `mbedtls_ssl_set_session()`. Since `mbedtls_ssl_set_session()`
-    makes a copy of the session that's being loaded, this
-    is functionally equivalent.
-  * If the various session copies are later serialized
-    via `mbedtls_ssl_session_save()`, export and serialize
-    the session only once via `mbedtls_ssl_get_session()` and
-    `mbedtls_ssl_session_save()` and make copies of the raw
-    data instead.
-- Calling `mbedtls_ssl_set_session()` multiple times in Mbed TLS 2.x
-  is not useful since subsequent calls overwrite the effect of previous
-  calls. Applications achieve equivalent functional behaviour by
-  issuing only the very last call to `mbedtls_ssl_set_session()`.
diff --git a/docs/3.0-migration-guide.d/turn_SSL_SRV_RESPECT_CLIENT_PREFERENCE_config_opt_to_runtime_opt.md b/docs/3.0-migration-guide.d/turn_SSL_SRV_RESPECT_CLIENT_PREFERENCE_config_opt_to_runtime_opt.md
deleted file mode 100644
index 6a6554d..0000000
--- a/docs/3.0-migration-guide.d/turn_SSL_SRV_RESPECT_CLIENT_PREFERENCE_config_opt_to_runtime_opt.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Turn MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE configuration option into a runtime option
---
-
-This change affects users who were enabling MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
-option in the `config.h`
-
-This option has been removed and a new function with similar functionality has
-been introduced into the SSL API.
-
-This new function `mbedtls_ssl_conf_preference_order()` can be used to
-change the preferred order of ciphersuites on the server to those used on the client,
-e.g.: `mbedtls_ssl_conf_preference_order(ssl_config, MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT)`
-has the same effect as enabling the removed option. The default state is to use
-the server order of suites.
diff --git a/docs/3.0-migration-guide.md b/docs/3.0-migration-guide.md
index 1541c7a..a814c92 100644
--- a/docs/3.0-migration-guide.md
+++ b/docs/3.0-migration-guide.md
@@ -1,5 +1,4 @@
-Migrating from Mbed TLS 2.x to Mbed TLS 3.0
-===========================================
+# Migrating from Mbed TLS 2.x to Mbed TLS 3.0
 
 This guide details the steps required to migrate from Mbed TLS version 2.x to
 Mbed TLS version 3.0 or greater. Unlike normal releases, Mbed TLS 3.0 breaks
@@ -9,8 +8,436 @@
 Here's the list of breaking changes; each entry should help you answer these
 two questions: (1) am I affected? (2) if yes, what's my migration path?
 
-Some function parameters were made const
-----------------------------------------
+The changes are detailed below, and include:
+
+- Removal of many insecure or obsolete features
+- Tidying up of configuration options (including removing some less useful options).
+- Changing function signatures, e.g. adding return codes, adding extra parameters, or making some arguments const.
+- Removal of functions previously marked as deprecated.
+
+
+## General changes
+
+### Introduce a level of indirection and versioning in the config files
+
+`config.h` was split into `build_info.h` and `mbedtls_config.h`.
+
+* In code, use `#include <mbedtls/build_info.h>`. Don't include `mbedtls/config.h` and don't refer to `MBEDTLS_CONFIG_FILE`.
+* In build tools, edit `mbedtls_config.h`, or edit `MBEDTLS_CONFIG_FILE` as before.
+* If you had a tool that parsed the library version from `include/mbedtls/version.h`, this has moved to `include/mbedtls/build_info.h`. From C code, both headers now define the `MBEDTLS_VERSION_xxx` macros.
+
+Also, if you have a custom configuration file:
+
+* Don't include `check_config.h` or `config_psa.h` anymore.
+* Don't define `MBEDTLS_CONFIG_H` anymore.
+
+A config file version symbol, `MBEDTLS_CONFIG_VERSION` was introduced.
+Defining it to a particular value will ensure that Mbed TLS interprets
+the config file in a way that's compatible with the config file format
+used by the Mbed TLS release whose `MBEDTLS_VERSION_NUMBER` has the same
+value.
+The only value supported by Mbed TLS 3.0.0 is `0x03000000`.
+
+### Most structure fields are now private
+
+Direct access to fields of structures (`struct` types) declared in public headers is no longer supported. In Mbed TLS 3, the layout of structures is not considered part of the stable API, and minor versions (3.1, 3.2, etc.) may add, remove, rename, reorder or change the type of structure fields.
+
+There is a small number of exceptions where some fields are guaranteed to remain stable throughout the lifetime of Mbed TLS 3.x. These fields are explicitly documented as public. Please note that even if all the fields of a structure are public, future versions may add new fields. Also, as before, some public fields should be considered read-only, since modifying them may make the structure inconsistent; check the documentation in each case.
+
+Attempting to access a private field directly will result in a compilation error.
+
+If you were accessing structure fields directly, and these fields are not documented as public, you need to change your code. If an accessor (getter/setter) function exists, use that. Direct accessor functions are usually called `mbedtls_<MODULE>_{get,set}_<FIELD>` or `mbedtls_<MODULE>_<STRUCTURE>_{get,set}_<FIELD>`. Accessor functions that change the format may use different verbs, for example `read`/`write` for functions that import/export data from/to a text or byte string.
+
+If no accessor function exists, please open an [enhancement request against Mbed TLS](https://github.com/ARMmbed/mbedtls/issues/new?template=feature_request.md) and describe your use case. The Mbed TLS development team is aware that some useful accessor functions are missing in the 3.0 release, and we expect to add them to the first minor release(s) (3.1, etc.).
+
+As a last resort, you can access the field `foo` of a structure `bar` by writing `bar.MBEDTLS_PRIVATE(foo)`. Note that you do so at your own risk, since such code is likely to break in a future minor version of Mbed TLS.
+
+### Move part of timing module out of the library
+
+The change affects users who use any of the following functions:
+`mbedtls_timing_self_test()`, `mbedtls_hardclock_poll()`,
+`mbedtls_timing_hardclock()` and `mbedtls_set_alarm()`.
+
+If you were relying on these functions, you'll now need to change to using your
+platform's corresponding functions directly.
+
+### Deprecated net.h file was removed
+
+The file `include/mbedtls/net.h` was removed because its only function was to
+include `mbedtls/net_sockets.h` which now should be included directly.
+
+### Remove `MBEDTLS_CHECK_PARAMS` option
+
+This change does not affect users who use the default configuration; it only
+affects users who enabled that option.
+
+The option `MBEDTLS_CHECK_PARAMS` (disabled by default) enabled certain kinds
+of “parameter validation”. It covered two kinds of validations:
+
+- In some functions that require a valid pointer, “parameter validation” checks
+that the pointer is non-null. With the feature disabled, a null pointer is not
+treated differently from any other invalid pointer, and typically leads to a
+runtime crash. 90% of the uses of the feature are of this kind.
+- In some functions that take an enum-like argument, “parameter validation”
+checks that the value is a valid one. With the feature disabled, an invalid
+value causes a silent default to one of the valid values.
+
+The default reaction to a failed check was to call a function
+`mbedtls_param_failed()` which the application had to provide. If this function
+returned, its caller returned an error `MBEDTLS_ERR_xxx_BAD_INPUT_DATA`.
+
+This feature was only used in some classic (non-PSA) cryptography modules. It was
+not used in X.509, TLS or in PSA crypto, and it was not implemented in all
+classic crypto modules.
+
+This feature has been removed. The library no longer checks for NULL pointers;
+checks for enum-like arguments will be kept or re-introduced on a case-by-case
+basis, but their presence will no longer be dependent on a compile-time option.
+
+Validation of enum-like values is somewhat useful, but not extremely important,
+because the parameters concerned are usually constants in applications.
+
+For more information see issue #4313.
+
+### Remove the `MBEDTLS_TEST_NULL_ENTROPY` configuration option
+
+This does not affect users who use the default `mbedtls_config.h`, as this option was
+already off by default.
+
+If you were using the `MBEDTLS_TEST_NULL_ENTROPY` option and your platform
+doesn't have any entropy source, you should use `MBEDTLS_ENTROPY_NV_SEED`
+and make sure your device is provisioned with a strong random seed.
+Alternatively, for testing purposes only, you can create and register a fake
+entropy function.
+
+### Remove the HAVEGE module
+
+This doesn't affect people using the default configuration as it was already
+disabled by default.
+
+This only affects users who called the HAVEGE modules directly (not
+recommended), or users who used it through the entropy module but had it as the
+only source of entropy. If you're in that case, please declare OS or hardware
+RNG interfaces with `mbedtls_entropy_add_source()` and/or use an entropy seed
+file created securely during device provisioning. See
+<https://tls.mbed.org/kb/how-to/add-entropy-sources-to-entropy-pool> for more
+information.
+
+### Remove helpers for the transition from Mbed TLS 1.3 to Mbed TLS 2.0
+
+This only affects people who've been using Mbed TLS since before version 2.0
+and still relied on `compat-1.3.h` in their code.
+
+Please use the new names directly in your code; `scripts/rename.pl` (from any
+of the 2.x releases — no longer included in 3.0) might help you do that.
+
+
+## Low-level crypto
+
+Please also refer to the section [High-level crypto](#high-level-crypto) for
+changes that could sit in either category.
+
+### Deprecated functions were removed from bignum
+
+The function `mbedtls_mpi_is_prime()` was removed. Please use
+`mbedtls_mpi_is_prime_ext()` instead which additionally allows specifying the
+number of Miller-Rabin rounds.
+
+### Deprecated functions were removed from DRBGs
+
+The functions `mbedtls_ctr_drbg_update_ret()` and `mbedtls_hmac_drbg_update_ret()`
+were renamed to replace the corresponding functions without `_ret` appended. Please call
+the name without `_ret` appended and check the return value.
+
+### Deprecated hex-encoded primes were removed from DHM
+
+The macros `MBEDTLS_DHM_RFC5114_MODP_2048_P`, `MBEDTLS_DHM_RFC5114_MODP_2048_G`,
+`MBEDTLS_DHM_RFC3526_MODP_2048_P`, `MBEDTLS_DHM_RFC3526_MODP_2048_G`,
+`MBEDTLS_DHM_RFC3526_MODP_3072_P`, `MBEDTLS_DHM_RFC3526_MODP_3072_G`,
+`MBEDTLS_DHM_RFC3526_MODP_4096_P `and `MBEDTLS_DHM_RFC3526_MODP_4096_G` were
+removed. The primes from RFC 5114 are deprecated because their derivation is not
+documented and therefore their usage constitutes a security risk; they are fully
+removed from the library. Please use parameters from RFC3526 (still in the
+library, only in binary form) or RFC 7919 (also available in the library) or
+other trusted sources instead.
+
+### Deprecated functions were removed from hashing modules
+
+Modules: MD5, SHA1, SHA256, SHA512, MD.
+
+- The functions `mbedtls_xxx_starts_ret()`, `mbedtls_xxx_update_ret()`,
+  `mbedtls_xxx_finish_ret()` and `mbedtls_xxx_ret()` were renamed to replace
+  the corresponding functions without `_ret` appended. Please call the name without `_ret` appended and check the return value.
+- The function `mbedtls_md_init_ctx()` was removed; please use
+  `mbedtls_md_setup()` instead.
+- The functions `mbedtls_xxx_process()` were removed. You normally don't need
+  to call that from application code. However if you do (or if you want to
+  provide your own version of that function), please use
+  `mbedtls_internal_xxx_process()` instead, and check the return value.
+
+### Change `MBEDTLS_ECP_FIXED_POINT_OPTIM` behavior
+
+The option `MBEDTLS_ECP_FIXED_POINT_OPTIM` now increases code size and it does
+not increase peak RAM usage anymore.
+
+If you are limited by code size, you can define `MBEDTLS_ECP_FIXED_POINT_OPTIM`
+to `0` in your config file. The impact depends on the number and size of
+enabled curves. For example, for P-256 the difference is 1KB; see the documentation
+of this option for details.
+
+### Separated `MBEDTLS_SHA224_C` and `MBEDTLS_SHA256_C`
+
+This does not affect users who use the default `mbedtls_config.h`. `MBEDTLS_SHA256_C`
+was enabled by default. Now both `MBEDTLS_SHA256_C` and `MBEDTLS_SHA224_C` are
+enabled.
+
+If you were using custom config file with `MBEDTLS_SHA256_C` enabled, then
+you will need to add `#define MBEDTLS_SHA224_C` option to your config.
+Current version of the library does not support enabling `MBEDTLS_SHA256_C`
+without `MBEDTLS_SHA224_C`.
+
+### Replaced `MBEDTLS_SHA512_NO_SHA384` with `MBEDTLS_SHA384_C`
+
+This does not affect users who use the default `mbedtls_config.h`.
+`MBEDTLS_SHA512_NO_SHA384` was disabled by default, now `MBEDTLS_SHA384_C` is
+enabled by default.
+
+If you were using a config file with both `MBEDTLS_SHA512_C` and
+MBEDTLS_SHA512_NO_SHA384, then just remove the `MBEDTLS_SHA512_NO_SHA384`.
+If you were using a config file with `MBEDTLS_SHA512_C` and without
+`MBEDTLS_SHA512_NO_SHA384` and you need the SHA-384 algorithm, then add
+`#define MBEDTLS_SHA384_C` to your config file.
+
+### GCM multipart interface: application changes
+
+The GCM module now supports arbitrary chunked input in the multipart interface.
+This changes the interface for applications using the GCM module directly for multipart operations.
+Applications using one-shot GCM or using GCM via the `mbedtls_cipher_xxx` or `psa_aead_xxx` interfaces do not require any changes.
+
+* `mbedtls_gcm_starts()` now only sets the mode and the nonce (IV). Call the new function `mbedtls_gcm_update_ad()` to pass the associated data.
+* `mbedtls_gcm_update()` now takes an extra parameter to indicate the actual output length. In Mbed TLS 2.x, applications had to pass inputs consisting of whole 16-byte blocks except for the last block (this limitation has been lifted). In this case:
+    * As long as the input remains block-aligned, the output length is exactly the input length, as before.
+    * If the length of the last input is not a multiple of 16, alternative implementations may return the last partial block in the call to `mbedtls_gcm_finish()` instead of returning it in the last call to `mbedtls_gcm_update()`.
+* `mbedtls_gcm_finish()` now takes an extra output buffer for the last partial block. This is needed for alternative implementations that can only process a whole block at a time.
+
+### GCM interface changes: impact for alternative implementations
+
+The GCM multipart interface has changed as described in [“GCM multipart interface: application changes”](#gcm-multipart-interface-application-changes). The consequences for an alternative implementation of GCM (`MBEDTLS_GCM_ALT`) are as follows:
+
+* `mbedtls_gcm_starts()` now only sets the mode and the nonce (IV). The new function `mbedtls_gcm_update_ad()` receives the associated data. It may be called multiple times.
+* `mbedtls_gcm_update()` now allows arbitrary-length inputs, takes an extra parameter to indicate the actual output length. Alternative implementations may choose between two modes:
+    * Always return the partial output immediately, even if it does not consist of a whole number of blocks.
+    * Buffer the data for the last partial block, to be returned in the next call to `mbedtls_gcm_update()` or `mbedtls_gcm_finish()`.
+* `mbedtls_gcm_finish()` now takes an extra output buffer for the last partial block if needed.
+
+### The configuration option `MBEDTLS_ECP_NO_INTERNAL_RNG` was removed
+
+This doesn't affect users of the default configuration; it only affects people
+who were explicitly setting this option.
+
+This was a trade-off between code size and countermeasures; it is no longer
+relevant as the countermeasure is now always on at no cost in code size.
+
+### SHA-512 and SHA-256 output type change
+
+The output parameter of `mbedtls_sha256_finish_ret()`, `mbedtls_sha256_ret()`, `mbedtls_sha512_finish_ret()`, `mbedtls_sha512_ret()` now has a pointer type rather than array type. This makes no difference in terms of C semantics, but removes spurious warnings in some compilers when outputting a SHA-384 hash into a 48-byte buffer or a SHA-224 hash into a 28-byte buffer.
+
+This makes no difference to a vast majority of applications. If your code takes a pointer to one of these functions, you may need to change the type of the pointer.
+
+Alternative implementations of the SHA256 and SHA512 modules must adjust their functions' prototype accordingly.
+
+### Deprecated error codes for hardware failures were removed
+
+- The macros `MBEDTLS_ERR_xxx_FEATURE_UNSUPPORTED` from various crypto modules
+  were removed; `MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED` is now used
+  instead.
+- The macros `MBEDTLS_ERR_xxx_HW_ACCEL_FAILED` from various crypto modules
+  were removed; `MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED` is now used instead.
+
+### Remove the mode parameter from RSA functions
+
+This affects all users who use the RSA encryption, decryption, sign and
+verify APIs.
+
+The RSA module no longer supports private-key operations with the public key or
+vice versa. As a consequence, RSA operation functions no longer have a mode
+parameter. If you were calling RSA operations with the normal mode (public key
+for verification or encryption, private key for signature or decryption), remove
+the `MBEDTLS_MODE_PUBLIC` or `MBEDTLS_MODE_PRIVATE` argument. If you were calling
+RSA operations with the wrong mode, which rarely makes sense from a security
+perspective, this is no longer supported.
+
+### Deprecated functions were removed from AES
+
+The functions `mbedtls_aes_encrypt()` and `mbedtls_aes_decrypt()` were
+removed.
+
+If you're simply using the AES module, you should be calling the higher-level
+functions `mbedtls_aes_crypt_xxx()`.
+
+If you're providing an alternative implementation using
+`MBEDTLS_AES_ENCRYPT_ALT` or `MBEDTLS_AES_DECRYPT_ALT`, you should be
+replacing the removed functions with `mbedtls_internal_aes_encrypt()` and
+`mbedtls_internal_aes_decrypt()` respectively.
+
+### Deprecated functions were removed from ECDSA
+
+The functions `mbedtls_ecdsa_write_signature_det()` and
+`mbedtls_ecdsa_sign_det()` were removed. They were superseded by
+`mbedtls_ecdsa_write_signature()` and `mbedtls_ecdsa_sign_det_ext()`
+respectively.
+
+### Rename `mbedtls_*_ret()` cryptography functions whose deprecated variants have been removed
+
+This change affects users who were using the `mbedtls_*_ret()` cryptography
+functions.
+
+Those functions were created based on now-deprecated functions according to a
+requirement that a function needs to return a value. This change brings back the
+original names of those functions. The renamed functions are:
+
+| name before this change        | after the change           |
+|--------------------------------|----------------------------|
+| `mbedtls_ctr_drbg_update_ret`  | `mbedtls_ctr_drbg_update`  |
+| `mbedtls_hmac_drbg_update_ret` | `mbedtls_hmac_drbg_update` |
+| `mbedtls_md5_starts_ret`       | `mbedtls_md5_starts`       |
+| `mbedtls_md5_update_ret`       | `mbedtls_md5_update`       |
+| `mbedtls_md5_finish_ret`       | `mbedtls_md5_finish`       |
+| `mbedtls_md5_ret`              | `mbedtls_md5`              |
+| `mbedtls_ripemd160_starts_ret` | `mbedtls_ripemd160_starts` |
+| `mbedtls_ripemd160_update_ret` | `mbedtls_ripemd160_update` |
+| `mbedtls_ripemd160_finish_ret` | `mbedtls_ripemd160_finish` |
+| `mbedtls_ripemd160_ret`        | `mbedtls_ripemd160`        |
+| `mbedtls_sha1_starts_ret`      | `mbedtls_sha1_starts`      |
+| `mbedtls_sha1_update_ret`      | `mbedtls_sha1_update`      |
+| `mbedtls_sha1_finish_ret`      | `mbedtls_sha1_finish`      |
+| `mbedtls_sha1_ret`             | `mbedtls_sha1`             |
+| `mbedtls_sha256_starts_ret`    | `mbedtls_sha256_starts`    |
+| `mbedtls_sha256_update_ret`    | `mbedtls_sha256_update`    |
+| `mbedtls_sha256_finish_ret`    | `mbedtls_sha256_finish`    |
+| `mbedtls_sha256_ret`           | `mbedtls_sha256`           |
+| `mbedtls_sha512_starts_ret`    | `mbedtls_sha512_starts`    |
+| `mbedtls_sha512_update_ret`    | `mbedtls_sha512_update`    |
+| `mbedtls_sha512_finish_ret`    | `mbedtls_sha512_finish`    |
+| `mbedtls_sha512_ret`           | `mbedtls_sha512`           |
+
+To migrate to the this change the user can keep the `*_ret` names in their code
+and include the `compat_2.x.h` header file which holds macros with proper
+renaming or to rename those functions in their code according to the list from
+mentioned header file.
+
+### Remove the RNG parameter from RSA verify functions
+
+RSA verification functions also no longer take random generator arguments (this
+was only needed when using a private key). This affects all applications using
+the RSA verify functions.
+
+### Remove the padding parameters from `mbedtls_rsa_init()`
+
+This affects all users who use the RSA encryption, decryption, sign and
+verify APIs.
+
+The function `mbedtls_rsa_init()` no longer supports selecting the PKCS#1 v2.1
+encoding and its hash. It just selects the PKCS#1 v1.5 encoding by default. If
+you were using the PKCS#1 v2.1 encoding you now need, subsequently to the call
+to `mbedtls_rsa_init()`, to call `mbedtls_rsa_set_padding()` to set it.
+
+To choose the padding type when initializing a context, instead of
+
+```C
+    mbedtls_rsa_init(ctx, padding, hash_id);
+```
+
+use
+
+```C
+    mbedtls_rsa_init(ctx);
+    mbedtls_rsa_set_padding(ctx, padding, hash_id);
+```
+
+To use PKCS#1 v1.5 padding, instead of
+
+```C
+    mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, <ignored>);
+```
+
+just use
+
+```C
+    mbedtls_rsa_init(ctx);
+```
+
+
+## High-level crypto
+
+Please also refer to the section [Low-level crypto](#low-level-crypto) for
+changes that could sit in either category.
+
+### Calling `mbedtls_cipher_finish()` is mandatory for all multi-part operations
+
+This only affects people who use the cipher module to perform AEAD operations
+using the multi-part API.
+
+Previously, the documentation didn't state explicitly if it was OK to call
+`mbedtls_cipher_check_tag()` or `mbedtls_cipher_write_tag()` directly after
+the last call to `mbedtls_cipher_update()` — that is, without calling
+`mbedtls_cipher_finish()` in-between. If you code was missing that call,
+please add it and be prepared to get as much as 15 bytes of output.
+
+Currently the output is always 0 bytes, but it may be more when alternative
+implementations of the underlying primitives are in use, or with future
+versions of the library.
+
+### Remove MD2, MD4, RC4, Blowfish and XTEA algorithms
+
+This change affects users of the MD2, MD4, RC4, Blowfish and XTEA algorithms.
+
+They are already niche or obsolete and most of them are weak or broken. For
+those reasons possible users should consider switching to modern and safe
+alternatives to be found in literature.
+
+### Deprecated functions were removed from cipher
+
+The functions `mbedtls_cipher_auth_encrypt()` and
+`mbedtls_cipher_auth_decrypt()` were removed. They were superseded by
+`mbedtls_cipher_auth_encrypt_ext()` and `mbedtls_cipher_auth_decrypt_ext()`
+respectively which additionally support key wrapping algorithms such as
+NIST_KW.
+
+### Extra parameter for the output buffer size
+
+The following functions now take an extra parameter indicating the size of the output buffer:
+
+* `mbedtls_ecdsa_write_signature()`, `mbedtls_ecdsa_write_signature_restartable()`
+* `mbedtls_pk_sign()`, `mbedtls_pk_sign_restartable()`
+
+The requirements for the output buffer have not changed, but passing a buffer that is too small now reliably causes the functions to return an error, rather than overflowing the buffer.
+
+### Signature functions now require the hash length to match the expected value
+
+This affects users of the PK API as well as users of the low-level API in the RSA module. Users of the PSA API or of the ECDSA module are unaffected.
+
+All the functions in the RSA module that accept a `hashlen` parameter used to
+ignore it unless the `md_alg` parameter was `MBEDTLS_MD_NONE`, indicating raw
+data was signed. The `hashlen` parameter is now always the size that is read
+from the `hash` input buffer. This length must be equal to the output size of
+the hash algorithm used when signing a hash. (The requirements when signing
+raw data are unchanged.) This affects the following functions:
+
+* `mbedtls_rsa_pkcs1_sign`, `mbedtls_rsa_pkcs1_verify`
+* `mbedtls_rsa_rsassa_pkcs1_v15_sign`, `mbedtls_rsa_rsassa_pkcs1_v15_verify`
+* `mbedtls_rsa_rsassa_pss_sign`, `mbedtls_rsa_rsassa_pss_verify`
+* `mbedtls_rsa_rsassa_pss_sign_ext`, `mbedtls_rsa_rsassa_pss_verify_ext`
+
+The signature functions in the PK module no longer accept 0 as the `hash_len` parameter. The `hash_len` parameter is now always the size that is read from the `hash` input buffer. This affects the following functions:
+
+* `mbedtls_pk_sign`, `mbedtls_pk_verify`
+* `mbedtls_pk_sign_restartable`, `mbedtls_pk_verify_restartable`
+* `mbedtls_pk_verify_ext`
+
+The migration path is to pass the correct value to those functions.
+
+### Some function parameters were made const
 
 Various functions in the PK and ASN.1 modules had a `const` qualifier added to
 some of their parameters.
@@ -19,39 +446,49 @@
 those functions. In this case, you'll need to update the type of your pointers
 in order to match the new signature.
 
-Deprecated functions were removed from hashing modules
-------------------------------------------------------
+### The RNG parameter is now mandatory for all functions that accept one
 
-Modules: MD5, SHA1, SHA256, SHA512, MD.
+This change affects all users who called a function accepting a `f_rng`
+parameter with `NULL` as the value of this argument; this is no longer
+supported.
 
-- The functions `mbedtls_xxx_starts()`, `mbedtls_xxx_update()`,
-  `mbedtls_xxx_finish()` and `mbedtls_xxx()` were removed. Please use the
-function with the same name with `_ret` appended and check the return value.
-- The function `mbedtls_md_init_ctx()` was removed; please use
-  `mbedtls_md_setup()` instead.
-- The functions `mbedtls_xxx_process()` were removed. You normally don't need
-  to call that from application code. However if you do (or if you want to
-provide your own version of that function), please use
-`mbedtls_internal_xxx_process()` instead, and check the return value.
+The changed functions are: the X.509 CRT and CSR writing functions; the PK and
+RSA sign and decrypt functions; `mbedtls_rsa_private()`; the functions in DHM
+and ECDH that compute the shared secret; the scalar multiplication functions in
+ECP.
 
-Deprecated error codes for hardware failures were removed
----------------------------------------------------------
+You now need to pass a properly seeded, cryptographically secure RNG to all
+functions that accept a `f_rng` parameter. It is of course still possible to
+pass `NULL` as the context pointer `p_rng` if your RNG function doesn't need a
+context.
 
-- The macros `MBEDTLS_ERR_xxx_FEATURE_UNSUPPORTED` from various crypto modules
-  were removed; `MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED` is now used
-instead.
-- The macros `MBEDTLS_ERR_xxx_HW_ACCEL_FAILED` from various crypto modules
-  were removed; `MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED` is now used instead.
+Alternative implementations of a module (enabled with the `MBEDTLS_module_ALT`
+configuration options) may have their own internal and are free to ignore the
+`f_rng` argument but must allow users to pass one anyway.
 
-Deprecated names for PSA constants and types were removed
----------------------------------------------------------
+### Some functions gained an RNG parameter
+
+This affects users of the following functions: `mbedtls_ecp_check_pub_priv()`,
+`mbedtls_pk_check_pair()`, `mbedtls_pk_parse_key()`, and
+`mbedtls_pk_parse_keyfile()`.
+
+You now need to pass a properly seeded, cryptographically secure RNG when
+calling these functions. It is used for blinding, a countermeasure against
+side-channel attacks.
+
+
+## PSA
+
+### Deprecated names for PSA constants and types were removed
 
 Some constants and types that were present in beta versions of the PSA Crypto
 API were removed from version 1.0 of specification. Please switch to the new
 names provided by the 1.0 specification instead.
 
-Internal / alt-focused headers were moved to a private location
-----------------------------------------------------------------
+
+## Changes that only affect alternative implementations
+
+### Internal / alt-focused headers were moved to a private location
 
 This shouldn't affect users who took care not to include headers that
 were documented as internal, despite being in the public include directory.
@@ -65,8 +502,19 @@
 function that's now in a private header, please reach out on the mailing list
 and explain your need; we'll consider adding a new API in a future version.
 
-Remove the certs module from the library
-----------------------------------------
+### CCM interface changes: impact for alternative implementations
+
+The CCM interface has changed with the addition of support for
+multi-part operations. Five new API functions have been defined:
+ `mbedtls_ccm_starts()`, `mbedtls_ccm_set_lengths()`,
+ `mbedtls_ccm_update_ad()`, `mbedtls_ccm_update()` and `mbedtls_ccm_finish()`.
+Alternative implementations of CCM (`MBEDTLS_CCM_ALT`) have now to
+implement those additional five API functions.
+
+
+## X.509
+
+### Remove the certs module from the library
 
 This should not affect production use of the library, as the certificates and
 keys included there were never suitable for production use.
@@ -76,33 +524,108 @@
 `certs.c` is out of the library there is no longer any stability guaranteed
 and it may change in incompatible ways at any time.
 
-Remove the HAVEGE module
-------------------------
+### Change the API to allow adding critical extensions to CSRs
+
+This affects applications that call the `mbedtls_x509write_csr_set_extension`
+function.
+
+The API is changed to include the parameter `critical` which enables marking an
+extension included in a CSR as critical. To get the previous behavior pass 0.
+
+### Remove the config option `MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION`
+
+This change does not affect users of the default configuration; it only affects
+users who enable this option.
+
+The X.509 standard says that implementations must reject critical extensions that
+they don't recognize, and this is what Mbed TLS does by default. This option
+allowed to continue parsing those certificates but didn't provide a convenient
+way to handle those extensions.
+
+The migration path from that option is to use the
+`mbedtls_x509_crt_parse_der_with_ext_cb()` function which is functionally
+equivalent to `mbedtls_x509_crt_parse_der()`, and/or
+`mbedtls_x509_crt_parse_der_nocopy()` but it calls the callback with every
+unsupported certificate extension and additionally the "certificate policies"
+extension if it contains any unsupported certificate policies.
+
+### Remove `MBEDTLS_X509_CHECK_*_KEY_USAGE` options from `mbedtls_config.h`
+
+This change affects users who have chosen the configuration options to disable the
+library's verification of the `keyUsage` and `extendedKeyUsage` fields of x509
+certificates.
+
+The `MBEDTLS_X509_CHECK_KEY_USAGE` and `MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE`
+configuration options are removed and the X509 code now behaves as if they were
+always enabled. It is consequently not possible anymore to disable at compile
+time the verification of the `keyUsage` and `extendedKeyUsage` fields of X509
+certificates.
+
+The verification of the `keyUsage` and `extendedKeyUsage` fields is important,
+disabling it can cause security issues and it is thus not recommended. If the
+verification is for some reason undesirable, it can still be disabled by means
+of the verification callback function passed to `mbedtls_x509_crt_verify()` (see
+the documentation of this function for more information).
+
+### Remove the `MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3` option
+
+This change does not affect users who were using the default configuration, as
+this option was already disabled by default. Also, it does not affect users who
+are working with current V3 X.509 certificates.
+
+Extensions were added in V3 of the X.509 specification, so pre-V3 certificates
+containing extensions were never compliant. Mbed TLS now rejects them with a
+parsing error in all configurations, as it did previously in the default
+configuration.
+
+If you are working with the pre-V3 certificates you need to switch to the
+current ones.
+
+### Strengthen default algorithm selection for X.509
+
+This is described in the section [Strengthen default algorithm selection for X.509 and TLS](#strengthen-default-algorithm-selection-for-x.509-and-tls).
+
+### Remove wrapper for libpkcs11-helper
 
 This doesn't affect people using the default configuration as it was already
 disabled by default.
 
-This only affects users who called the HAVEGE modules directly (not
-recommended), or users who used it through the entropy module but had it as the
-only source of entropy. If you're in that case, please declare OS or hardware
-RNG interfaces with `mbedtls_entropy_add_source()` and/or use an entropy seed
-file created securely during device provisioning. See
-<https://tls.mbed.org/kb/how-to/add-entropy-sources-to-entropy-pool> for more
-information.
+If you used to rely on this module in order to store your private keys
+securely, please have a look at the key management facilities provided by the
+PSA crypto API. If you have a use case that's not covered yet by this API,
+please reach out on the mailing list.
 
-Remove support for parsing SSLv2 ClientHello
---------------------------------------------
 
-This doesn't affect people using the default configuration as it was already
-disabled by default.
+## SSL
 
-This only affects TLS servers that have clients who send an SSLv2 ClientHello.
-These days clients are very unlikely to do that. If you have a client that
-does, please try contacting them and encouraging them to upgrade their
-software.
+### Remove support for TLS 1.0, 1.1 and DTLS 1.0
 
-Remove support for SSL 3.0
---------------------------
+This change affects users of the TLS 1.0, 1.1 and DTLS 1.0 protocols.
+
+These versions have been deprecated by RFC 8996.
+Keeping them in the library creates opportunities for misconfiguration
+and possibly downgrade attacks. More generally, more code means a larger attack
+surface, even if the code is supposedly not used.
+
+The migration path is to adopt the latest versions of the protocol.
+
+As a consequence of removing TLS 1.0, support for CBC record splitting was
+also removed, as it was a work-around for a weakness in this particular
+version. There is no migration path since the feature is no longer relevant.
+
+As a consequence of currently supporting only one version of (D)TLS (and in the
+future 1.3 which will have a different version negotiation mechanism), support
+for fallback SCSV (RFC 7507) was also removed. There is no migration path as
+it's no longer useful with TLS 1.2 and later.
+
+As a consequence of currently supporting only one version of (D)TLS (and in the
+future 1.3 which will have a different concept of ciphersuites), support for
+configuring ciphersuites separately for each version via
+`mbedtls_ssl_conf_ciphersuites_for_version()` was removed. Use
+`mbedtls_ssl_conf_ciphersuites()` to configure ciphersuites to use with (D)TLS
+1.2; in the future a different API will be added for (D)TLS 1.3.
+
+### Remove support for SSL 3.0
 
 This doesn't affect people using the default configuration as it was already
 disabled by default.
@@ -112,8 +635,17 @@
 to date. If one of your peers is in that case, please try contacting them and
 encouraging them to upgrade their software.
 
-Remove support for truncated HMAC
----------------------------------
+### Remove support for parsing SSLv2 ClientHello
+
+This doesn't affect people using the default configuration as it was already
+disabled by default.
+
+This only affects TLS servers that have clients who send an SSLv2 ClientHello.
+These days clients are very unlikely to do that. If you have a client that
+does, please try contacting them and encouraging them to upgrade their
+software.
+
+### Remove support for truncated HMAC
 
 This affects users of truncated HMAC, that is, users who called
 `mbedtls_ssl_conf_truncated_hmac( ..., MBEDTLS_SSL_TRUNC_HMAC_ENABLED)`,
@@ -123,8 +655,7 @@
 The recommended migration path for people who want minimal overhead is to use a
 CCM-8 ciphersuite.
 
-Remove support for TLS record-level compression
------------------------------------------------
+### Remove support for TLS record-level compression
 
 This doesn't affect people using the default configuration as it was already
 disabled by default.
@@ -136,10 +667,9 @@
 own compression mechanisms and are in a better position than the TLS stack to
 avoid variants of the CRIME and BREACH attacks.
 
-Remove support for TLS RC4-based ciphersuites
----------------------------------------------
+### Remove support for TLS RC4-based ciphersuites
 
-This does not affect people who used the default `config.h` and the default
+This does not affect people who used the default `mbedtls_config.h` and the default
 list of ciphersuites, as RC4-based ciphersuites were already not negotiated in
 that case.
 
@@ -147,8 +677,7 @@
 AES-GCM, AES-CCM or ChachaPoly for example) and if your peer doesn't support
 any, encourage them to upgrade their software.
 
-Remove support for TLS single-DES ciphersuites
-----------------------------------------------
+### Remove support for TLS single-DES ciphersuites
 
 This doesn't affect people using the default configuration as it was already
 disabled by default.
@@ -157,8 +686,7 @@
 AES-GCM, AES-CCM or ChachaPoly for example) and if your peer doesn't support
 any, encourage them to upgrade their software.
 
-Remove support for TLS record-level hardware acceleration
----------------------------------------------------------
+### Remove support for TLS record-level hardware acceleration
 
 This doesn't affect people using the default configuration as it was already
 disabled by default.
@@ -167,30 +695,317 @@
 However if you did, please reach out on the mailing list and let us know about
 your use case.
 
-Remove wrapper for libpkcs11-helper
------------------------------------
-
-This doesn't affect people using the default configuration as it was already
-disabled by default.
-
-If you used to rely on this module in order to store your private keys
-securely, please have a look at the key management facilities provided by the
-PSA crypto API. If you have a use case that's not covered yet by this API,
-please reach out on the mailing list.
-
-Remove config option `MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME`
-----------------------------------------------------------
+### Remove config option `MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME`
 
 This doesn't affect people using the default configuration.
 
 This option has not had any effect for a long time. Please use the `lifetime`
 parameter of `mbedtls_ssl_ticket_setup()` instead.
 
-Remove helpers for the transition from Mbed TLS 1.3 to Mbed TLS 2.0
--------------------------------------------------------------------
+### Combine the `MBEDTLS_SSL_CID_PADDING_GRANULARITY` and `MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY` options
 
-This only affects people who've been using Mbed TLS since before version 2.0
-and still relied on `compat-1.3.h` in their code.
+This change affects users who modified the default `mbedtls_config.h` padding granularity
+settings, i.e. enabled at least one of the options.
 
-Please use the new names directly in your code; `scripts/rename.pl` (from any
-of the 2.x releases - no longer included in 3.0) might help you do that.
+The `mbedtls_config.h` options `MBEDTLS_SSL_CID_PADDING_GRANULARITY` and
+`MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY` were combined into one option because
+they used exactly the same padding mechanism and hence their respective padding
+granularities can be used in exactly the same way. This change simplifies the
+code maintenance.
+
+The new single option `MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY` can be used
+for both DTLS-CID and TLS 1.3.
+
+### TLS now favors faster curves over larger curves
+
+The default preference order for curves in TLS now favors resource usage (performance and memory consumption) over size. The exact order is unspecified and may change, but generally you can expect 256-bit curves to be preferred over larger curves.
+
+If you prefer a different order, call `mbedtls_ssl_conf_curves()` when configuring a TLS connection.
+
+### SSL key export interface change
+
+This affects users of the SSL key export APIs:
+```
+    mbedtls_ssl_conf_export_keys_cb()
+    mbedtls_ssl_conf_export_keys_ext_cb()
+```
+
+Those APIs have been removed and replaced by the new API
+`mbedtls_ssl_set_export_keys_cb()`. This API differs from
+the previous key export API in the following ways:
+
+- It is no longer bound to an SSL configuration, but to an
+  SSL context. This allows users to more easily identify the
+  connection an exported key belongs to.
+- It no longer exports raw keys and IV.
+- A secret type parameter has been added to identify which key
+  is being exported. For TLS 1.2, only the master secret is
+  exported, but upcoming TLS 1.3 support will add other kinds of keys.
+- The callback now specifies a void return type, rather than
+  returning an error code. It is the responsibility of the application
+  to handle failures in the key export callback, for example by
+  shutting down the TLS connection.
+
+For users which do not rely on raw keys and IV, adjusting to the new
+callback type should be straightforward — see the example programs
+`programs/ssl/ssl_client2` and `programs/ssl/ssl_server2` for callbacks
+for NSSKeylog, EAP-TLS and DTLS-SRTP.
+
+Users which require access to the raw keys used to secure application
+traffic may derive those by hand based on the master secret and the
+handshake transcript hashes which can be obtained from the raw data
+on the wire. Such users are also encouraged to reach out to the
+Mbed TLS team on the mailing list, to let the team know about their
+use case.
+
+### Remove MaximumFragmentLength (MFL) query API
+
+This affects users which use the MFL query APIs
+`mbedtls_ssl_get_{input,output}_max_frag_len()` to
+infer upper bounds on the plaintext size of incoming and
+outgoing record.
+
+Users should switch to `mbedtls_ssl_get_max_{in,out}_record_payload()`
+instead, which also provides such upper bounds but takes more factors
+than just the MFL configuration into account.
+
+### Relaxed semantics for PSK configuration
+
+This affects users which call the PSK configuration APIs
+`mbedtlsl_ssl_conf_psk()` and `mbedtls_ssl_conf_psk_opaque()`
+multiple times on the same SSL configuration.
+
+In Mbed TLS 2.x, users would observe later calls overwriting
+the effect of earlier calls, with the prevailing PSK being
+the one that has been configured last. In Mbed TLS 3.0,
+calling `mbedtls_ssl_conf_[opaque_]psk()` multiple times
+will return an error, leaving the first PSK intact.
+
+To achieve equivalent functionality when migrating to Mbed TLS 3.0,
+users calling `mbedtls_ssl_conf_[opaque_]psk()` multiple times should
+remove all but the last call, so that only one call to _either_
+`mbedtls_ssl_conf_psk()` _or_ `mbedtls_ssl_conf_psk_opaque()`
+remains.
+
+### Remove the configuration to enable weak ciphersuites in SSL / TLS
+
+This does not affect users who use the default `mbedtls_config.h`, as this option was
+already off by default.
+
+If you were using a weak cipher, please switch to any of the modern,
+recommended ciphersuites (based on AES-GCM, AES-CCM or ChachaPoly for example)
+and if your peer doesn't support any, encourage them to upgrade their software.
+
+If you were using a ciphersuite without encryption, you just have to
+enable `MBEDTLS_CIPHER_NULL_CIPHER` now.
+
+### Remove the `MBEDTLS_SSL_MAX_CONTENT_LEN` configuration option
+
+This affects users who use the `MBEDTLS_SSL_MAX_CONTENT_LEN` option to
+set the maximum length of incoming and outgoing plaintext fragments,
+which can save memory by reducing the size of the TLS I/O buffers.
+
+This option is replaced by the more fine-grained options
+`MBEDTLS_SSL_IN_CONTENT_LEN` and `MBEDTLS_SSL_OUT_CONTENT_LEN` that set
+the maximum incoming and outgoing plaintext fragment lengths, respectively.
+
+### Remove the SSL API `mbedtls_ssl_get_session_pointer()`
+
+This affects two classes of users:
+
+1. Users who manually inspect parts of the current session through
+   direct structure field access.
+
+2. Users of session resumption who query the current session
+   via `mbedtls_ssl_get_session_pointer()` prior to saving or exporting
+   it via `mbedtls_ssl_session_copy()` or `mbedtls_ssl_session_save()`,
+   respectively.
+
+Migration paths:
+
+1. Mbed TLS 3.0 does not offer a migration path for the use case 1: Like many
+   other Mbed TLS structures, the structure of `mbedtls_ssl_session` is no
+   longer part of the public API in Mbed TLS 3.0, and direct structure field
+   access is no longer supported. Please see the [section on private structure fields](#most-structure-fields-are-now-private) for more details.
+
+2. Users should replace calls to `mbedtls_ssl_get_session_pointer()` by
+   calls to `mbedtls_ssl_get_session()` as demonstrated in the example
+   program `programs/ssl/ssl_client2.c`.
+
+### Remove `MBEDTLS_SSL_DTLS_BADMAC_LIMIT` option
+
+This change does not affect users who used the default `mbedtls_config.h`, as the option
+`MBEDTLS_SSL_DTLS_BADMAC_LIMIT` was already on by default.
+
+This option was a trade-off between functionality and code size: it allowed
+users who didn't need that feature to avoid paying the cost in code size, by
+disabling it.
+
+This option is no longer present, but its functionality is now always enabled.
+
+### Deprecated functions were removed from SSL
+
+The function `mbedtls_ssl_conf_dh_param()` was removed. Please use
+`mbedtls_ssl_conf_dh_param_bin()` or `mbedtls_ssl_conf_dh_param_ctx()` instead.
+
+The function `mbedtls_ssl_get_max_frag_len()` was removed. Please use
+`mbedtls_ssl_get_max_out_record_payload()` and
+`mbedtls_ssl_get_max_in_record_payload()`
+instead.
+
+### Remove `MBEDTLS_SSL_RECORD_CHECKING` option and enable its action by default
+
+This change does not affect users who use the default `mbedtls_config.h`, as the
+option `MBEDTLS_SSL_RECORD_CHECKING` was already on by default.
+
+This option was added only to control compilation of one function,
+ `mbedtls_ssl_check_record()`, which is only useful in some specific cases, so it
+was made optional to allow users who don't need it to save some code space.
+However, the same effect can be achieved by using link-time garbage collection.
+
+Users who changed the default setting of the option need to change the config/
+build system to remove that change.
+
+### Session Cache API Change
+
+This affects users who use `mbedtls_ssl_conf_session_cache()`
+to configure a custom session cache implementation different
+from the one Mbed TLS implements in `library/ssl_cache.c`.
+
+Those users will need to modify the API of their session cache
+implementation to that of a key-value store with keys being
+session IDs and values being instances of `mbedtls_ssl_session`:
+
+```C
+typedef int mbedtls_ssl_cache_get_t( void *data,
+                                     unsigned char const *session_id,
+                                     size_t session_id_len,
+                                     mbedtls_ssl_session *session );
+typedef int mbedtls_ssl_cache_set_t( void *data,
+                                     unsigned char const *session_id,
+                                     size_t session_id_len,
+                                     const mbedtls_ssl_session *session );
+```
+
+Since the structure of `mbedtls_ssl_session` is no longer public from 3.0
+onwards, portable session cache implementations must not access fields of
+`mbedtls_ssl_session`. See the corresponding migration guide. Users that
+find themselves unable to migrate their session cache functionality without
+accessing fields of `mbedtls_ssl_session` should describe their use case
+on the Mbed TLS mailing list.
+
+### Changes in the SSL error code space
+
+This affects users manually checking for the following error codes:
+
+- `MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED`
+- `MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH`
+- `MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE`
+- `MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN`
+- `MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE`
+- `MBEDTLS_ERR_SSL_BAD_HS_XXX`
+
+Migration paths:
+- `MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE` has been removed, and
+  `MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL` is returned instead if the user's own certificate
+  is too large to fit into the output buffers.
+  
+  Users should check for `MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL` instead, and potentially
+  compare the size of their own certificate against the configured size of the output buffer to
+  understand if the error is due to an overly large certificate.
+
+- `MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN` and `MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE` have been
+  replaced by `MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE`.
+
+- All codes of the form `MBEDTLS_ERR_SSL_BAD_HS_XXX` have been replaced by various alternatives, which give more information about the type of error raised.
+
+  Users should check for the newly introduced generic error codes
+
+  * `MBEDTLS_ERR_SSL_DECODE_ERROR`
+  * `MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER`,
+  * `MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE`
+  * `MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION`
+  * `MBEDTLS_ERR_SSL_BAD_CERTIFICATE`
+  * `MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME`
+  * `MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION`
+  * `MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL`
+
+  and the pre-existing generic error codes
+
+  * `MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE`
+  * `MBEDTLS_ERR_SSL_INTERNAL_ERROR`
+
+  instead.
+
+### Modified semantics of `mbedtls_ssl_{get,set}_session()`
+
+This affects users who call `mbedtls_ssl_get_session()` or
+`mbedtls_ssl_set_session()` multiple times on the same SSL context
+representing an established TLS 1.2 connection.
+Those users will now observe the second call to fail with
+`MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE`.
+
+Migration path:
+- Exporting the same TLS 1.2 connection multiple times via
+  `mbedtls_ssl_get_session()` leads to multiple copies of
+  the same session. This use of `mbedtls_ssl_get_session()`
+  is discouraged, and the following should be considered:
+  * If the various session copies are later loaded into
+    fresh SSL contexts via `mbedtls_ssl_set_session()`,
+    export via `mbedtls_ssl_get_session()` only once and
+    load the same session into different contexts via
+    `mbedtls_ssl_set_session()`. Since `mbedtls_ssl_set_session()`
+    makes a copy of the session that's being loaded, this
+    is functionally equivalent.
+  * If the various session copies are later serialized
+    via `mbedtls_ssl_session_save()`, export and serialize
+    the session only once via `mbedtls_ssl_get_session()` and
+    `mbedtls_ssl_session_save()` and make copies of the raw
+    data instead.
+- Calling `mbedtls_ssl_set_session()` multiple times in Mbed TLS 2.x
+  is not useful since subsequent calls overwrite the effect of previous
+  calls. Applications achieve equivalent functional behavior by
+  issuing only the very last call to `mbedtls_ssl_set_session()`.
+
+### Turn `MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE` configuration option into a runtime option
+
+This change affects users who were enabling `MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE`
+option in the `mbedtls_config.h`
+
+This option has been removed and a new function with similar functionality has
+been introduced into the SSL API.
+
+This new function `mbedtls_ssl_conf_preference_order()` can be used to
+change the preferred order of ciphersuites on the server to those used on the client,
+e.g.: `mbedtls_ssl_conf_preference_order(ssl_config, MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT)`
+has the same effect as enabling the removed option. The default state is to use
+the server order of suites.
+
+### Strengthen default algorithm selection for X.509 and TLS
+
+The default X.509 verification profile (`mbedtls_x509_crt_profile_default`) and the default curve and hash selection in TLS have changed. They are now aligned, except that the X.509 profile only lists curves that support signature verification.
+
+Hashes and curves weaker than 255 bits (security strength less than 128 bits) are no longer accepted by default. The following hashes have been removed: SHA-1 (formerly only accepted for key exchanges but not for certificate signatures), SHA-224 (weaker hashes were already not accepted). The following curves have been removed: secp192r1, secp224r1, secp192k1, secp224k1.
+
+The compile-time options `MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES` and `MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE` are no longer available.
+
+The curve secp256k1 has also been removed from the default X.509 and TLS profiles. [RFC 8422](https://datatracker.ietf.org/doc/html/rfc8422#section-5.1.1) deprecates it in TLS, and it is very rarely used, although it is not known to be weak at the time of writing.
+
+If you still need to accept certificates signed with algorithms that have been removed from the default profile, call `mbedtls_x509_crt_verify_with_profile` instead of `mbedtls_x509_crt_verify` and pass a profile that allows the curves and hashes you want. For example, to allow SHA-224:
+```C
+mbedtls_x509_crt_profile my_profile = mbedtls_x509_crt_profile_default;
+my_profile.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 );
+```
+
+If you still need to allow hashes and curves in TLS that have been removed from the default configuration, call `mbedtls_ssl_conf_sig_hashes()` and `mbedtls_ssl_conf_curves()` with the desired lists.
+
+### Remove 3DES ciphersuites
+
+This change does not affect users using default settings for 3DES in `mbedtls_config.h`
+because the 3DES ciphersuites were disabled by that.
+
+3DES has weaknesses/limitations and there are better alternatives, and more and
+more standard bodies are recommending against its use in TLS.
+
+The migration path here is to chose from the alternatives recommended in the
+literature, such as AES.
diff --git a/docs/architecture/testing/test-framework.md b/docs/architecture/testing/test-framework.md
index c4178fa..d0d4776 100644
--- a/docs/architecture/testing/test-framework.md
+++ b/docs/architecture/testing/test-framework.md
@@ -51,7 +51,7 @@
 The outcome file has 6 fields:
 
 * **Platform**: a description of the platform, e.g. `Linux-x86_64` or `Linux-x86_64-gcc7-msan`.
-* **Configuration**: a unique description of the configuration (`config.h`).
+* **Configuration**: a unique description of the configuration (`mbedtls_config.h`).
 * **Test suite**: `test_suite_xxx` or `ssl-opt`.
 * **Test case**: the description of the test case.
 * **Result**: one of `PASS`, `SKIP` or `FAIL`.
diff --git a/docs/architecture/tls13-experimental.md b/docs/architecture/tls13-experimental.md
index 10cbfa1..0009c68 100644
--- a/docs/architecture/tls13-experimental.md
+++ b/docs/architecture/tls13-experimental.md
@@ -15,7 +15,7 @@
 This macro will likely be renamed to `MBEDTLS_SSL_PROTO_TLS1_3` once a minimal viable
 implementation of the TLS 1.3 protocol is available.
 
-See the [documentation of `MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL`](../../include/mbedtls/config.h)
+See the [documentation of `MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL`](../../include/mbedtls/mbedtls_config.h)
 for more information.
 
 Status
diff --git a/docs/proposed/psa-conditional-inclusion-c.md b/docs/proposed/psa-conditional-inclusion-c.md
index 2ddba7f..50a1404 100644
--- a/docs/proposed/psa-conditional-inclusion-c.md
+++ b/docs/proposed/psa-conditional-inclusion-c.md
@@ -15,7 +15,7 @@
 
 ### Conditional inclusion of legacy cryptography modules
 
-Mbed TLS offers a way to select which cryptographic mechanisms are included in a build through its configuration file (`config.h`). This mechanism is based on two main sets of symbols: `MBEDTLS_xxx_C` controls the availability of the mechanism to the application, and `MBEDTLS_xxx_ALT` controls the availability of an alternative implementation, so the software implementation is only included if `MBEDTLS_xxx_C` is defined but not `MBEDTLS_xxx_ALT`.
+Mbed TLS offers a way to select which cryptographic mechanisms are included in a build through its configuration file (`mbedtls_config.h`). This mechanism is based on two main sets of symbols: `MBEDTLS_xxx_C` controls the availability of the mechanism to the application, and `MBEDTLS_xxx_ALT` controls the availability of an alternative implementation, so the software implementation is only included if `MBEDTLS_xxx_C` is defined but not `MBEDTLS_xxx_ALT`.
 
 ### PSA evolution
 
@@ -51,10 +51,10 @@
 
 The PSA Crypto configuration file `psa/crypto_config.h` defines a series of symbols of the form `PSA_WANT_xxx` where `xxx` describes the feature that the symbol enables. The symbols are documented in the section [“PSA Crypto configuration symbols”](#psa-crypto-configuration-symbols) below.
 
-The symbol `MBEDTLS_PSA_CRYPTO_CONFIG` in `mbedtls/config.h` determines whether `psa/crypto_config.h` is used.
+The symbol `MBEDTLS_PSA_CRYPTO_CONFIG` in `mbedtls/mbedtls_config.h` determines whether `psa/crypto_config.h` is used.
 
 * If `MBEDTLS_PSA_CRYPTO_CONFIG` is unset, which is the default at least in Mbed TLS 2.x versions, things are as they are today: the PSA subsystem includes generic code unconditionally, and includes support for specific mechanisms conditionally based on the existing `MBEDTLS_xxx_` symbols.
-* If `MBEDTLS_PSA_CRYPTO_CONFIG` is set, the necessary software implementations of cryptographic algorithms are included based on both the content of the PSA Crypto configuration file and the Mbed TLS configuration file. For example, the code in `aes.c` is enabled if either `mbedtls/config.h` contains `MBEDTLS_AES_C` or `psa/crypto_config.h` contains `PSA_WANT_KEY_TYPE_AES`.
+* If `MBEDTLS_PSA_CRYPTO_CONFIG` is set, the necessary software implementations of cryptographic algorithms are included based on both the content of the PSA Crypto configuration file and the Mbed TLS configuration file. For example, the code in `aes.c` is enabled if either `mbedtls/mbedtls_config.h` contains `MBEDTLS_AES_C` or `psa/crypto_config.h` contains `PSA_WANT_KEY_TYPE_AES`.
 
 ### PSA Crypto configuration symbols
 
@@ -123,17 +123,17 @@
 
 #### New-style definition of configuration symbols
 
-When `MBEDTLS_PSA_CRYPTO_CONFIG` is set, the header file `mbedtls/config.h` needs to define all the `MBEDTLS_xxx_C` configuration symbols, including the ones deduced from the PSA Crypto configuration. It does this by including the new header file **`mbedtls/config_psa.h`**, which defines the `MBEDTLS_PSA_BUILTIN_xxx` symbols and deduces the corresponding `MBEDTLS_xxx_C` (and other) symbols.
+When `MBEDTLS_PSA_CRYPTO_CONFIG` is set, the header file `mbedtls/mbedtls_config.h` needs to define all the `MBEDTLS_xxx_C` configuration symbols, including the ones deduced from the PSA Crypto configuration. It does this by including the new header file **`mbedtls/config_psa.h`**, which defines the `MBEDTLS_PSA_BUILTIN_xxx` symbols and deduces the corresponding `MBEDTLS_xxx_C` (and other) symbols.
 
 `mbedtls/config_psa.h` includes `psa/crypto_config.h`, the user-editable file that defines application requirements.
 
 #### Old-style definition of configuration symbols
 
-When `MBEDTLS_PSA_CRYPTO_CONFIG` is not set, the configuration of Mbed TLS works as before, and the inclusion of non-PSA code only depends on `MBEDTLS_xxx` symbols defined (or not) in `mbedtls/config.h`. Furthermore, the new header file **`mbedtls/config_psa.h`** deduces PSA configuration symbols (`PSA_WANT_xxx`, `MBEDTLS_PSA_BUILTIN_xxx`) from classic configuration symbols (`MBEDTLS_xxx`).
+When `MBEDTLS_PSA_CRYPTO_CONFIG` is not set, the configuration of Mbed TLS works as before, and the inclusion of non-PSA code only depends on `MBEDTLS_xxx` symbols defined (or not) in `mbedtls/mbedtls_config.h`. Furthermore, the new header file **`mbedtls/config_psa.h`** deduces PSA configuration symbols (`PSA_WANT_xxx`, `MBEDTLS_PSA_BUILTIN_xxx`) from classic configuration symbols (`MBEDTLS_xxx`).
 
 The `PSA_WANT_xxx` definitions in `mbedtls/config_psa.h` are needed not only to build the PSA parts of the library, but also to build code that uses these parts. This includes structure definitions in `psa/crypto_struct.h`, size calculations in `psa/crypto_sizes.h`, and application code that's specific to a given cryptographic mechanism. In Mbed TLS itself, code under `MBEDTLS_USE_PSA_CRYPTO` and conditional compilation guards in tests and sample programs need `PSA_WANT_xxx`.
 
-Since some existing applications use a handwritten `mbedtls/config.h` or an edited copy of `mbedtls/config.h` from an earlier version of Mbed TLS, `mbedtls/config_psa.h` must be included via an already existing header that is not `mbedtls/config.h`, so it is included via `psa/crypto.h` (for example from `psa/crypto_platform.h`).
+Since some existing applications use a handwritten `mbedtls/mbedtls_config.h` or an edited copy of `mbedtls/mbedtls_config.h` from an earlier version of Mbed TLS, `mbedtls/config_psa.h` must be included via an already existing header that is not `mbedtls/mbedtls_config.h`, so it is included via `psa/crypto.h` (for example from `psa/crypto_platform.h`).
 
 #### Summary of definitions of configuration symbols
 
@@ -145,13 +145,13 @@
 * (D) indicates a symbol that is deduced from other symbols by code that ships with Mbed TLS.
 * (G) indicates a symbol that is generated from driver descriptions.
 
-| Symbols                   | With `MBEDTLS_PSA_CRYPTO_CONFIG` | Without `MBEDTLS_PSA_CRYPTO_CONFIG` |
-| ------------------------- | -------------------------------- | ----------------------------------- |
-| `MBEDTLS_xxx_C`           | `mbedtls/config.h` (U) or        | `mbedtls/config.h` (U)              |
-|                           | `mbedtls/config_psa.h` (D)       |                                     |
-| `PSA_WANT_xxx`            | `psa/crypto_config.h` (U)        | `mbedtls/config_psa.h` (D)          |
-| `MBEDTLS_PSA_BUILTIN_xxx` | `mbedtls/config_psa.h` (D)       | `mbedtls/config_psa.h` (D)          |
-| `MBEDTLS_PSA_ACCEL_xxx`   | `mbedtls/crypto_drivers.h` (G)   | N/A                                 |
+| Symbols                   | With `MBEDTLS_PSA_CRYPTO_CONFIG`  | Without `MBEDTLS_PSA_CRYPTO_CONFIG` |
+| ------------------------- | --------------------------------- | ----------------------------------- |
+| `MBEDTLS_xxx_C`           | `mbedtls/mbedtls_config.h` (U) or | `mbedtls/mbedtls_config.h` (U)      |
+|                           | `mbedtls/config_psa.h` (D)        |                                     |
+| `PSA_WANT_xxx`            | `psa/crypto_config.h` (U)         | `mbedtls/config_psa.h` (D)          |
+| `MBEDTLS_PSA_BUILTIN_xxx` | `mbedtls/config_psa.h` (D)        | `mbedtls/config_psa.h` (D)          |
+| `MBEDTLS_PSA_ACCEL_xxx`   | `mbedtls/crypto_drivers.h` (G)    | N/A                                 |
 
 #### Visibility of internal symbols
 
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 62c0f62..e693bc1 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -15,7 +15,7 @@
 
 endif(INSTALL_MBEDTLS_HEADERS)
 
-# Make config.h available in an out-of-source build. ssl-opt.sh requires it.
+# Make mbedtls_config.h available in an out-of-source build. ssl-opt.sh requires it.
 if (ENABLE_TESTING AND NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
     link_to_source(mbedtls)
     link_to_source(psa)
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index e23b9ca..0050980 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -41,11 +41,7 @@
 #define MBEDTLS_AES_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
index 854aa69..0854706 100644
--- a/include/mbedtls/aria.h
+++ b/include/mbedtls/aria.h
@@ -30,11 +30,7 @@
 #define MBEDTLS_ARIA_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index 6611981..4668581 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_ASN1_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h
index fb111ca..d60ca0d 100644
--- a/include/mbedtls/asn1write.h
+++ b/include/mbedtls/asn1write.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_ASN1_WRITE_H
 #define MBEDTLS_ASN1_WRITE_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/asn1.h"
 
diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h
index 7e73a8b..e3938b4 100644
--- a/include/mbedtls/base64.h
+++ b/include/mbedtls/base64.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_BASE64_H
 #define MBEDTLS_BASE64_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 74deecf..5187d86 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_BIGNUM_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
new file mode 100644
index 0000000..c7d4cdb
--- /dev/null
+++ b/include/mbedtls/build_info.h
@@ -0,0 +1,83 @@
+/**
+ * \file build_info.h
+ *
+ * \brief Build-time configuration info
+ *
+ *  Include this file if you need to depend on the
+ *  configuration options defined in mbedtls_config.h or MBEDTLS_CONFIG_FILE
+ */
+ /*
+  *  Copyright The Mbed TLS Contributors
+  *  SPDX-License-Identifier: Apache-2.0
+  *
+  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+  *  not use this file except in compliance with the License.
+  *  You may obtain a copy of the License at
+  *
+  *  http://www.apache.org/licenses/LICENSE-2.0
+  *
+  *  Unless required by applicable law or agreed to in writing, software
+  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  *  See the License for the specific language governing permissions and
+  *  limitations under the License.
+  */
+
+#ifndef MBEDTLS_BUILD_INFO_H
+#define MBEDTLS_BUILD_INFO_H
+
+/*
+ * This set of compile-time defines can be used to determine the version number
+ * of the Mbed TLS library used. Run-time variables for the same can be found in
+ * version.h
+ */
+
+/**
+ * The version number x.y.z is split into three parts.
+ * Major, Minor, Patchlevel
+ */
+#define MBEDTLS_VERSION_MAJOR  2
+#define MBEDTLS_VERSION_MINOR  26
+#define MBEDTLS_VERSION_PATCH  0
+
+/**
+ * The single version number has the following structure:
+ *    MMNNPP00
+ *    Major version | Minor version | Patch version
+ */
+#define MBEDTLS_VERSION_NUMBER         0x021A0000
+#define MBEDTLS_VERSION_STRING         "2.26.0"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.26.0"
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/mbedtls_config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CONFIG_VERSION) && ( \
+    MBEDTLS_CONFIG_VERSION < 0x03000000 || \
+    MBEDTLS_CONFIG_VERSION > MBEDTLS_VERSION_NUMBER )
+#error "Invalid config version, defined value of MBEDTLS_CONFIG_VERSION is unsupported"
+#endif
+
+/* Target and application specific configurations
+ *
+ * Allow user to override any previous default.
+ *
+ */
+#if defined(MBEDTLS_USER_CONFIG_FILE)
+#include MBEDTLS_USER_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#include "mbedtls/config_psa.h"
+#endif
+
+#include "mbedtls/check_config.h"
+
+#endif /* MBEDTLS_BUILD_INFO_H */
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index d2d4f61..6a09da8 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_CAMELLIA_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index 98f5693..6613cee 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -48,11 +48,7 @@
 #define MBEDTLS_CCM_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/cipher.h"
 
@@ -345,6 +341,9 @@
  * \param plaintext_len  The length in bytes of the plaintext to encrypt or
  *                       result of the decryption (thus not encompassing the
  *                       additional data that are not encrypted).
+ * \param tag_len   The length of the tag to generate in Bytes:
+ *                  4, 6, 8, 10, 12, 14 or 16.
+ *                  For CCM*, zero is also valid.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_CCM_BAD_INPUT on failure:
@@ -353,7 +352,8 @@
  */
 int mbedtls_ccm_set_lengths( mbedtls_ccm_context *ctx,
                              size_t total_ad_len,
-                             size_t plaintext_len );
+                             size_t plaintext_len,
+                             size_t tag_len );
 
 /**
  * \brief           This function feeds an input buffer as associated data
@@ -473,9 +473,8 @@
  * \param tag       The buffer for holding the tag. If \p tag_len is greater
  *                  than zero, this must be a writable buffer of at least \p
  *                  tag_len Bytes.
- * \param tag_len   The length of the tag to generate in Bytes:
- *                  4, 6, 8, 10, 12, 14 or 16.
- *                  For CCM*, zero is also valid.
+ * \param tag_len   The length of the tag. Must match the tag length passed to
+ *                  mbedtls_ccm_set_lengths() function.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_CCM_BAD_INPUT on failure:
diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h
index 441aaa4..25e1a26 100644
--- a/include/mbedtls/chacha20.h
+++ b/include/mbedtls/chacha20.h
@@ -33,11 +33,7 @@
 #define MBEDTLS_CHACHA20_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stdint.h>
 #include <stddef.h>
diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h
index 7c36739..3f6e4a3 100644
--- a/include/mbedtls/chachapoly.h
+++ b/include/mbedtls/chachapoly.h
@@ -33,11 +33,7 @@
 #define MBEDTLS_CHACHAPOLY_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 /* for shared error codes */
 #include "mbedtls/poly1305.h"
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 36959ed..e38892d 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -20,11 +20,6 @@
  *  limitations under the License.
  */
 
-/*
- * It is recommended to include this file from your config.h
- * in order to catch dependency issues early.
- */
-
 #ifndef MBEDTLS_CHECK_CONFIG_H
 #define MBEDTLS_CHECK_CONFIG_H
 
@@ -42,7 +37,7 @@
 #error "MBEDTLS_PLATFORM_C is required on Windows"
 #endif
 
-/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
+/* Fix the config here. Not convenient to put an #ifdef _WIN32 in mbedtls_config.h as
  * it would confuse config.py. */
 #if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
     !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 63c5309..7afdc6a 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -28,11 +28,7 @@
 #define MBEDTLS_CIPHER_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include "mbedtls/platform_util.h"
@@ -725,8 +721,6 @@
 /**
  * \brief               This function adds additional data for AEAD ciphers.
  *                      Currently supported with GCM and ChaCha20+Poly1305.
- *                      This must be called exactly once, after
- *                      mbedtls_cipher_reset().
  *
  * \param ctx           The generic cipher context. This must be initialized.
  * \param ad            The additional data to use. This must be a readable
diff --git a/include/mbedtls/cmac.h b/include/mbedtls/cmac.h
index 65c831c..3e599b9 100644
--- a/include/mbedtls/cmac.h
+++ b/include/mbedtls/cmac.h
@@ -27,11 +27,7 @@
 #define MBEDTLS_CMAC_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/cipher.h"
 
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index a0f2637..f182c52 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -3,11 +3,11 @@
  * \brief PSA crypto configuration options (set of defines)
  *
  *  This set of compile-time options takes settings defined in
- *  include/mbedtls/config.h and include/psa/crypto_config.h and uses
+ *  include/mbedtls/mbedtls_config.h and include/psa/crypto_config.h and uses
  *  those definitions to define symbols used in the library code.
  *
  *  Users and integrators should not edit this file, please edit
- *  include/mbedtls/config.h for MBETLS_XXX settings or
+ *  include/mbedtls/mbedtls_config.h for MBETLS_XXX settings or
  *  include/psa/crypto_config.h for PSA_WANT_XXX settings.
  */
 /*
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index b8e2c71..c188b08 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -16,7 +16,7 @@
  * The security strength as defined in NIST SP 800-90A is
  * 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
  * and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
- * kept at its default value (and not overridden in config.h) and that the
+ * kept at its default value (and not overridden in mbedtls_config.h) and that the
  * DRBG instance is set up with default parameters.
  * See the documentation of mbedtls_ctr_drbg_seed() for more
  * information.
@@ -42,11 +42,7 @@
 #define MBEDTLS_CTR_DRBG_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/aes.h"
 
@@ -84,7 +80,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them using the compiler command
+ * Either change them in mbedtls_config.h or define them using the compiler command
  * line.
  * \{
  */
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
index 71b0829..0aed596 100644
--- a/include/mbedtls/debug.h
+++ b/include/mbedtls/debug.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_DEBUG_H
 #define MBEDTLS_DEBUG_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ssl.h"
 
diff --git a/include/mbedtls/des.h b/include/mbedtls/des.h
index 24d2402..9e2f683 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -28,11 +28,7 @@
 #define MBEDTLS_DES_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index 850813e..75baed9 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -64,11 +64,7 @@
 #define MBEDTLS_DHM_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 #include "mbedtls/bignum.h"
 
 /*
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index 587035a..7fa7440 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -33,11 +33,7 @@
 #define MBEDTLS_ECDH_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ecp.h"
 
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index 735d377..71b73ee 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -31,11 +31,7 @@
 #define MBEDTLS_ECDSA_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ecp.h"
 #include "mbedtls/md.h"
@@ -294,6 +290,7 @@
  *                  size of the curve used, plus 9. For example, 73 Bytes if
  *                  a 256-bit curve is used. A buffer length of
  *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param sig_size  The size of the \p sig buffer in bytes.
  * \param slen      The address at which to store the actual length of
  *                  the signature written. Must not be \c NULL.
  * \param f_rng     The RNG function. This must not be \c NULL if
@@ -310,7 +307,7 @@
 int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
                                    mbedtls_md_type_t md_alg,
                            const unsigned char *hash, size_t hlen,
-                           unsigned char *sig, size_t *slen,
+                           unsigned char *sig, size_t sig_size, size_t *slen,
                            int (*f_rng)(void *, unsigned char *, size_t),
                            void *p_rng );
 
@@ -336,6 +333,7 @@
  *                  size of the curve used, plus 9. For example, 73 Bytes if
  *                  a 256-bit curve is used. A buffer length of
  *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param sig_size  The size of the \p sig buffer in bytes.
  * \param slen      The address at which to store the actual length of
  *                  the signature written. Must not be \c NULL.
  * \param f_rng     The RNG function. This must not be \c NULL if
@@ -356,7 +354,7 @@
 int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
                            mbedtls_md_type_t md_alg,
                            const unsigned char *hash, size_t hlen,
-                           unsigned char *sig, size_t *slen,
+                           unsigned char *sig, size_t sig_size, size_t *slen,
                            int (*f_rng)(void *, unsigned char *, size_t),
                            void *p_rng,
                            mbedtls_ecdsa_restart_ctx *rs_ctx );
diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h
index 27a091d..a73f624 100644
--- a/include/mbedtls/ecjpake.h
+++ b/include/mbedtls/ecjpake.h
@@ -39,11 +39,7 @@
  * The payloads are serialized in a way suitable for use in TLS, but could
  * also be use outside TLS.
  */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ecp.h"
 #include "mbedtls/md.h"
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index db84c10..b87114b 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -35,11 +35,7 @@
 #define MBEDTLS_ECP_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/bignum.h"
 
@@ -95,7 +91,7 @@
  * - Increment MBEDTLS_ECP_DP_MAX below if needed.
  * - Update the calculation of MBEDTLS_ECP_MAX_BITS below.
  * - Add the corresponding MBEDTLS_ECP_DP_xxx_ENABLED macro definition to
- *   config.h.
+ *   mbedtls_config.h.
  * - List the curve as a dependency of MBEDTLS_ECP_C and
  *   MBEDTLS_ECDSA_C if supported in check_config.h.
  * - Add the curve to the appropriate curve type macro
@@ -248,7 +244,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h, or define them using the compiler command line.
+ * Either change them in mbedtls_config.h, or define them using the compiler command line.
  * \{
  */
 
diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index 78591e7..a16a375 100644
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_ENTROPY_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
@@ -56,7 +52,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
  * \{
  */
 
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 2835fd5..9a8690d 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_ERROR_H
 #define MBEDTLS_ERROR_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
@@ -101,10 +97,9 @@
  * HKDF      5   1 (Started from top)
  * SSL       5   2 (Started from 0x5F00)
  * CIPHER    6   8 (Started from 0x6080)
- * SSL       6   23 (Started from top, plus 0x6000, gaps at
- *                   0x6600)
- * SSL       7   28 (Started from 0x7080, gaps at
- *                   0x7300, 0x7500, 0x7580, 0x7800)
+ * SSL       6   22 (Started from top, plus 0x6000)
+ * SSL       7   20 (Started from 0x7000, gaps at
+ *                   0x7380, 0x7900-0x7980, 0x7A80-0x7E80)
  *
  * Module dependent error code (5 bits 0x.00.-0x.F8.)
  */
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index c8e384a..d1219bb 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -32,11 +32,7 @@
 #define MBEDTLS_GCM_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/cipher.h"
 
@@ -246,11 +242,6 @@
  *                  you do not need to call this function. You may not
  *                  call this function after calling mbedtls_cipher_update().
  *
- * \note            This function may only be called once per operation:
- *                  you must pass the whole associated data in a single
- *                  call. This limitation will be lifted in a future version
- *                  of Mbed TLS.
- *
  * \param ctx       The GCM context. This must have been started with
  *                  mbedtls_gcm_starts() and must not have yet received
  *                  any input with mbedtls_gcm_update().
@@ -344,6 +335,10 @@
  *                    then mbedtls_gcm_finish() never produces any output,
  *                    so \p output_size can be \c 0.
  *                  - \p output_size never needs to be more than \c 15.
+ * \param output_length On success, \p *output_length contains the actual
+ *                      length of the output written in \p output.
+ *                      On failure, the content of \p *output_length is
+ *                      unspecified.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_GCM_BAD_INPUT on failure:
@@ -352,6 +347,7 @@
  */
 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
                         unsigned char *output, size_t output_size,
+                        size_t *output_length,
                         unsigned char *tag, size_t tag_len );
 
 /**
diff --git a/include/mbedtls/hkdf.h b/include/mbedtls/hkdf.h
index 2e6b363..81a6270 100644
--- a/include/mbedtls/hkdf.h
+++ b/include/mbedtls/hkdf.h
@@ -25,11 +25,7 @@
 #ifndef MBEDTLS_HKDF_H
 #define MBEDTLS_HKDF_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/md.h"
 
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 164a4f7..0df8ee8 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -27,11 +27,7 @@
 #define MBEDTLS_HMAC_DRBG_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/md.h"
 
@@ -51,7 +47,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
  * \{
  */
 
diff --git a/include/mbedtls/config.h b/include/mbedtls/mbedtls_config.h
similarity index 99%
rename from include/mbedtls/config.h
rename to include/mbedtls/mbedtls_config.h
index 47605f9..a60db7e 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1,5 +1,5 @@
 /**
- * \file config.h
+ * \file mbedtls_config.h
  *
  * \brief Configuration options (set of defines)
  *
@@ -24,12 +24,14 @@
  *  limitations under the License.
  */
 
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
-#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
-#define _CRT_SECURE_NO_DEPRECATE 1
-#endif
+/**
+ * This is an optional version symbol that enables comatibility handling of
+ * config files.
+ *
+ * It is equal to the #MBEDTLS_VERSION_NUMBER of the Mbed TLS version that
+ * introduced the config format we want to be compatible with.
+ */
+//#define MBEDTLS_CONFIG_VERSION 0x03000000
 
 /**
  * \name SECTION: System support
@@ -1741,10 +1743,6 @@
  * Uncomment this to enable use of PSA Crypto configuration settings which
  * can be found in include/psa/crypto_config.h.
  *
- * If you enable this option and write your own configuration file, you must
- * include mbedtls/config_psa.h in your configuration file. The default
- * provided mbedtls/config.h contains the necessary inclusion.
- *
  * This feature is still experimental and is not ready for production since
  * it is not completed.
  */
@@ -3263,20 +3261,3 @@
 //#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
 
 /* \} name SECTION: Customisation configuration options */
-
-/* Target and application specific configurations
- *
- * Allow user to override any previous default.
- *
- */
-#if defined(MBEDTLS_USER_CONFIG_FILE)
-#include MBEDTLS_USER_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
-#include "mbedtls/config_psa.h"
-#endif
-
-#include "mbedtls/check_config.h"
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h
index 7bf8213..1170bc1 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -28,11 +28,7 @@
 
 #include <stddef.h>
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE                -0x5080  /**< The selected feature is not available. */
 #define MBEDTLS_ERR_MD_BAD_INPUT_DATA                     -0x5100  /**< Bad input parameters to function. */
diff --git a/include/mbedtls/md5.h b/include/mbedtls/md5.h
index 6ef3591..e7befc3 100644
--- a/include/mbedtls/md5.h
+++ b/include/mbedtls/md5.h
@@ -27,11 +27,7 @@
 #define MBEDTLS_MD5_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/memory_buffer_alloc.h b/include/mbedtls/memory_buffer_alloc.h
index 2339772..d4737f5 100644
--- a/include/mbedtls/memory_buffer_alloc.h
+++ b/include/mbedtls/memory_buffer_alloc.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H
 #define MBEDTLS_MEMORY_BUFFER_ALLOC_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
@@ -34,7 +30,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
  * \{
  */
 
diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
index 502b9f4..7b77329 100644
--- a/include/mbedtls/net_sockets.h
+++ b/include/mbedtls/net_sockets.h
@@ -39,11 +39,7 @@
 #define MBEDTLS_NET_SOCKETS_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ssl.h"
 
diff --git a/include/mbedtls/nist_kw.h b/include/mbedtls/nist_kw.h
index c537b58..bd6c658 100644
--- a/include/mbedtls/nist_kw.h
+++ b/include/mbedtls/nist_kw.h
@@ -36,11 +36,7 @@
 #define MBEDTLS_NIST_KW_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/cipher.h"
 
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index 1921042..9e68e91 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_OID_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/asn1.h"
 #include "mbedtls/pk.h"
diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h
index 9242da6..a01a296 100644
--- a/include/mbedtls/pem.h
+++ b/include/mbedtls/pem.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_PEM_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index dec5111..f3553cc 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -24,11 +24,7 @@
 #define MBEDTLS_PK_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/md.h"
 
@@ -67,6 +63,7 @@
 #define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00  /**< Elliptic curve is unsupported (only NIST curves are supported). */
 #define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980  /**< Unavailable feature, e.g. RSA disabled for RSA key. */
 #define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH    -0x3900  /**< The buffer contains a valid signature followed by more data. */
+#define MBEDTLS_ERR_PK_BUFFER_TOO_SMALL    -0x3880  /**< The output buffer is too small. */
 
 #ifdef __cplusplus
 extern "C" {
@@ -399,9 +396,17 @@
  * \brief           Verify signature (including padding if relevant).
  *
  * \param ctx       The PK context to use. It must have been set up.
- * \param md_alg    Hash algorithm used (see notes)
+ * \param md_alg    Hash algorithm used.
+ *                  This can be #MBEDTLS_MD_NONE if the signature algorithm
+ *                  does not rely on a hash algorithm (non-deterministic
+ *                  ECDSA, RSA PKCS#1 v1.5).
+ *                  For PKCS#1 v1.5, if \p md_alg is #MBEDTLS_MD_NONE, then
+ *                  \p hash is the DigestInfo structure used by RFC 8017
+ *                  &sect;9.2 steps 3&ndash;6. If \p md_alg is a valid hash
+ *                  algorithm then \p hash is the digest itself, and this
+ *                  function calculates the DigestInfo encoding internally.
  * \param hash      Hash of the message to sign
- * \param hash_len  Hash length or 0 (see notes)
+ * \param hash_len  Hash length
  * \param sig       Signature to verify
  * \param sig_len   Signature length
  *
@@ -413,11 +418,6 @@
  * \note            For RSA keys, the default padding type is PKCS#1 v1.5.
  *                  Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... )
  *                  to verify RSASSA_PSS signatures.
- *
- * \note            If hash_len is 0, then the length associated with md_alg
- *                  is used instead, or an error returned if it is invalid.
- *
- * \note            md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0
  */
 int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
                const unsigned char *hash, size_t hash_len,
@@ -490,12 +490,13 @@
  *                  with a private key.
  * \param md_alg    Hash algorithm used (see notes)
  * \param hash      Hash of the message to sign
- * \param hash_len  Hash length or 0 (see notes)
+ * \param hash_len  Hash length
  * \param sig       Place to write the signature.
  *                  It must have enough room for the signature.
  *                  #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
  *                  You may use a smaller buffer if it is large enough
  *                  given the key type.
+ * \param sig_size  The size of the \p sig buffer in bytes.
  * \param sig_len   On successful return,
  *                  the number of bytes written to \p sig.
  * \param f_rng     RNG function, must not be \c NULL.
@@ -507,15 +508,12 @@
  *                  There is no interface in the PK module to make RSASSA-PSS
  *                  signatures yet.
  *
- * \note            If hash_len is 0, then the length associated with md_alg
- *                  is used instead, or an error returned if it is invalid.
- *
  * \note            For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
  *                  For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
  */
 int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
              const unsigned char *hash, size_t hash_len,
-             unsigned char *sig, size_t *sig_len,
+             unsigned char *sig, size_t sig_size, size_t *sig_len,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 /**
@@ -530,12 +528,13 @@
  *                  with a private key.
  * \param md_alg    Hash algorithm used (see notes for mbedtls_pk_sign())
  * \param hash      Hash of the message to sign
- * \param hash_len  Hash length or 0 (see notes for mbedtls_pk_sign())
+ * \param hash_len  Hash length
  * \param sig       Place to write the signature.
  *                  It must have enough room for the signature.
  *                  #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
  *                  You may use a smaller buffer if it is large enough
  *                  given the key type.
+ * \param sig_size  The size of the \p sig buffer in bytes.
  * \param sig_len   On successful return,
  *                  the number of bytes written to \p sig.
  * \param f_rng     RNG function, must not be \c NULL.
@@ -549,7 +548,7 @@
 int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
              mbedtls_md_type_t md_alg,
              const unsigned char *hash, size_t hash_len,
-             unsigned char *sig, size_t *sig_len,
+             unsigned char *sig, size_t sig_size, size_t *sig_len,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
              mbedtls_pk_restart_ctx *rs_ctx );
 
diff --git a/include/mbedtls/pkcs12.h b/include/mbedtls/pkcs12.h
index 06092d3..de139ac 100644
--- a/include/mbedtls/pkcs12.h
+++ b/include/mbedtls/pkcs12.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_PKCS12_H
 #define MBEDTLS_PKCS12_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/md.h"
 #include "mbedtls/cipher.h"
diff --git a/include/mbedtls/pkcs5.h b/include/mbedtls/pkcs5.h
index 8f348ce..c339398 100644
--- a/include/mbedtls/pkcs5.h
+++ b/include/mbedtls/pkcs5.h
@@ -24,11 +24,7 @@
 #ifndef MBEDTLS_PKCS5_H
 #define MBEDTLS_PKCS5_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/asn1.h"
 #include "mbedtls/md.h"
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index c50d7d2..277a85c 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -32,11 +32,7 @@
 #define MBEDTLS_PLATFORM_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_HAVE_TIME)
 #include "mbedtls/platform_time.h"
@@ -50,7 +46,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
  * \{
  */
 
diff --git a/include/mbedtls/platform_time.h b/include/mbedtls/platform_time.h
index 7e7daab..8d4b95d 100644
--- a/include/mbedtls/platform_time.h
+++ b/include/mbedtls/platform_time.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_PLATFORM_TIME_H
 #define MBEDTLS_PLATFORM_TIME_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -36,7 +32,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
  * \{
  */
 
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 6d9cfec..1a0a135 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -23,11 +23,7 @@
 #ifndef MBEDTLS_PLATFORM_UTIL_H
 #define MBEDTLS_PLATFORM_UTIL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #if defined(MBEDTLS_HAVE_TIME_DATE)
diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h
index 4d25385..7984ca4 100644
--- a/include/mbedtls/poly1305.h
+++ b/include/mbedtls/poly1305.h
@@ -33,11 +33,7 @@
 #define MBEDTLS_POLY1305_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stdint.h>
 #include <stddef.h>
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index d7b9b17..f6f2e58 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -27,11 +27,7 @@
 #define MBEDTLS_PSA_UTIL_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 
diff --git a/include/mbedtls/ripemd160.h b/include/mbedtls/ripemd160.h
index f12f434..9132a83 100644
--- a/include/mbedtls/ripemd160.h
+++ b/include/mbedtls/ripemd160.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_RIPEMD160_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index f29a0aa..cffbe3b 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -29,11 +29,7 @@
 #define MBEDTLS_RSA_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/bignum.h"
 #include "mbedtls/md.h"
@@ -796,13 +792,11 @@
  *                 if \p f_rng doesn't need a context argument.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest.
- *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hashlen  The length of the message digest or raw data in Bytes.
+ *                 If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ *                 output length of the corresponding hash algorithm.
  * \param hash     The buffer holding the message digest or raw data.
- *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
- *                 buffer of length \p hashlen Bytes. If \p md_alg is not
- *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
- *                 the size of the hash corresponding to \p md_alg.
+ *                 This must be a readable buffer of at least \p hashlen Bytes.
  * \param sig      The buffer to hold the signature. This must be a writable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
  *                 for an 2048-bit RSA modulus. A buffer length of
@@ -830,13 +824,11 @@
  *                 if \p f_rng doesn't need a context argument.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest.
- *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hashlen  The length of the message digest or raw data in Bytes.
+ *                 If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ *                 output length of the corresponding hash algorithm.
  * \param hash     The buffer holding the message digest or raw data.
- *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
- *                 buffer of length \p hashlen Bytes. If \p md_alg is not
- *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
- *                 the size of the hash corresponding to \p md_alg.
+ *                 This must be a readable buffer of at least \p hashlen Bytes.
  * \param sig      The buffer to hold the signature. This must be a writable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
  *                 for an 2048-bit RSA modulus. A buffer length of
@@ -857,12 +849,13 @@
  * \brief          This function performs a PKCS#1 v2.1 PSS signature
  *                 operation (RSASSA-PSS-SIGN).
  *
- * \note           The \p hash_id in the RSA context is the one used for the
- *                 encoding. \p md_alg in the function call is the type of hash
- *                 that is encoded. According to <em>RFC-3447: Public-Key
+ * \note           The \c hash_id set in \p ctx by calling
+ *                 mbedtls_rsa_set_padding() selects the hash used for the
+ *                 encoding operation and for the mask generation function
+ *                 (MGF1). For more details on the encoding operation and the
+ *                 mask generation function, consult <em>RFC-3447: Public-Key
  *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
- *                 Specifications</em> it is advised to keep both hashes the
- *                 same.
+ *                 Specifications</em>.
  *
  * \note           This function enforces that the provided salt length complies
  *                 with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 v2.2) §9.1.1
@@ -877,13 +870,11 @@
  *                 if \p f_rng doesn't need a context argument.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest.
- *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hashlen  The length of the message digest or raw data in Bytes.
+ *                 If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ *                 output length of the corresponding hash algorithm.
  * \param hash     The buffer holding the message digest or raw data.
- *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
- *                 buffer of length \p hashlen Bytes. If \p md_alg is not
- *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
- *                 the size of the hash corresponding to \p md_alg.
+ *                 This must be a readable buffer of at least \p hashlen Bytes.
  * \param saltlen  The length of the salt that should be used.
  *                 If passed #MBEDTLS_RSA_SALT_LEN_ANY, the function will use
  *                 the largest possible salt length up to the hash length,
@@ -910,12 +901,13 @@
  * \brief          This function performs a PKCS#1 v2.1 PSS signature
  *                 operation (RSASSA-PSS-SIGN).
  *
- * \note           The \p hash_id in the RSA context is the one used for the
- *                 encoding. \p md_alg in the function call is the type of hash
- *                 that is encoded. According to <em>RFC-3447: Public-Key
+ * \note           The \c hash_id set in \p ctx by calling
+ *                 mbedtls_rsa_set_padding() selects the hash used for the
+ *                 encoding operation and for the mask generation function
+ *                 (MGF1). For more details on the encoding operation and the
+ *                 mask generation function, consult <em>RFC-3447: Public-Key
  *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
- *                 Specifications</em> it is advised to keep both hashes the
- *                 same.
+ *                 Specifications</em>.
  *
  * \note           This function always uses the maximum possible salt size,
  *                 up to the length of the payload hash. This choice of salt
@@ -933,13 +925,11 @@
  *                 if \p f_rng doesn't need a context argument.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest.
- *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hashlen  The length of the message digest or raw data in Bytes.
+ *                 If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ *                 output length of the corresponding hash algorithm.
  * \param hash     The buffer holding the message digest or raw data.
- *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
- *                 buffer of length \p hashlen Bytes. If \p md_alg is not
- *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
- *                 the size of the hash corresponding to \p md_alg.
+ *                 This must be a readable buffer of at least \p hashlen Bytes.
  * \param sig      The buffer to hold the signature. This must be a writable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
  *                 for an 2048-bit RSA modulus. A buffer length of
@@ -970,13 +960,11 @@
  * \param ctx      The initialized RSA public key context to use.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest.
- *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hashlen  The length of the message digest or raw data in Bytes.
+ *                 If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ *                 output length of the corresponding hash algorithm.
  * \param hash     The buffer holding the message digest or raw data.
- *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
- *                 buffer of length \p hashlen Bytes. If \p md_alg is not
- *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
- *                 the size of the hash corresponding to \p md_alg.
+ *                 This must be a readable buffer of at least \p hashlen Bytes.
  * \param sig      The buffer holding the signature. This must be a readable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
  *                 for an 2048-bit RSA modulus.
@@ -997,13 +985,11 @@
  * \param ctx      The initialized RSA public key context to use.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest.
- *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hashlen  The length of the message digest or raw data in Bytes.
+ *                 If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ *                 output length of the corresponding hash algorithm.
  * \param hash     The buffer holding the message digest or raw data.
- *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
- *                 buffer of length \p hashlen Bytes. If \p md_alg is not
- *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
- *                 the size of the hash corresponding to \p md_alg.
+ *                 This must be a readable buffer of at least \p hashlen Bytes.
  * \param sig      The buffer holding the signature. This must be a readable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
  *                 for an 2048-bit RSA modulus.
@@ -1021,27 +1007,24 @@
  * \brief          This function performs a PKCS#1 v2.1 PSS verification
  *                 operation (RSASSA-PSS-VERIFY).
  *
- *                 The hash function for the MGF mask generating function
- *                 is that specified in the RSA context.
- *
- * \note           The \p hash_id in the RSA context is the one used for the
- *                 verification. \p md_alg in the function call is the type of
- *                 hash that is verified. According to <em>RFC-3447: Public-Key
+ * \note           The \c hash_id set in \p ctx by calling
+ *                 mbedtls_rsa_set_padding() selects the hash used for the
+ *                 encoding operation and for the mask generation function
+ *                 (MGF1). For more details on the encoding operation and the
+ *                 mask generation function, consult <em>RFC-3447: Public-Key
  *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
- *                 Specifications</em> it is advised to keep both hashes the
- *                 same. If \p hash_id in the RSA context is unset,
- *                 the \p md_alg from the function call is used.
+ *                 Specifications</em>. If the \c hash_id set in \p ctx by
+ *                 mbedtls_rsa_set_padding() is #MBEDTLS_MD_NONE, the \p md_alg
+ *                 parameter is used.
  *
  * \param ctx      The initialized RSA public key context to use.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest.
- *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hashlen  The length of the message digest or raw data in Bytes.
+ *                 If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ *                 output length of the corresponding hash algorithm.
  * \param hash     The buffer holding the message digest or raw data.
- *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
- *                 buffer of length \p hashlen Bytes. If \p md_alg is not
- *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
- *                 the size of the hash corresponding to \p md_alg.
+ *                 This must be a readable buffer of at least \p hashlen Bytes.
  * \param sig      The buffer holding the signature. This must be a readable
  *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
  *                 for an 2048-bit RSA modulus.
@@ -1059,25 +1042,27 @@
  * \brief          This function performs a PKCS#1 v2.1 PSS verification
  *                 operation (RSASSA-PSS-VERIFY).
  *
- *                 The hash function for the MGF mask generating function
- *                 is that specified in \p mgf1_hash_id.
- *
  * \note           The \p sig buffer must be as large as the size
  *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
  *
- * \note           The \p hash_id in the RSA context is ignored.
+ * \note           The \c hash_id set in \p ctx by mbedtls_rsa_set_padding() is
+ *                 ignored.
  *
  * \param ctx      The initialized RSA public key context to use.
  * \param md_alg   The message-digest algorithm used to hash the original data.
  *                 Use #MBEDTLS_MD_NONE for signing raw data.
- * \param hashlen  The length of the message digest.
- *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hashlen  The length of the message digest or raw data in Bytes.
+ *                 If \p md_alg is not #MBEDTLS_MD_NONE, this must match the
+ *                 output length of the corresponding hash algorithm.
  * \param hash     The buffer holding the message digest or raw data.
- *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
- *                 buffer of length \p hashlen Bytes. If \p md_alg is not
- *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
- *                 the size of the hash corresponding to \p md_alg.
- * \param mgf1_hash_id      The message digest used for mask generation.
+ *                 This must be a readable buffer of at least \p hashlen Bytes.
+ * \param mgf1_hash_id      The message digest algorithm used for the
+ *                          verification operation and the mask generation
+ *                          function (MGF1). For more details on the encoding
+ *                          operation and the mask generation function, consult
+ *                          <em>RFC-3447: Public-Key Cryptography Standards
+ *                          (PKCS) #1 v2.1: RSA Cryptography
+ *                          Specifications</em>.
  * \param expected_salt_len The length of the salt used in padding. Use
  *                          #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
  * \param sig      The buffer holding the signature. This must be a readable
diff --git a/include/mbedtls/sha1.h b/include/mbedtls/sha1.h
index 0975e2d..d2db67c 100644
--- a/include/mbedtls/sha1.h
+++ b/include/mbedtls/sha1.h
@@ -30,11 +30,7 @@
 #define MBEDTLS_SHA1_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index 76bed43..7f42c2c 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -26,11 +26,7 @@
 #define MBEDTLS_SHA256_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 00d8338..c43b907 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -25,11 +25,7 @@
 #define MBEDTLS_SHA512_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 02b59ed..3a14a58 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_SSL_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/bignum.h"
 #include "mbedtls/ecp.h"
@@ -63,40 +59,41 @@
 /*
  * SSL Error codes
  */
+#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS                -0x7000  /**< A cryptographic operation is in progress. Try again later. */
 #define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE               -0x7080  /**< The requested feature is not available. */
 #define MBEDTLS_ERR_SSL_BAD_INPUT_DATA                    -0x7100  /**< Bad input parameters to function. */
 #define MBEDTLS_ERR_SSL_INVALID_MAC                       -0x7180  /**< Verification of the message MAC failed. */
 #define MBEDTLS_ERR_SSL_INVALID_RECORD                    -0x7200  /**< An invalid SSL record was received. */
 #define MBEDTLS_ERR_SSL_CONN_EOF                          -0x7280  /**< The connection indicated an EOF. */
-/* NOTE: Error space gap */
-#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN                  -0x7380  /**< The server has no ciphersuites in common with the client. */
+#define MBEDTLS_ERR_SSL_DECODE_ERROR                      -0x7300  /**< A message could not be parsed due to a syntactic error. */
+/* Error space gap */
 #define MBEDTLS_ERR_SSL_NO_RNG                            -0x7400  /**< No RNG was provided to the SSL module. */
 #define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE             -0x7480  /**< No client certification received from the client, but required by the authentication mode. */
-/* NOTE: Error space gap */
-/* NOTE: Error space gap */
+#define MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION             -0x7500  /**< Client received an extended server hello containing an unsupported extension */
+#define MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL           -0x7580  /**< No ALPN protocols supported that the client advertises */
 #define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED              -0x7600  /**< The own private key or pre-shared key is not set, but needed. */
 #define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED                 -0x7680  /**< No CA Chain is set, but required to operate. */
 #define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE                -0x7700  /**< An unexpected message was received from our peer. */
 #define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE               -0x7780  /**< A fatal alert message was received from our peer. */
-/* NOTE: Error space gap */
+#define MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME                 -0x7800  /**< No server could be identified matching the client's SNI. */
 #define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY                 -0x7880  /**< The peer notified us that the connection is going to be closed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO               -0x7900  /**< Processing of the ClientHello handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO               -0x7980  /**< Processing of the ServerHello handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE                -0x7A00  /**< Processing of the Certificate handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST        -0x7A80  /**< Processing of the CertificateRequest handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE        -0x7B00  /**< Processing of the ServerKeyExchange handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE          -0x7B80  /**< Processing of the ServerHelloDone handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE        -0x7C00  /**< Processing of the ClientKeyExchange handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP     -0x7C80  /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS     -0x7D00  /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY         -0x7D80  /**< Processing of the CertificateVerify handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC         -0x7E00  /**< Processing of the ChangeCipherSpec handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED                   -0x7E80  /**< Processing of the Finished handshake message failed. */
+/* Error space gap */
+/* Error space gap */
+#define MBEDTLS_ERR_SSL_BAD_CERTIFICATE                   -0x7A00  /**< Processing of the Certificate handshake message failed. */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
 #define MBEDTLS_ERR_SSL_ALLOC_FAILED                      -0x7F00  /**< Memory allocation failed */
 #define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED                   -0x7F80  /**< Hardware acceleration function returned with error */
 #define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH              -0x6F80  /**< Hardware acceleration function skipped / left alone data */
-#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION           -0x6E80  /**< Handshake protocol not within min/max boundaries */
-#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET         -0x6E00  /**< Processing of the NewSessionTicket handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION              -0x6E80  /**< Handshake protocol not within min/max boundaries */
+#define MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE                 -0x6E00  /**< The handshake negotiation failed. */
 #define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED            -0x6D80  /**< Session ticket has expired. */
 #define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH                  -0x6D00  /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */
 #define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY                  -0x6C80  /**< Unknown identity received (eg, PSK identity) */
@@ -105,20 +102,27 @@
 #define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO       -0x6B00  /**< Unexpected message at ServerHello in renegotiation. */
 #define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED             -0x6A80  /**< DTLS client must retry for hello verification */
 #define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL                  -0x6A00  /**< A buffer is too small to receive or write a message */
-#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE             -0x6980  /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */
+/* Error space gap */
 #define MBEDTLS_ERR_SSL_WANT_READ                         -0x6900  /**< No data of requested type currently available on underlying transport. */
 #define MBEDTLS_ERR_SSL_WANT_WRITE                        -0x6880  /**< Connection requires a write call. */
 #define MBEDTLS_ERR_SSL_TIMEOUT                           -0x6800  /**< The operation timed out. */
 #define MBEDTLS_ERR_SSL_CLIENT_RECONNECT                  -0x6780  /**< The client initiated a reconnect from the same port. */
 #define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD                 -0x6700  /**< Record header looks valid but is not expected. */
 #define MBEDTLS_ERR_SSL_NON_FATAL                         -0x6680  /**< The alert message received indicates a non-fatal error. */
-/* NOTE: Error space gap */
+#define MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER                 -0x6600  /**< A field in a message was incorrect or inconsistent with other fields. */
 #define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING               -0x6580  /**< Internal-only message signaling that further message-processing should be done */
 #define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS                 -0x6500  /**< The asynchronous operation is not completed yet. */
 #define MBEDTLS_ERR_SSL_EARLY_MESSAGE                     -0x6480  /**< Internal-only message signaling that a message arrived early. */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
+/* Error space gap */
 #define MBEDTLS_ERR_SSL_UNEXPECTED_CID                    -0x6000  /**< An encrypted DTLS-frame with an unexpected CID was received. */
 #define MBEDTLS_ERR_SSL_VERSION_MISMATCH                  -0x5F00  /**< An operation failed due to an unexpected version or configuration. */
-#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS                -0x7000  /**< A cryptographic operation is in progress. Try again later. */
 #define MBEDTLS_ERR_SSL_BAD_CONFIG                        -0x5E80  /**< Invalid value in SSL config */
 
 /*
@@ -215,7 +219,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
  * \{
  */
 
@@ -3543,7 +3547,7 @@
  *
  * \note           The logic to determine the maximum outgoing record payload is
  *                 version-specific. It takes into account various factors, such as
- *                 the config.h setting \c MBEDTLS_SSL_OUT_CONTENT_LEN, extensions
+ *                 the mbedtls_config.h setting \c MBEDTLS_SSL_OUT_CONTENT_LEN, extensions
  *                 such as the max fragment length or record size limit extension if
  *                 used, and for DTLS the path MTU as configured and current
  *                 record expansion.
@@ -3570,7 +3574,7 @@
  *
  * \note           The logic to determine the maximum outgoing record payload is
  *                 version-specific. It takes into account various factors, such as
- *                 the config.h setting \c MBEDTLS_SSL_IN_CONTENT_LEN, extensions
+ *                 the mbedtls_config.h setting \c MBEDTLS_SSL_IN_CONTENT_LEN, extensions
  *                 such as the max fragment length extension or record size limit
  *                 extension if used, and the current record expansion.
  *
diff --git a/include/mbedtls/ssl_cache.h b/include/mbedtls/ssl_cache.h
index d995f8f..6a81ac9 100644
--- a/include/mbedtls/ssl_cache.h
+++ b/include/mbedtls/ssl_cache.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_SSL_CACHE_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ssl.h"
 
@@ -39,7 +35,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
  * \{
  */
 
diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h
index e343c9c..812560c 100644
--- a/include/mbedtls/ssl_ciphersuites.h
+++ b/include/mbedtls/ssl_ciphersuites.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_SSL_CIPHERSUITES_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/pk.h"
 #include "mbedtls/cipher.h"
diff --git a/include/mbedtls/ssl_cookie.h b/include/mbedtls/ssl_cookie.h
index c4f042c..86698b0 100644
--- a/include/mbedtls/ssl_cookie.h
+++ b/include/mbedtls/ssl_cookie.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_SSL_COOKIE_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ssl.h"
 
@@ -39,7 +35,7 @@
  * \name SECTION: Module settings
  *
  * The configuration options you can set for this module are in this section.
- * Either change them in config.h or define them on the compiler command line.
+ * Either change them in mbedtls_config.h or define them on the compiler command line.
  * \{
  */
 #ifndef MBEDTLS_SSL_COOKIE_TIMEOUT
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index 1047dbb..0f4117d 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_SSL_TICKET_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 /*
  * This implementation of the session ticket callbacks includes key
diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h
index fae96c2..96cadc4 100644
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_THREADING_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stdlib.h>
 
diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h
index 6ffc812..25db1c6 100644
--- a/include/mbedtls/timing.h
+++ b/include/mbedtls/timing.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_TIMING_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stdint.h>
 
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index 5b0c70f..773da4a 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -20,34 +20,14 @@
  *  limitations under the License.
  */
 /*
- * This set of compile-time defines and run-time variables can be used to
- * determine the version number of the mbed TLS library used.
+ * This set of run-time variables can be used to determine the version number of
+ * the Mbed TLS library used. Compile-time version defines for the same can be
+ * found in build_info.h
  */
 #ifndef MBEDTLS_VERSION_H
 #define MBEDTLS_VERSION_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-/**
- * The version number x.y.z is split into three parts.
- * Major, Minor, Patchlevel
- */
-#define MBEDTLS_VERSION_MAJOR  2
-#define MBEDTLS_VERSION_MINOR  26
-#define MBEDTLS_VERSION_PATCH  0
-
-/**
- * The single version number has the following structure:
- *    MMNNPP00
- *    Major version | Minor version | Patch version
- */
-#define MBEDTLS_VERSION_NUMBER         0x021A0000
-#define MBEDTLS_VERSION_STRING         "2.26.0"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.26.0"
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_VERSION_C)
 
@@ -90,7 +70,7 @@
  *
  * \note            only checks against defines in the sections "System
  *                  support", "mbed TLS modules" and "mbed TLS feature
- *                  support" in config.h
+ *                  support" in mbedtls_config.h
  *
  * \param feature   The string for the define to check (e.g. "MBEDTLS_AES_C")
  *
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index b7a969a..5be4286 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_X509_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/asn1.h"
 #include "mbedtls/pk.h"
diff --git a/include/mbedtls/x509_crl.h b/include/mbedtls/x509_crl.h
index 440da12..9331827 100644
--- a/include/mbedtls/x509_crl.h
+++ b/include/mbedtls/x509_crl.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_X509_CRL_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/x509.h"
 
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 340c522..49211a9 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_X509_CRT_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/x509.h"
 #include "mbedtls/x509_crl.h"
@@ -156,13 +152,33 @@
  * Security profile for certificate verification.
  *
  * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG().
+ *
+ * The fields of this structure are part of the public API and can be
+ * manipulated directly by applications. Future versions of the library may
+ * add extra fields or reorder existing fields.
+ *
+ * You can create custom profiles by starting from a copy of
+ * an existing profile, such as mbedtls_x509_crt_profile_default or
+ * mbedtls_x509_ctr_profile_none and then tune it to your needs.
+ *
+ * For example to allow SHA-224 in addition to the default:
+ *
+ *  mbedtls_x509_crt_profile my_profile = mbedtls_x509_crt_profile_default;
+ *  my_profile.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 );
+ *
+ * Or to allow only RSA-3072+ with SHA-256:
+ *
+ *  mbedtls_x509_crt_profile my_profile = mbedtls_x509_crt_profile_none;
+ *  my_profile.allowed_mds = MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 );
+ *  my_profile.allowed_pks = MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_RSA );
+ *  my_profile.rsa_min_bitlen = 3072;
  */
 typedef struct mbedtls_x509_crt_profile
 {
-    uint32_t MBEDTLS_PRIVATE(allowed_mds);       /**< MDs for signatures         */
-    uint32_t MBEDTLS_PRIVATE(allowed_pks);       /**< PK algs for signatures     */
-    uint32_t MBEDTLS_PRIVATE(allowed_curves);    /**< Elliptic curves for ECDSA  */
-    uint32_t MBEDTLS_PRIVATE(rsa_min_bitlen);    /**< Minimum size for RSA keys  */
+    uint32_t allowed_mds;       /**< MDs for signatures         */
+    uint32_t allowed_pks;       /**< PK algs for signatures     */
+    uint32_t allowed_curves;    /**< Elliptic curves for ECDSA  */
+    uint32_t rsa_min_bitlen;    /**< Minimum size for RSA keys  */
 }
 mbedtls_x509_crt_profile;
 
@@ -357,6 +373,12 @@
 extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb;
 
 /**
+ * Empty profile that allows nothing. Useful as a basis for constructing
+ * custom profiles.
+ */
+extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_none;
+
+/**
  * \brief          Parse a single DER formatted certificate and add it
  *                 to the end of the provided chained list.
  *
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index a0f1278..674f9ce 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -23,11 +23,7 @@
 #define MBEDTLS_X509_CSR_H
 #include "mbedtls/private_access.h"
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/x509.h"
 
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 3532fef..b3ef363 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -3805,7 +3805,7 @@
  * This function calculates output bytes from a key derivation algorithm and
  * compares those bytes to an expected value in constant time.
  * If you view the key derivation's output as a stream of bytes, this
- * function destructively reads the requested number of bytes from the
+ * function destructively reads the expected number of bytes from the
  * stream before comparing them.
  * The operation's capacity decreases by the number of bytes read.
  *
@@ -3824,13 +3824,13 @@
  * psa_key_derivation_abort().
  *
  * \param[in,out] operation The key derivation operation object to read from.
- * \param[in] expected_output Buffer where the output will be written.
+ * \param[in] expected_output Buffer containing the expected derivation output.
  * \param output_length     Length ot the expected output; this is also the
  *                          number of bytes that will be read.
  *
  * \retval #PSA_SUCCESS
  * \retval #PSA_ERROR_INVALID_SIGNATURE
- *         The output was read successfully, but if differs from the expected
+ *         The output was read successfully, but it differs from the expected
  *         output.
  * \retval #PSA_ERROR_NOT_PERMITTED
  *         One of the inputs was a key whose policy didn't allow
@@ -3840,7 +3840,7 @@
  *                          \p output_length bytes. Note that in this case,
  *                          the operation's capacity is set to 0, thus
  *                          subsequent calls to this function will not
- *                          succeed, even with a smaller output buffer.
+ *                          succeed, even with a smaller expected output.
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid (it must be active and completed
  *         all required input steps).
@@ -3905,7 +3905,7 @@
  *                          the length of the expected value. In this case,
  *                          the operation's capacity is set to 0, thus
  *                          subsequent calls to this function will not
- *                          succeed, even with a smaller output buffer.
+ *                          succeed, even with a smaller expected output.
  * \retval #PSA_ERROR_BAD_STATE
  *         The operation state is not valid (it must be active and completed
  *         all required input steps).
diff --git a/include/psa/crypto_builtin_primitives.h b/include/psa/crypto_builtin_primitives.h
index 20451c9..31f4aa6 100644
--- a/include/psa/crypto_builtin_primitives.h
+++ b/include/psa/crypto_builtin_primitives.h
@@ -104,7 +104,10 @@
     psa_algorithm_t MBEDTLS_PRIVATE(alg);
     uint8_t MBEDTLS_PRIVATE(iv_length);
     uint8_t MBEDTLS_PRIVATE(block_length);
-    mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher);
+    union {
+        unsigned int MBEDTLS_PRIVATE(dummy);
+        mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher);
+    } MBEDTLS_PRIVATE(ctx);
 } mbedtls_psa_cipher_operation_t;
 
 #define MBEDTLS_PSA_CIPHER_OPERATION_INIT {0, 0, 0, {0}}
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index 32ef1c2..3f95d0e 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -5,7 +5,7 @@
  */
 #if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
 /**
- * When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in config.h,
+ * When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in mbedtls_config.h,
  * this file determines which cryptographic mechanisms are enabled
  * through the PSA Cryptography API (\c psa_xxx() functions).
  *
@@ -24,7 +24,7 @@
  */
 #else
 /**
- * When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in config.h,
+ * When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in mbedtls_config.h,
  * this file is not used, and cryptographic mechanisms are supported
  * through the PSA API if and only if they are supported through the
  * mbedtls_xxx API.
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 51c0859..2c0b106 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -40,7 +40,7 @@
 /* UID for secure storage seed */
 #define PSA_CRYPTO_ITS_RANDOM_SEED_UID 0xFFFFFF52
 
-/* See config.h for definition */
+/* See mbedtls_config.h for definition */
 #if !defined(MBEDTLS_PSA_KEY_SLOT_COUNT)
 #define MBEDTLS_PSA_KEY_SLOT_COUNT 32
 #endif
diff --git a/include/psa/crypto_platform.h b/include/psa/crypto_platform.h
index d60b773..4787e44 100644
--- a/include/psa/crypto_platform.h
+++ b/include/psa/crypto_platform.h
@@ -36,11 +36,7 @@
 
 /* Include the Mbed TLS configuration file, the way Mbed TLS does it
  * in each of its header files. */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 /* Translate between classic MBEDTLS_xxx feature symbols and PSA_xxx
  * feature symbols. */
@@ -82,6 +78,18 @@
 
 #endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
 
+/*
+ * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM
+ * (Secure Partition Manager) integration which separates the code into two
+ * parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing
+ * Environment). When building for the SPE, an additional header file should be
+ * included.
+ */
+#if defined(MBEDTLS_PSA_CRYPTO_SPM)
+#define PSA_CRYPTO_SECURE 1
+#include "crypto_spe.h"
+#endif // MBEDTLS_PSA_CRYPTO_SPM
+
 #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
 /** The type of the context passed to mbedtls_psa_external_get_random().
  *
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index 15cdb41..2811c23 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -42,11 +42,7 @@
 
 /* Include the Mbed TLS configuration file, the way Mbed TLS does it
  * in each of its header files. */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
 #define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 0afdf84..381abf9 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -68,11 +68,7 @@
 
 /* Include the Mbed TLS configuration file, the way Mbed TLS does it
  * in each of its header files. */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/cmac.h"
 #include "mbedtls/gcm.h"
@@ -396,9 +392,19 @@
     return( attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) );
 }
 
-static inline void psa_set_key_usage_flags( psa_key_attributes_t *attributes,
-                                           psa_key_usage_t usage_flags )
+static inline void psa_extend_key_usage_flags( psa_key_usage_t *usage_flags )
 {
+    if( *usage_flags & PSA_KEY_USAGE_SIGN_HASH )
+        *usage_flags |= PSA_KEY_USAGE_SIGN_MESSAGE;
+
+    if( *usage_flags & PSA_KEY_USAGE_VERIFY_HASH )
+        *usage_flags |= PSA_KEY_USAGE_VERIFY_MESSAGE;
+}
+
+static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
+                                           psa_key_usage_t usage_flags)
+{
+    psa_extend_key_usage_flags( &usage_flags );
     attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
 }
 
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index 391ae60..daef941 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -835,7 +835,7 @@
  *
  * \param alg An algorithm identifier (value of type #psa_algorithm_t).
  *
- * \return 1 if \p alg is a key stretching / passowrd hashing algorithm, 0
+ * \return 1 if \p alg is a key stretching / password hashing algorithm, 0
  *         otherwise. This macro may return either 0 or 1 if \p alg is not a
  *         supported algorithm identifier.
  */
@@ -2020,6 +2020,27 @@
     (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \
      PSA_KEY_PERSISTENCE_VOLATILE)
 
+/** Whether a key lifetime indicates that the key is read-only.
+ *
+ * Read-only keys cannot be created or destroyed through the PSA Crypto API.
+ * They must be created through platform-specific means that bypass the API.
+ *
+ * Some platforms may offer ways to destroy read-only keys. For example,
+ * consider a platform with multiple levels of privilege, where a
+ * low-privilege application can use a key but is not allowed to destroy
+ * it, and the platform exposes the key to the application with a read-only
+ * lifetime. High-privilege code can destroy the key even though the
+ * application sees the key as read-only.
+ *
+ * \param lifetime      The lifetime value to query (value of type
+ *                      ::psa_key_lifetime_t).
+ *
+ * \return \c 1 if the key is read-only, otherwise \c 0.
+ */
+#define PSA_KEY_LIFETIME_IS_READ_ONLY(lifetime)  \
+    (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \
+     PSA_KEY_PERSISTENCE_READ_ONLY)
+
 /** Construct a lifetime from a persistence level and a location.
  *
  * \param persistence   The persistence level
@@ -2140,7 +2161,7 @@
  */
 static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key )
 {
-    return( ( key.MBEDTLS_PRIVATE(key_id) == 0 ) && ( key.MBEDTLS_PRIVATE(owner) == 0 ) );
+    return( key.MBEDTLS_PRIVATE(key_id) == 0 );
 }
 
 #endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
@@ -2245,12 +2266,14 @@
 /** Whether the key may be used to derive other keys or produce a password
  * hash.
  *
- * This flag allows the key to be used as the input of
- * psa_key_derivation_input_key() at the step
- * #PSA_KEY_DERIVATION_INPUT_SECRET of #PSA_KEY_DERIVATION_INPUT_PASSWORD
- * depending on the algorithm, and allows the use of
- * psa_key_derivation_output_bytes() or psa_key_derivation_output_key()
- * at the end of the operation.
+ * This flag allows the key to be used for a key derivation operation or for
+ * a key agreement operation, if otherwise permitted by by the key's type and
+ * policy.
+ *
+ * If this flag is present on all keys used in calls to
+ * psa_key_derivation_input_key() for a key derivation operation, then it
+ * permits calling psa_key_derivation_output_bytes() or
+ * psa_key_derivation_output_key() at the end of the operation.
  */
 #define PSA_KEY_USAGE_DERIVE                    ((psa_key_usage_t)0x00004000)
 
@@ -2259,14 +2282,13 @@
  *
  * This flag allows the key to be used:
  *
- * - for a key of type #PSA_KEY_TYPE_PASSWORD_HASH, as the \c key argument of
- *   psa_key_derivation_verify_key();
- * - for a key of type #PSA_KEY_TYPE_PASSWORD (or #PSA_KEY_TYPE_DERIVE), as
- *   the input to psa_key_derivation_input_key() at the step
- *   #PSA_KEY_DERIVATION_INPUT_PASSWORD (or #PSA_KEY_DERIVATION_INPUT_SECRET);
- *   then at the end of the operation use of psa_key_derivation_verify_bytes()
- *   or psa_key_derivation_verify_key() will be permitted (but not
- *   psa_key_derivation_output_xxx() unless #PSA_KEY_USAGE_DERIVE is set).
+ * This flag allows the key to be used in a key derivation operation, if
+ * otherwise permitted by by the key's type and policy.
+ *
+ * If this flag is present on all keys used in calls to
+ * psa_key_derivation_input_key() for a key derivation operation, then it
+ * permits calling psa_key_derivation_verify_bytes() or
+ * psa_key_derivation_verify_key() at the end of the operation.
  */
 #define PSA_KEY_USAGE_VERIFY_DERIVATION         ((psa_key_usage_t)0x00008000)
 
@@ -2285,11 +2307,11 @@
  *
  * The secret can also be a direct input (passed to
  * key_derivation_input_bytes()). In this case, the derivation operation
- * may not be used to derive or verify keys: the operation will only allow
- * psa_key_derivation_output_bytes() or
- * psa_key_derivation_verify_bytes() but not
- * psa_key_derivation_output_key() or
- * psa_key_derivation_verify_key().
+ * may not be used to derive keys: the operation will only allow
+ * psa_key_derivation_output_bytes(),
+ * psa_key_derivation_verify_bytes(), or
+ * psa_key_derivation_verify_key(), but not
+ * psa_key_derivation_output_key().
  */
 #define PSA_KEY_DERIVATION_INPUT_SECRET     ((psa_key_derivation_step_t)0x0101)
 
@@ -2303,11 +2325,11 @@
  *
  * The secret can also be a direct input (passed to
  * key_derivation_input_bytes()). In this case, the derivation operation
- * may not be used to derive or verify keys: the operation will only allow
- * psa_key_derivation_output_bytes() or
- * psa_key_derivation_verify_bytes(), not
- * psa_key_derivation_output_key() or
- * psa_key_derivation_verify_key().
+ * may not be used to derive keys: the operation will only allow
+ * psa_key_derivation_output_bytes(),
+ * psa_key_derivation_verify_bytes(), or
+ * psa_key_derivation_verify_key(), but not
+ * psa_key_derivation_output_key().
  */
 #define PSA_KEY_DERIVATION_INPUT_PASSWORD   ((psa_key_derivation_step_t)0x0102)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index d6ecba5..14fecff 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -82,8 +82,6 @@
     version_features.c
 )
 
-list(APPEND src_crypto ${thirdparty_src})
-
 set(src_x509
     x509.c
     x509_create.c
@@ -175,6 +173,10 @@
     set_target_properties(${mbedcrypto_static_target} PROPERTIES OUTPUT_NAME mbedcrypto)
     target_link_libraries(${mbedcrypto_static_target} PUBLIC ${libs})
 
+    if(TARGET everest)
+        target_link_libraries(${mbedcrypto_static_target} PUBLIC everest)
+    endif()
+
     add_library(${mbedx509_static_target} STATIC ${src_x509})
     set_target_properties(${mbedx509_static_target} PROPERTIES OUTPUT_NAME mbedx509)
     target_link_libraries(${mbedx509_static_target} PUBLIC ${libs} ${mbedcrypto_static_target})
@@ -189,6 +191,10 @@
     set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.26.0 SOVERSION 6)
     target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
 
+    if(TARGET everest)
+        target_link_libraries(${mbedcrypto_target} PUBLIC everest)
+    endif()
+
     add_library(${mbedx509_target} SHARED ${src_x509})
     set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.26.0 SOVERSION 1)
     target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
@@ -205,15 +211,14 @@
     # /library needs to be listed explicitly when building .c files outside
     # of /library (which currently means: under /3rdparty).
     target_include_directories(${target}
-        PUBLIC ${MBEDTLS_DIR}/include/
-        PUBLIC ${thirdparty_inc_public}
-        PRIVATE ${MBEDTLS_DIR}/library/
-        PRIVATE ${thirdparty_inc})
-    target_compile_definitions(${target}
-        PRIVATE ${thirdparty_def})
-    install(TARGETS ${target}
-            DESTINATION ${LIB_INSTALL_DIR}
-            PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+        PUBLIC $<BUILD_INTERFACE:${MBEDTLS_DIR}/include/>
+               $<INSTALL_INTERFACE:include/>
+        PRIVATE ${MBEDTLS_DIR}/library/)
+    install(
+        TARGETS ${target}
+        EXPORT MbedTLSTargets
+        DESTINATION ${LIB_INSTALL_DIR}
+        PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
 endforeach(target)
 
 set(lib_target "${MBEDTLS_TARGET_PREFIX}lib")
diff --git a/library/Makefile b/library/Makefile
index 62fd997..3f54bac 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -1,5 +1,5 @@
 
-# Also see "include/mbedtls/config.h"
+# Also see "include/mbedtls/mbedtls_config.h"
 
 CFLAGS	?= -O2
 WARNING_CFLAGS ?=  -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
@@ -281,12 +281,12 @@
 
 version_features.c: ../scripts/generate_features.pl
 version_features.c: ../scripts/data_files/version_features.fmt
-## The generated file only depends on the options that are present in config.h,
+## The generated file only depends on the options that are present in mbedtls_config.h,
 ## not on which options are set. To avoid regenerating this file all the time
-## when switching between configurations, don't declare config.h as a
+## when switching between configurations, don't declare mbedtls_config.h as a
 ## dependency. Remove this file from your working tree if you've just added or
-## removed an option in config.h.
-#version_features.c: ../include/mbedtls/config.h
+## removed an option in mbedtls_config.h.
+#version_features.c: ../include/mbedtls/mbedtls_config.h
 version_features.c:
 	echo "  Gen   $@"
 	$(PERL) ../scripts/generate_features.pl
diff --git a/library/aesni.h b/library/aesni.h
index c1d22f5..3359cfe 100644
--- a/library/aesni.h
+++ b/library/aesni.h
@@ -25,11 +25,7 @@
 #ifndef MBEDTLS_AESNI_H
 #define MBEDTLS_AESNI_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/aes.h"
 
diff --git a/library/bignum.c b/library/bignum.c
index 967d2a7..dfc78c9 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -203,7 +203,13 @@
 }
 
 /*
- * Copy the contents of Y into X
+ * Copy the contents of Y into X.
+ *
+ * This function is not constant-time. Leading zeros in Y may be removed.
+ *
+ * Ensure that X does not shrink. This is not guaranteed by the public API,
+ * but some code in the bignum module relies on this property, for example
+ * in mbedtls_mpi_exp_mod().
  */
 int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
 {
@@ -217,7 +223,11 @@
 
     if( Y->n == 0 )
     {
-        mbedtls_mpi_free( X );
+        if( X->n != 0 )
+        {
+            X->s = 1;
+            memset( X->p, 0, X->n * ciL );
+        }
         return( 0 );
     }
 
@@ -575,6 +585,12 @@
 
     mbedtls_mpi_init( &T );
 
+    if( s[0] == 0 )
+    {
+        mbedtls_mpi_free( X );
+        return( 0 );
+    }
+
     if( s[0] == '-' )
     {
         ++s;
@@ -1698,6 +1714,7 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t i, j;
     mbedtls_mpi TA, TB;
+    int result_is_zero = 0;
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( A != NULL );
     MPI_VALIDATE_RET( B != NULL );
@@ -1710,10 +1727,14 @@
     for( i = A->n; i > 0; i-- )
         if( A->p[i - 1] != 0 )
             break;
+    if( i == 0 )
+        result_is_zero = 1;
 
     for( j = B->n; j > 0; j-- )
         if( B->p[j - 1] != 0 )
             break;
+    if( j == 0 )
+        result_is_zero = 1;
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
@@ -1721,7 +1742,14 @@
     for( ; j > 0; j-- )
         mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
 
-    X->s = A->s * B->s;
+    /* If the result is 0, we don't shortcut the operation, which reduces
+     * but does not eliminate side channels leaking the zero-ness. We do
+     * need to take care to set the sign bit properly since the library does
+     * not fully support an MPI object with a value of 0 and s == -1. */
+    if( result_is_zero )
+        X->s = 1;
+    else
+        X->s = A->s * B->s;
 
 cleanup:
 
@@ -2314,6 +2342,11 @@
 #endif
 
     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[1],  j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
@@ -2348,10 +2381,18 @@
      * W[1] = A * R^2 * R^-1 mod N = A * R mod N
      */
     if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
+    {
         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
+        /* This should be a no-op because W[1] is already that large before
+         * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
+         * in mpi_montmul() below, so let's make sure. */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n + 1 ) );
+    }
     else
         MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
 
+    /* Note that this is safe because W[1] always has at least N->n limbs
+     * (it grew above and was preserved by mbedtls_mpi_copy()). */
     mpi_montmul( &W[1], &RR, N, mm, &T );
 
     /*
@@ -2509,19 +2550,67 @@
     lz = mbedtls_mpi_lsb( &TA );
     lzt = mbedtls_mpi_lsb( &TB );
 
+    /* The loop below gives the correct result when A==0 but not when B==0.
+     * So have a special case for B==0. Leverage the fact that we just
+     * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
+     * slightly more efficient than cmp_int(). */
+    if( lzt == 0 && mbedtls_mpi_get_bit( &TB, 0 ) == 0 )
+    {
+        ret = mbedtls_mpi_copy( G, A );
+        goto cleanup;
+    }
+
     if( lzt < lz )
         lz = lzt;
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
-
     TA.s = TB.s = 1;
 
+    /* We mostly follow the procedure described in HAC 14.54, but with some
+     * minor differences:
+     * - Sequences of multiplications or divisions by 2 are grouped into a
+     *   single shift operation.
+     * - The procedure in HAC assumes that 0 < TB <= TA.
+     *     - The condition TB <= TA is not actually necessary for correctness.
+     *       TA and TB have symmetric roles except for the loop termination
+     *       condition, and the shifts at the beginning of the loop body
+     *       remove any significance from the ordering of TA vs TB before
+     *       the shifts.
+     *     - If TA = 0, the loop goes through 0 iterations and the result is
+     *       correctly TB.
+     *     - The case TB = 0 was short-circuited above.
+     *
+     * For the correctness proof below, decompose the original values of
+     * A and B as
+     *   A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1
+     *   B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1
+     * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
+     * and gcd(A',B') is odd or 0.
+     *
+     * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
+     * The code maintains the following invariant:
+     *     gcd(A,B) = 2^k * gcd(TA,TB) for some k   (I)
+     */
+
+    /* Proof that the loop terminates:
+     * At each iteration, either the right-shift by 1 is made on a nonzero
+     * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases
+     * by at least 1, or the right-shift by 1 is made on zero and then
+     * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted
+     * since in that case TB is calculated from TB-TA with the condition TB>TA).
+     */
     while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
     {
+        /* Divisions by 2 preserve the invariant (I). */
         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
 
+        /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,
+         * TA-TB is even so the division by 2 has an integer result.
+         * Invariant (I) is preserved since any odd divisor of both TA and TB
+         * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
+         * also divides TB, and any odd divisior of both TB and |TA-TB|/2 also
+         * divides TA.
+         */
         if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
         {
             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
@@ -2532,8 +2621,18 @@
             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
             MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
         }
+        /* Note that one of TA or TB is still odd. */
     }
 
+    /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.
+     * At the loop exit, TA = 0, so gcd(TA,TB) = TB.
+     * - If there was at least one loop iteration, then one of TA or TB is odd,
+     *   and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,
+     *   lz = min(a,b) so gcd(A,B) = 2^lz * TB.
+     * - If there was no loop iteration, then A was 0, and gcd(A,B) = B.
+     *   In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.
+     */
+
     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
 
diff --git a/library/bn_mul.h b/library/bn_mul.h
index a0fa677..6ddffc4 100644
--- a/library/bn_mul.h
+++ b/library/bn_mul.h
@@ -36,11 +36,7 @@
 #ifndef MBEDTLS_BN_MUL_H
 #define MBEDTLS_BN_MUL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/bignum.h"
 
diff --git a/library/cipher.c b/library/cipher.c
index 4f56b52..546cace 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1109,9 +1109,14 @@
 
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+    {
+        size_t output_length;
+        /* The code here doesn't yet support alternative implementations
+         * that can delay up to a block of output. */
         return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
-                                    NULL, 0,
+                                    NULL, 0, &output_length,
                                     tag, tag_len ) );
+    }
 #endif
 
 #if defined(MBEDTLS_CHACHAPOLY_C)
@@ -1158,12 +1163,16 @@
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
+        size_t output_length;
+        /* The code here doesn't yet support alternative implementations
+         * that can delay up to a block of output. */
+
         if( tag_len > sizeof( check_tag ) )
             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
         if( 0 != ( ret = mbedtls_gcm_finish(
                        (mbedtls_gcm_context *) ctx->cipher_ctx,
-                       NULL, 0,
+                       NULL, 0, &output_length,
                        check_tag, tag_len ) ) )
         {
             return( ret );
diff --git a/library/cipher_wrap.h b/library/cipher_wrap.h
index 5635982..90563d8 100644
--- a/library/cipher_wrap.h
+++ b/library/cipher_wrap.h
@@ -24,11 +24,7 @@
 #ifndef MBEDTLS_CIPHER_WRAP_H
 #define MBEDTLS_CIPHER_WRAP_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/cipher.h"
 
diff --git a/library/common.h b/library/common.h
index 0f61f94..a2c8a1e 100644
--- a/library/common.h
+++ b/library/common.h
@@ -23,11 +23,7 @@
 #ifndef MBEDTLS_LIBRARY_COMMON_H
 #define MBEDTLS_LIBRARY_COMMON_H
 
-#if defined(MBEDTLS_CONFIG_FILE)
-#include MBEDTLS_CONFIG_FILE
-#else
-#include "mbedtls/config.h"
-#endif
+#include "mbedtls/build_info.h"
 
 /** Helper to define a function as static except when building invasive tests.
  *
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 9220633..0b612ce 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -648,7 +648,8 @@
  * Convert a signature (given by context) to ASN.1
  */
 static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
-                                    unsigned char *sig, size_t *slen )
+                                    unsigned char *sig, size_t sig_size,
+                                    size_t *slen )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = {0};
@@ -662,6 +663,9 @@
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
 
+    if( len > sig_size )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
     memcpy( sig, p, len );
     *slen = len;
 
@@ -674,7 +678,7 @@
 int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
                            mbedtls_md_type_t md_alg,
                            const unsigned char *hash, size_t hlen,
-                           unsigned char *sig, size_t *slen,
+                           unsigned char *sig, size_t sig_size, size_t *slen,
                            int (*f_rng)(void *, unsigned char *, size_t),
                            void *p_rng,
                            mbedtls_ecdsa_restart_ctx *rs_ctx )
@@ -712,7 +716,7 @@
 #endif /* MBEDTLS_ECDSA_SIGN_ALT */
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
-    MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
+    MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, sig_size, slen ) );
 
 cleanup:
     mbedtls_mpi_free( &r );
@@ -727,7 +731,7 @@
 int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
                                  mbedtls_md_type_t md_alg,
                                  const unsigned char *hash, size_t hlen,
-                                 unsigned char *sig, size_t *slen,
+                                 unsigned char *sig, size_t sig_size, size_t *slen,
                                  int (*f_rng)(void *, unsigned char *, size_t),
                                  void *p_rng )
 {
@@ -736,7 +740,8 @@
     ECDSA_VALIDATE_RET( sig  != NULL );
     ECDSA_VALIDATE_RET( slen != NULL );
     return( mbedtls_ecdsa_write_signature_restartable(
-                ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
+                ctx, md_alg, hash, hlen, sig, sig_size, slen,
+                f_rng, p_rng, NULL ) );
 }
 
 /*
diff --git a/library/ecp_internal_alt.h b/library/ecp_internal_alt.h
index 9b157ea..a7544aa 100644
--- a/library/ecp_internal_alt.h
+++ b/library/ecp_internal_alt.h
@@ -59,11 +59,7 @@
 #ifndef MBEDTLS_ECP_INTERNAL_H
 #define MBEDTLS_ECP_INTERNAL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
 
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index bccc034..058c307 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -44,7 +44,7 @@
 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
     !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
     !defined(__HAIKU__) && !defined(__midipix__)
-#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
+#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in mbedtls_config.h"
 #endif
 
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
diff --git a/library/entropy_poll.h b/library/entropy_poll.h
index bf26889..aef1a09 100644
--- a/library/entropy_poll.h
+++ b/library/entropy_poll.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_ENTROPY_POLL_H
 #define MBEDTLS_ENTROPY_POLL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
@@ -55,7 +51,7 @@
  * \brief           Entropy poll callback for a hardware source
  *
  * \warning         This is not provided by mbed TLS!
- *                  See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h.
+ *                  See \c MBEDTLS_ENTROPY_HARDWARE_ALT in mbedtls_config.h.
  *
  * \note            This must accept NULL as its first argument.
  */
diff --git a/library/gcm.c b/library/gcm.c
index 2bd9071..835b1b2 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -281,7 +281,7 @@
     GCM_VALIDATE_RET( ctx != NULL );
     GCM_VALIDATE_RET( iv != NULL );
 
-    /* IV is are limited to 2^64 bits, so 2^61 bytes */
+    /* IV is limited to 2^64 bits, so 2^61 bytes */
     /* IV is not allowed to be zero length */
     if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -332,36 +332,72 @@
     return( 0 );
 }
 
-
+/**
+ * mbedtls_gcm_context::buf contains the partial state of the computation of
+ * the authentication tag.
+ * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
+ * different stages of the computation:
+ *     * len == 0 && add_len == 0:      initial state
+ *     * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
+ *                                      a partial block of AD that has been
+ *                                      xored in but not yet multiplied in.
+ *     * len == 0 && add_len % 16 == 0: the authentication tag is correct if
+ *                                      the data ends now.
+ *     * len % 16 != 0:                 the first `len % 16` bytes have
+ *                                      a partial block of ciphertext that has
+ *                                      been xored in but not yet multiplied in.
+ *     * len > 0 && len % 16 == 0:      the authentication tag is correct if
+ *                                      the data ends now.
+ */
 int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
                            const unsigned char *add, size_t add_len )
 {
     const unsigned char *p;
-    size_t use_len, i;
+    size_t use_len, i, offset;
 
     GCM_VALIDATE_RET( add_len == 0 || add != NULL );
 
-    /* IV is are limited to 2^64 bits, so 2^61 bytes */
+    /* IV is limited to 2^64 bits, so 2^61 bytes */
     if( (uint64_t) add_len >> 61 != 0 )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
 
-    /* Calling update_ad multiple times is not yet supported */
-    if( ctx->add_len != 0 )
-        return( MBEDTLS_ERR_GCM_BAD_INPUT );
-
-    ctx->add_len = add_len;
+    offset = ctx->add_len % 16;
     p = add;
-    while( add_len > 0 )
+
+    if( offset != 0 )
     {
-        use_len = ( add_len < 16 ) ? add_len : 16;
+        use_len = 16 - offset;
+        if( use_len > add_len )
+            use_len = add_len;
 
         for( i = 0; i < use_len; i++ )
+            ctx->buf[i+offset] ^= p[i];
+
+        if( offset + use_len == 16 )
+            gcm_mult( ctx, ctx->buf, ctx->buf );
+
+        ctx->add_len += use_len;
+        add_len -= use_len;
+        p += use_len;
+    }
+
+    ctx->add_len += add_len;
+
+    while( add_len >= 16 )
+    {
+        for( i = 0; i < 16; i++ )
             ctx->buf[i] ^= p[i];
 
         gcm_mult( ctx, ctx->buf, ctx->buf );
 
-        add_len -= use_len;
-        p += use_len;
+        add_len -= 16;
+        p += 16;
+    }
+
+    if( add_len > 0 )
+    {
+        for( i = 0; i < add_len; i++ )
+            ctx->buf[i] ^= p[i];
     }
 
     return( 0 );
@@ -423,7 +459,9 @@
     *output_length = input_length;
 
     /* Exit early if input_length==0 so that we don't do any pointer arithmetic
-     * on a potentially null pointer. */
+     * on a potentially null pointer.
+     * Returning early also means that the last partial block of AD remains
+     * untouched for mbedtls_gcm_finish */
     if( input_length == 0 )
         return( 0 );
 
@@ -442,6 +480,11 @@
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
     }
 
+    if( ctx->len == 0 && ctx->add_len % 16 != 0 )
+    {
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+    }
+
     offset = ctx->len % 16;
     if( offset != 0 )
     {
@@ -489,6 +532,7 @@
 
 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
                         unsigned char *output, size_t output_size,
+                        size_t *output_length,
                         unsigned char *tag, size_t tag_len )
 {
     unsigned char work_buf[16];
@@ -503,10 +547,16 @@
      * for the sake of alternative implementations. */
     (void) output;
     (void) output_size;
+    *output_length = 0;
 
     orig_len = ctx->len * 8;
     orig_add_len = ctx->add_len * 8;
 
+    if( ctx->len == 0 && ctx->add_len % 16 != 0 )
+    {
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+    }
+
     if( tag_len > 16 || tag_len < 4 )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
 
@@ -568,7 +618,7 @@
                                     output, length, &olen ) ) != 0 )
         return( ret );
 
-    if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
+    if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
         return( ret );
 
     return( 0 );
@@ -1020,7 +1070,7 @@
                     goto exit;
             }
 
-            ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
+            ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
             if( ret != 0 )
                 goto exit;
 
@@ -1092,7 +1142,7 @@
                     goto exit;
             }
 
-            ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
+            ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
             if( ret != 0 )
                 goto exit;
 
diff --git a/library/md_wrap.h b/library/md_wrap.h
index cfd418a..90c7957 100644
--- a/library/md_wrap.h
+++ b/library/md_wrap.h
@@ -26,11 +26,7 @@
 #ifndef MBEDTLS_MD_WRAP_H
 #define MBEDTLS_MD_WRAP_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/md.h"
 
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 5fbe1f7..17a9e4a 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -18,7 +18,7 @@
  */
 
 /* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
- * be set before config.h, which pulls in glibc's features.h indirectly.
+ * be set before mbedtls_config.h, which pulls in glibc's features.h indirectly.
  * Harmless on other platforms. */
 #ifndef _POSIX_C_SOURCE
 #define _POSIX_C_SOURCE 200112L
@@ -34,7 +34,7 @@
 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
     !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
     !defined(__HAIKU__) && !defined(__midipix__)
-#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
+#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in mbedtls_config.h"
 #endif
 
 #if defined(MBEDTLS_PLATFORM_C)
diff --git a/library/padlock.h b/library/padlock.h
index 4f4e400..1506ee0 100644
--- a/library/padlock.h
+++ b/library/padlock.h
@@ -26,11 +26,7 @@
 #ifndef MBEDTLS_PADLOCK_H
 #define MBEDTLS_PADLOCK_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/aes.h"
 
diff --git a/library/pk.c b/library/pk.c
index 275d34b..ea4869c 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -396,7 +396,7 @@
 int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
              mbedtls_md_type_t md_alg,
              const unsigned char *hash, size_t hash_len,
-             unsigned char *sig, size_t *sig_len,
+             unsigned char *sig, size_t sig_size, size_t *sig_len,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
              mbedtls_pk_restart_ctx *rs_ctx )
 {
@@ -421,7 +421,9 @@
             return( ret );
 
         ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
-                hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
+                                          hash, hash_len,
+                                          sig, sig_size, sig_len,
+                                          f_rng, p_rng, rs_ctx->rs_ctx );
 
         if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
             mbedtls_pk_restart_free( rs_ctx );
@@ -435,8 +437,10 @@
     if( ctx->pk_info->sign_func == NULL )
         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
 
-    return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
-                                     sig, sig_len, f_rng, p_rng ) );
+    return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg,
+                                     hash, hash_len,
+                                     sig, sig_size, sig_len,
+                                     f_rng, p_rng ) );
 }
 
 /*
@@ -444,11 +448,12 @@
  */
 int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
              const unsigned char *hash, size_t hash_len,
-             unsigned char *sig, size_t *sig_len,
+             unsigned char *sig, size_t sig_size, size_t *sig_len,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
-                                         sig, sig_len, f_rng, p_rng, NULL ) );
+                                         sig, sig_size, sig_len,
+                                         f_rng, p_rng, NULL ) );
 }
 
 /*
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 864e495..80c0aad 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -108,7 +108,7 @@
 
 static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
@@ -119,6 +119,8 @@
 #endif /* SIZE_MAX > UINT_MAX */
 
     *sig_len = mbedtls_rsa_get_len( rsa );
+    if( sig_size < *sig_len )
+        return( MBEDTLS_ERR_PK_BUFFER_TOO_SMALL );
 
     return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng,
                                     md_alg, (unsigned int) hash_len,
@@ -247,7 +249,7 @@
 
 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
@@ -269,7 +271,7 @@
 
 static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -278,7 +280,8 @@
     mbedtls_ecdsa_init( &ecdsa );
 
     if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
-        ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
+        ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len,
+                               sig, sig_size, sig_len,
                                f_rng, p_rng );
 
     mbedtls_ecdsa_free( &ecdsa );
@@ -295,7 +298,7 @@
 
 static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
                    void *rs_ctx );
 
@@ -367,7 +370,7 @@
 
 static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
                        void *rs_ctx )
 {
@@ -383,7 +386,7 @@
         MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
 
     MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,
-                                         hash, hash_len, sig, sig_len,
+                                         hash, hash_len, sig, sig_size, sig_len,
                                          f_rng, p_rng, &rs->ecdsa_rs ) );
 
 cleanup:
@@ -652,11 +655,13 @@
 
 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
-                md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
+                                           md_alg, hash, hash_len,
+                                           sig, sig_size, sig_len,
+                                           f_rng, p_rng ) );
 }
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -681,13 +686,13 @@
 
 static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
                    void *rs_ctx )
 {
     return( mbedtls_ecdsa_write_signature_restartable(
                 (mbedtls_ecdsa_context *) ctx,
-                md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
+                md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng,
                 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
 
 }
@@ -770,7 +775,7 @@
 
 static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
@@ -783,6 +788,8 @@
     *sig_len = rsa_alt->key_len_func( rsa_alt->key );
     if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+    if( *sig_len > sig_size )
+        return( MBEDTLS_ERR_PK_BUFFER_TOO_SMALL );
 
     return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng,
                 md_alg, (unsigned int) hash_len, hash, sig ) );
@@ -822,7 +829,8 @@
 
     if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
                                    hash, sizeof( hash ),
-                                   sig, &sig_len, f_rng, p_rng ) ) != 0 )
+                                   sig, sizeof( sig ), &sig_len,
+                                   f_rng, p_rng ) ) != 0 )
     {
         return( ret );
     }
@@ -1010,7 +1018,7 @@
 
 static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
 #if !defined(MBEDTLS_ECDSA_C)
@@ -1019,41 +1027,28 @@
     ((void) hash);
     ((void) hash_len);
     ((void) sig);
+    ((void) sig_size);
     ((void) sig_len);
     ((void) f_rng);
     ((void) p_rng);
     return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
 #else /* !MBEDTLS_ECDSA_C */
     const psa_key_id_t *key = (const psa_key_id_t *) ctx;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
-    size_t buf_len;
     psa_status_t status;
 
     /* PSA has its own RNG */
     (void) f_rng;
     (void) p_rng;
 
-    /* PSA needs an output buffer of known size, but our API doesn't provide
-     * that information. Assume that the buffer is large enough for a
-     * maximal-length signature with that key (otherwise the application is
-     * buggy anyway). */
-    status = psa_get_key_attributes( *key, &attributes );
-    if( status != PSA_SUCCESS )
-        return( mbedtls_psa_err_translate_pk( status ) );
-    buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( psa_get_key_bits( &attributes ) );
-    psa_reset_key_attributes( &attributes );
-    if( buf_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )
-        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
-
     /* make the signature */
     status = psa_sign_hash( *key, alg, hash, hash_len,
-                            sig, buf_len, sig_len );
+                            sig, sig_size, sig_len );
     if( status != PSA_SUCCESS )
         return( mbedtls_psa_err_translate_pk( status ) );
 
     /* transcode it to ASN.1 sequence */
-    return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) );
+    return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, sig_size ) );
 #endif /* !MBEDTLS_ECDSA_C */
 }
 
diff --git a/library/pk_wrap.h b/library/pk_wrap.h
index b2db637..6f5addf 100644
--- a/library/pk_wrap.h
+++ b/library/pk_wrap.h
@@ -23,11 +23,7 @@
 #ifndef MBEDTLS_PK_WRAP_H
 #define MBEDTLS_PK_WRAP_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/pk.h"
 
@@ -53,7 +49,7 @@
     /** Make signature */
     int (*sign_func)( void *ctx, mbedtls_md_type_t md_alg,
                       const unsigned char *hash, size_t hash_len,
-                      unsigned char *sig, size_t *sig_len,
+                      unsigned char *sig, size_t sig_size, size_t *sig_len,
                       int (*f_rng)(void *, unsigned char *, size_t),
                       void *p_rng );
 
@@ -67,7 +63,7 @@
     /** Make signature (restartable) */
     int (*sign_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
                          const unsigned char *hash, size_t hash_len,
-                         unsigned char *sig, size_t *sig_len,
+                         unsigned char *sig, size_t sig_size, size_t *sig_len,
                          int (*f_rng)(void *, unsigned char *, size_t),
                          void *p_rng, void *rs_ctx );
 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
diff --git a/library/platform_util.c b/library/platform_util.c
index 98fe5de..4e97e4d 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -20,7 +20,7 @@
 
 /*
  * Ensure gmtime_r is available even with -std=c99; must be defined before
- * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ * mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms.
  */
 #if !defined(_POSIX_C_SOURCE)
 #define _POSIX_C_SOURCE 200112L
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index a0acc3f..6e73d12 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -26,7 +26,6 @@
 #include "check_crypto_config.h"
 #endif
 
-#include "psa_crypto_service_integration.h"
 #include "psa/crypto.h"
 
 #include "psa_crypto_cipher.h"
@@ -267,6 +266,8 @@
             return( PSA_ERROR_NOT_SUPPORTED );
         case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
             return( PSA_ERROR_INVALID_SIGNATURE );
+        case MBEDTLS_ERR_PK_BUFFER_TOO_SMALL:
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
 
         case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
             return( PSA_ERROR_HARDWARE_FAILURE );
@@ -1052,6 +1053,17 @@
        return( PSA_ERROR_GENERIC_ERROR );
     }
 
+    if( PSA_KEY_LIFETIME_IS_READ_ONLY( slot->attr.lifetime ) )
+    {
+        /* Refuse the destruction of a read-only key (which may or may not work
+         * if we attempt it, depending on whether the key is merely read-only
+         * by policy or actually physically read-only).
+         * Just do the best we can, which is to wipe the copy in memory
+         * (done in this function's cleanup code). */
+        overall_status = PSA_ERROR_NOT_PERMITTED;
+        goto exit;
+    }
+
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     driver = psa_get_se_driver_entry( slot->attr.lifetime );
     if( driver != NULL )
@@ -1113,12 +1125,10 @@
     }
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
 exit:
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
     status = psa_wipe_key_slot( slot );
     /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
-    if( overall_status == PSA_SUCCESS )
+    if( status != PSA_SUCCESS )
         overall_status = status;
     return( overall_status );
 }
@@ -2080,34 +2090,54 @@
 psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
                              psa_algorithm_t alg )
 {
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
     /* A context must be freshly initialized before it can be set up. */
     if( operation->id != 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( !PSA_ALG_IS_HASH( alg ) )
-        return( PSA_ERROR_INVALID_ARGUMENT );
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
 
     /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
      * directly zeroes the int-sized dummy member of the context union. */
     memset( &operation->ctx, 0, sizeof( operation->ctx ) );
 
-    return( psa_driver_wrapper_hash_setup( operation, alg ) );
+    status = psa_driver_wrapper_hash_setup( operation, alg );
+
+exit:
+    if( status != PSA_SUCCESS )
+        psa_hash_abort( operation );
+
+    return status;
 }
 
 psa_status_t psa_hash_update( psa_hash_operation_t *operation,
                               const uint8_t *input,
                               size_t input_length )
 {
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
     if( operation->id == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     /* Don't require hash implementations to behave correctly on a
      * zero-length input, which may have an invalid pointer. */
     if( input_length == 0 )
         return( PSA_SUCCESS );
 
-    psa_status_t status = psa_driver_wrapper_hash_update( operation,
-                                                          input, input_length );
+    status = psa_driver_wrapper_hash_update( operation, input, input_length );
+
+exit:
     if( status != PSA_SUCCESS )
         psa_hash_abort( operation );
 
@@ -2139,13 +2169,24 @@
                             operation,
                             actual_hash, sizeof( actual_hash ),
                             &actual_hash_length );
+
     if( status != PSA_SUCCESS )
-        return( status );
+        goto exit;
+
     if( actual_hash_length != hash_length )
-        return( PSA_ERROR_INVALID_SIGNATURE );
+    {
+        status = PSA_ERROR_INVALID_SIGNATURE;
+        goto exit;
+    }
+
     if( mbedtls_psa_safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
-        return( PSA_ERROR_INVALID_SIGNATURE );
-    return( PSA_SUCCESS );
+        status = PSA_ERROR_INVALID_SIGNATURE;
+
+exit:
+    if( status != PSA_SUCCESS )
+        psa_hash_abort(operation);
+
+    return( status );
 }
 
 psa_status_t psa_hash_compute( psa_algorithm_t alg,
@@ -2267,11 +2308,14 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
-    psa_key_slot_t *slot;
+    psa_key_slot_t *slot = NULL;
 
     /* A context must be freshly initialized before it can be set up. */
     if( operation->id != 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     status = psa_get_and_lock_key_slot_with_policy(
                  key,
@@ -2279,7 +2323,7 @@
                  is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH,
                  alg );
     if( status != PSA_SUCCESS )
-        return( status );
+        goto exit;
 
     psa_key_attributes_t attributes = {
         .core = slot->attr
@@ -2360,29 +2404,37 @@
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
 
-    /* Set the output length and content to a safe default, such that in
-     * case the caller misses an error check, the output would be an
-     * unachievable MAC. */
-    *mac_length = mac_size;
-
     if( operation->id == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( ! operation->is_sign )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     /* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL)
      * once all the error checks are done. */
     if( operation->mac_size == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( mac_size < operation->mac_size )
-        return( PSA_ERROR_BUFFER_TOO_SMALL );
+    {
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        goto exit;
+    }
 
     status = psa_driver_wrapper_mac_sign_finish( operation,
                                                  mac, operation->mac_size,
                                                  mac_length );
 
+exit:
     /* In case of success, set the potential excess room in the output buffer
      * to an invalid value, to avoid potentially leaking a longer MAC.
      * In case of error, set the output length and content to a safe default,
@@ -2412,21 +2464,27 @@
     psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
 
     if( operation->id == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( operation->is_sign )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( operation->mac_size != mac_length )
     {
         status = PSA_ERROR_INVALID_SIGNATURE;
-        goto cleanup;
+        goto exit;
     }
 
     status = psa_driver_wrapper_mac_verify_finish( operation,
                                                    mac, mac_length );
 
-cleanup:
+exit:
     abort_status = psa_mac_abort( operation );
 
     return( status == PSA_SUCCESS ? abort_status : status );
@@ -3176,20 +3234,24 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
-    psa_key_slot_t *slot;
+    psa_key_slot_t *slot = NULL;
     psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
                               PSA_KEY_USAGE_ENCRYPT :
                               PSA_KEY_USAGE_DECRYPT );
 
     /* A context must be freshly initialized before it can be set up. */
     if( operation->id != 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
-    /* The requested algorithm must be one that can be processed by cipher. */
     if( ! PSA_ALG_IS_CIPHER( alg ) )
-        return( PSA_ERROR_INVALID_ARGUMENT );
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
 
-    /* Fetch key material from key storage. */
     status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg );
     if( status != PSA_SUCCESS )
         goto exit;
@@ -3257,12 +3319,14 @@
 
     if( operation->id == 0 )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
 
     if( operation->iv_set || ! operation->iv_required )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
 
     if( iv_size < operation->default_iv_length )
@@ -3298,18 +3362,28 @@
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
 
     if( operation->id == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( operation->iv_set || ! operation->iv_required )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( iv_length > PSA_CIPHER_IV_MAX_SIZE )
-        return( PSA_ERROR_INVALID_ARGUMENT );
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
 
     status = psa_driver_wrapper_cipher_set_iv( operation,
                                                iv,
                                                iv_length );
 
+exit:
     if( status == PSA_SUCCESS )
         operation->iv_set = 1;
     else
@@ -3328,11 +3402,14 @@
 
     if( operation->id == 0 )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
+
     if( operation->iv_required && ! operation->iv_set )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
 
     status = psa_driver_wrapper_cipher_update( operation,
@@ -3341,6 +3418,8 @@
                                                output,
                                                output_size,
                                                output_length );
+
+exit:
     if( status != PSA_SUCCESS )
         psa_cipher_abort( operation );
 
@@ -3356,17 +3435,22 @@
 
     if( operation->id == 0 )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
+
     if( operation->iv_required && ! operation->iv_set )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
 
     status = psa_driver_wrapper_cipher_finish( operation,
                                                output,
                                                output_size,
                                                output_length );
+
+exit:
     if( status == PSA_SUCCESS )
         return( psa_cipher_abort( operation ) );
     else
@@ -3397,6 +3481,107 @@
     return( PSA_SUCCESS );
 }
 
+psa_status_t psa_cipher_encrypt( mbedtls_svc_key_id_t key,
+                                 psa_algorithm_t alg,
+                                 const uint8_t *input,
+                                 size_t input_length,
+                                 uint8_t *output,
+                                 size_t output_size,
+                                 size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot;
+    psa_key_type_t key_type;
+    size_t iv_length;
+
+    *output_length = 0;
+
+    if( ! PSA_ALG_IS_CIPHER( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    status = psa_get_and_lock_key_slot_with_policy( key, &slot,
+                                                    PSA_KEY_USAGE_ENCRYPT,
+                                                    alg );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    psa_key_attributes_t attributes = {
+      .core = slot->attr
+    };
+
+    key_type = slot->attr.type;
+    iv_length = PSA_CIPHER_IV_LENGTH( key_type, alg );
+
+    if( iv_length > 0 )
+    {
+        if( output_size < iv_length )
+        {
+            status = PSA_ERROR_BUFFER_TOO_SMALL;
+            goto exit;
+        }
+
+        status = psa_generate_random( output, iv_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
+
+    status = psa_driver_wrapper_cipher_encrypt(
+        &attributes, slot->key.data, slot->key.bytes,
+        alg, input, input_length,
+        output, output_size, output_length );
+
+exit:
+    unlock_status = psa_unlock_key_slot( slot );
+
+    return( ( status == PSA_SUCCESS ) ? unlock_status : status );
+}
+
+psa_status_t psa_cipher_decrypt( mbedtls_svc_key_id_t key,
+                                 psa_algorithm_t alg,
+                                 const uint8_t *input,
+                                 size_t input_length,
+                                 uint8_t *output,
+                                 size_t output_size,
+                                 size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot;
+
+    *output_length = 0;
+
+    if( ! PSA_ALG_IS_CIPHER( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    status = psa_get_and_lock_key_slot_with_policy( key, &slot,
+                                                    PSA_KEY_USAGE_DECRYPT,
+                                                    alg );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    psa_key_attributes_t attributes = {
+      .core = slot->attr
+    };
+
+    if( input_length < PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ) )
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    status = psa_driver_wrapper_cipher_decrypt(
+        &attributes, slot->key.data, slot->key.bytes,
+        alg, input, input_length,
+        output, output_size, output_length );
+
+exit:
+    unlock_status = psa_unlock_key_slot( slot );
+
+    return( ( status == PSA_SUCCESS ) ? unlock_status : status );
+}
+
+
 /****************************************************************/
 /* AEAD */
 /****************************************************************/
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index a65e884..d8c722b 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -160,9 +160,7 @@
 
     (void)key_buffer_size;
 
-    /* Proceed with initializing an mbed TLS cipher context if no driver is
-     * available for the given algorithm & key. */
-    mbedtls_cipher_init( &operation->cipher );
+    mbedtls_cipher_init( &operation->ctx.cipher );
 
     operation->alg = alg;
     key_bits = attributes->core.bits;
@@ -171,7 +169,7 @@
     if( cipher_info == NULL )
         return( PSA_ERROR_NOT_SUPPORTED );
 
-    ret = mbedtls_cipher_setup( &operation->cipher, cipher_info );
+    ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
     if( ret != 0 )
         goto exit;
 
@@ -182,14 +180,14 @@
         uint8_t keys[24];
         memcpy( keys, key_buffer, 16 );
         memcpy( keys + 16, key_buffer, 8 );
-        ret = mbedtls_cipher_setkey( &operation->cipher,
+        ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
                                      keys,
                                      192, cipher_operation );
     }
     else
 #endif
     {
-        ret = mbedtls_cipher_setkey( &operation->cipher, key_buffer,
+        ret = mbedtls_cipher_setkey( &operation->ctx.cipher, key_buffer,
                                      (int) key_bits, cipher_operation );
     }
     if( ret != 0 )
@@ -200,11 +198,11 @@
     switch( alg )
     {
         case PSA_ALG_CBC_NO_PADDING:
-            ret = mbedtls_cipher_set_padding_mode( &operation->cipher,
+            ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
                                                    MBEDTLS_PADDING_NONE );
             break;
         case PSA_ALG_CBC_PKCS7:
-            ret = mbedtls_cipher_set_padding_mode( &operation->cipher,
+            ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
                                                    MBEDTLS_PADDING_PKCS7 );
             break;
         default:
@@ -253,7 +251,7 @@
         return( PSA_ERROR_INVALID_ARGUMENT );
 
     return( mbedtls_to_psa_error(
-                mbedtls_cipher_set_iv( &operation->cipher,
+                mbedtls_cipher_set_iv( &operation->ctx.cipher,
                                        iv, iv_length ) ) );
 }
 
@@ -362,7 +360,7 @@
          * the last partial block, if any. You get the data that will be
          * output in this call. */
         expected_output_size =
-            ( operation->cipher.unprocessed_len + input_length )
+            ( operation->ctx.cipher.unprocessed_len + input_length )
             / operation->block_length * operation->block_length;
     }
     else
@@ -378,7 +376,7 @@
         /* mbedtls_cipher_update has an API inconsistency: it will only
         * process a single block at a time in ECB mode. Abstract away that
         * inconsistency here to match the PSA API behaviour. */
-        status = psa_cipher_update_ecb( &operation->cipher,
+        status = psa_cipher_update_ecb( &operation->ctx.cipher,
                                         input,
                                         input_length,
                                         output,
@@ -388,8 +386,11 @@
     else
     {
         status = mbedtls_to_psa_error(
-            mbedtls_cipher_update( &operation->cipher, input,
+            mbedtls_cipher_update( &operation->ctx.cipher, input,
                                    input_length, output, output_length ) );
+
+        if( *output_length > output_size )
+            return( PSA_ERROR_CORRUPTION_DETECTED );
     }
 
     return( status );
@@ -403,7 +404,7 @@
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
     uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
 
-    if( operation->cipher.unprocessed_len != 0 )
+    if( operation->ctx.cipher.unprocessed_len != 0 )
     {
         if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
             operation->alg == PSA_ALG_CBC_NO_PADDING )
@@ -414,7 +415,7 @@
     }
 
     status = mbedtls_to_psa_error(
-        mbedtls_cipher_finish( &operation->cipher,
+        mbedtls_cipher_finish( &operation->ctx.cipher,
                                temp_output_buffer,
                                output_length ) );
     if( status != PSA_SUCCESS )
@@ -441,10 +442,112 @@
     if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
         return( PSA_ERROR_BAD_STATE );
 
-    mbedtls_cipher_free( &operation->cipher );
+    mbedtls_cipher_free( &operation->ctx.cipher );
 
     return( PSA_SUCCESS );
 }
+
+static psa_status_t cipher_encrypt( const psa_key_attributes_t *attributes,
+                                    const uint8_t *key_buffer,
+                                    size_t key_buffer_size,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
+    size_t olength, accumulated_length;
+
+    status = cipher_encrypt_setup( &operation, attributes,
+                                   key_buffer, key_buffer_size, alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    accumulated_length = 0;
+    if( operation.iv_length > 0 )
+    {
+        status = cipher_set_iv( &operation, output, operation.iv_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+
+        accumulated_length = operation.iv_length;
+    }
+
+    status = cipher_update( &operation, input, input_length,
+                            output + operation.iv_length,
+                            output_size - operation.iv_length,
+                            &olength );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    accumulated_length += olength;
+
+    status = cipher_finish( &operation, output + accumulated_length,
+                            output_size - accumulated_length, &olength );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    *output_length = accumulated_length + olength;
+
+exit:
+    if( status == PSA_SUCCESS )
+        status = cipher_abort( &operation );
+    else
+        cipher_abort( &operation );
+    return( status );
+}
+
+static psa_status_t cipher_decrypt( const psa_key_attributes_t *attributes,
+                                    const uint8_t *key_buffer,
+                                    size_t key_buffer_size,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
+    size_t olength, accumulated_length;
+
+    status = cipher_decrypt_setup( &operation, attributes,
+                                   key_buffer, key_buffer_size, alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    if( operation.iv_length > 0 )
+    {
+        status = cipher_set_iv( &operation, input, operation.iv_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
+
+    status = cipher_update( &operation, input + operation.iv_length,
+                            input_length - operation.iv_length,
+                            output, output_size, &olength );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    accumulated_length = olength;
+
+    status = cipher_finish( &operation, output + accumulated_length,
+                            output_size - accumulated_length, &olength );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    *output_length = accumulated_length + olength;
+
+exit:
+    if ( status == PSA_SUCCESS )
+        status = cipher_abort( &operation );
+    else
+        cipher_abort( &operation );
+    return( status );
+}
 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER || PSA_CRYPTO_DRIVER_TEST */
 
 #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
@@ -498,6 +601,36 @@
 {
     return( cipher_abort( operation ) );
 }
+
+psa_status_t mbedtls_psa_cipher_encrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length )
+{
+    return( cipher_encrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
+
+psa_status_t mbedtls_psa_cipher_decrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length )
+{
+    return( cipher_decrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
 
 /*
@@ -553,6 +686,38 @@
 {
     return( cipher_abort( operation ) );
 }
+
+psa_status_t mbedtls_transparent_test_driver_cipher_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
+{
+    return( cipher_encrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
+
+psa_status_t mbedtls_transparent_test_driver_cipher_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
+{
+    return( cipher_decrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_cipher.h b/library/psa_crypto_cipher.h
index 3e1a7a0..5971e8d 100644
--- a/library/psa_crypto_cipher.h
+++ b/library/psa_crypto_cipher.h
@@ -199,6 +199,111 @@
  */
 psa_status_t mbedtls_psa_cipher_abort( mbedtls_psa_cipher_operation_t *operation );
 
+/** Encrypt a message using a symmetric cipher.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       cipher_encrypt entry point. This function behaves as a
+ *       cipher_encrypt entry point as defined in the PSA driver
+ *       interface specification for transparent drivers.
+ *
+ * \param[in] attributes        The attributes of the key to use for the
+ *                              operation.
+ * \param[in] key_buffer        The buffer containing the key context.
+ * \param[in] key_buffer_size   Size of the \p key_buffer buffer in bytes.
+ * \param[in] alg               The cipher algorithm to compute
+ *                              (\c PSA_ALG_XXX value such that
+ *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param[in]  input            Buffer containing the message to encrypt.
+ * \param[in]  input_length     Size of the \p input buffer in bytes.
+ * \param[in,out] output        Buffer where the output is to be written.
+ *                              The core has generated and written the IV
+ *                              at the beginning of this buffer before
+ *                              this function is called. The size of the IV
+ *                              is PSA_CIPHER_IV_LENGTH( key_type, alg ) where
+ *                              \c key_type is the type of the key identified
+ *                              by \p key and \p alg is the cipher algorithm
+ *                              to compute.
+ * \param[in]  output_size      Size of the \p output buffer in bytes.
+ * \param[out] output_length    On success, the number of bytes that make up
+ *                              the returned output. Initialized to zero
+ *                              by the core.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size of \p iv is not acceptable for the chosen algorithm,
+ *         or the chosen algorithm does not use an IV.
+ *         The total input size passed to this operation is not valid for
+ *         this particular algorithm. For example, the algorithm is a based
+ *         on block cipher and requires a whole number of blocks, but the
+ *         total input size is not a multiple of the block size.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ *         This is a decryption operation for an algorithm that includes
+ *         padding, and the ciphertext does not contain valid padding.
+ */
+psa_status_t mbedtls_psa_cipher_encrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length );
+
+/** Decrypt a message using a symmetric cipher.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       cipher_decrypt entry point. This function behaves as a
+ *       cipher_decrypt entry point as defined in the PSA driver
+ *       interface specification for transparent drivers.
+ *
+ * \param[in]  attributes       The attributes of the key to use for the
+ *                              operation.
+ * \param[in]  key_buffer       The buffer containing the key context.
+ * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
+ * \param[in]  alg              The cipher algorithm to compute
+ *                              (\c PSA_ALG_XXX value such that
+ *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param[in]  input            Buffer containing the iv and the ciphertext.
+ * \param[in]  input_length     Size of the \p input buffer in bytes.
+ * \param[out] output           Buffer where the output is to be written.
+ * \param[in]  output_size      Size of the \p output buffer in bytes.
+ * \param[out] output_length    On success, the number of bytes that make up
+ *                              the returned output. Initialized to zero
+ *                              by the core.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size of \p iv is not acceptable for the chosen algorithm,
+ *         or the chosen algorithm does not use an IV.
+ *         The total input size passed to this operation is not valid for
+ *         this particular algorithm. For example, the algorithm is a based
+ *         on block cipher and requires a whole number of blocks, but the
+ *         total input size is not a multiple of the block size.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ *         This is a decryption operation for an algorithm that includes
+ *         padding, and the ciphertext does not contain valid padding.
+ */
+psa_status_t mbedtls_psa_cipher_decrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length );
+
 /*
  * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
  */
@@ -231,6 +336,28 @@
 
 psa_status_t mbedtls_transparent_test_driver_cipher_abort(
     mbedtls_psa_cipher_operation_t *operation );
+
+psa_status_t mbedtls_transparent_test_driver_cipher_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length );
+
+psa_status_t mbedtls_transparent_test_driver_cipher_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* PSA_CRYPTO_CIPHER_H */
diff --git a/library/psa_crypto_client.c b/library/psa_crypto_client.c
index e84cf30..629feb7 100644
--- a/library/psa_crypto_client.c
+++ b/library/psa_crypto_client.c
@@ -19,7 +19,6 @@
  */
 
 #include "common.h"
-#include "psa_crypto_service_integration.h"
 #include "psa/crypto.h"
 
 #if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index 4420ec2..91757b5 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -21,11 +21,7 @@
 #ifndef PSA_CRYPTO_CORE_H
 #define PSA_CRYPTO_CORE_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "psa/crypto.h"
 #include "psa/crypto_se_driver.h"
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 19260c4..38d0e30 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -737,7 +737,9 @@
  * Cipher functions
  */
 psa_status_t psa_driver_wrapper_cipher_encrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -745,22 +747,20 @@
     size_t output_size,
     size_t *output_length )
 {
-#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-    psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
-    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
-    psa_key_attributes_t attributes = {
-      .core = slot->attr
-    };
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
 
     switch( location )
     {
         case PSA_KEY_LOCATION_LOCAL_STORAGE:
             /* Key is stored in the slot in export representation, so
              * cycle through all known transparent accelerators */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = mbedtls_test_transparent_cipher_encrypt( &attributes,
-                                                              slot->key.data,
-                                                              slot->key.bytes,
+            status = mbedtls_test_transparent_cipher_encrypt( attributes,
+                                                              key_buffer,
+                                                              key_buffer_size,
                                                               alg,
                                                               input,
                                                               input_length,
@@ -771,14 +771,29 @@
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
-            /* Fell through, meaning no accelerator supports this operation */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
+            return( mbedtls_psa_cipher_encrypt( attributes,
+                                                key_buffer,
+                                                key_buffer_size,
+                                                alg,
+                                                input,
+                                                input_length,
+                                                output,
+                                                output_size,
+                                                output_length ) );
+#else
             return( PSA_ERROR_NOT_SUPPORTED );
+#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
+
         /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
         case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_cipher_encrypt( &attributes,
-                                                        slot->key.data,
-                                                        slot->key.bytes,
+            return( mbedtls_test_opaque_cipher_encrypt( attributes,
+                                                        key_buffer,
+                                                        key_buffer_size,
                                                         alg,
                                                         input,
                                                         input_length,
@@ -786,25 +801,27 @@
                                                         output_size,
                                                         output_length ) );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
         default:
             /* Key is declared with a lifetime not known to us */
-            return( status );
+            (void)status;
+            (void)key_buffer;
+            (void)key_buffer_size;
+            (void)alg;
+            (void)input;
+            (void)input_length;
+            (void)output;
+            (void)output_size;
+            (void)output_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
     }
-#else /* PSA_CRYPTO_DRIVER_PRESENT */
-    (void) slot;
-    (void) alg;
-    (void) input;
-    (void) input_length;
-    (void) output;
-    (void) output_size;
-    (void) output_length;
-
-    return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
 psa_status_t psa_driver_wrapper_cipher_decrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -812,22 +829,20 @@
     size_t output_size,
     size_t *output_length )
 {
-#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-    psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
-    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
-    psa_key_attributes_t attributes = {
-      .core = slot->attr
-    };
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
 
     switch( location )
     {
         case PSA_KEY_LOCATION_LOCAL_STORAGE:
             /* Key is stored in the slot in export representation, so
              * cycle through all known transparent accelerators */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = mbedtls_test_transparent_cipher_decrypt( &attributes,
-                                                              slot->key.data,
-                                                              slot->key.bytes,
+            status = mbedtls_test_transparent_cipher_decrypt( attributes,
+                                                              key_buffer,
+                                                              key_buffer_size,
                                                               alg,
                                                               input,
                                                               input_length,
@@ -838,14 +853,29 @@
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
-            /* Fell through, meaning no accelerator supports this operation */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
+            return( mbedtls_psa_cipher_decrypt( attributes,
+                                                key_buffer,
+                                                key_buffer_size,
+                                                alg,
+                                                input,
+                                                input_length,
+                                                output,
+                                                output_size,
+                                                output_length ) );
+#else
             return( PSA_ERROR_NOT_SUPPORTED );
+#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
+
         /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
         case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_cipher_decrypt( &attributes,
-                                                        slot->key.data,
-                                                        slot->key.bytes,
+            return( mbedtls_test_opaque_cipher_decrypt( attributes,
+                                                        key_buffer,
+                                                        key_buffer_size,
                                                         alg,
                                                         input,
                                                         input_length,
@@ -853,21 +883,21 @@
                                                         output_size,
                                                         output_length ) );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
         default:
             /* Key is declared with a lifetime not known to us */
-            return( status );
+            (void)status;
+            (void)key_buffer;
+            (void)key_buffer_size;
+            (void)alg;
+            (void)input;
+            (void)input_length;
+            (void)output;
+            (void)output_size;
+            (void)output_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
     }
-#else /* PSA_CRYPTO_DRIVER_PRESENT */
-    (void) slot;
-    (void) alg;
-    (void) input;
-    (void) input_length;
-    (void) output;
-    (void) output_size;
-    (void) output_length;
-
-    return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
 psa_status_t psa_driver_wrapper_cipher_encrypt_setup(
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index 732ed2a..38a6ee8 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -98,7 +98,9 @@
  * Cipher functions
  */
 psa_status_t psa_driver_wrapper_cipher_encrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -107,7 +109,9 @@
     size_t *output_length );
 
 psa_status_t psa_driver_wrapper_cipher_decrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
diff --git a/library/psa_crypto_invasive.h b/library/psa_crypto_invasive.h
index 1e5a407..1dd9579 100644
--- a/library/psa_crypto_invasive.h
+++ b/library/psa_crypto_invasive.h
@@ -28,11 +28,7 @@
 #ifndef PSA_CRYPTO_INVASIVE_H
 #define PSA_CRYPTO_INVASIVE_H
 
-#if defined(MBEDTLS_CONFIG_FILE)
-#include MBEDTLS_CONFIG_FILE
-#else
-#include "mbedtls/config.h"
-#endif
+#include "mbedtls/build_info.h"
 
 #include "psa/crypto.h"
 #include "common.h"
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index ef2adc1..d85b86c 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -361,27 +361,14 @@
         return( PSA_ERROR_INVALID_ARGUMENT );
 #endif
 
-#if defined(BUILTIN_ALG_RSA_PKCS1V15_SIGN)
-    /* For PKCS#1 v1.5 signature, if using a hash, the hash length
-     * must be correct. */
-    if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
-        alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
+    /* For signatures using a hash, the hash length must be correct. */
+    if( alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
     {
         if( md_info == NULL )
             return( PSA_ERROR_NOT_SUPPORTED );
         if( mbedtls_md_get_size( md_info ) != hash_length )
             return( PSA_ERROR_INVALID_ARGUMENT );
     }
-#endif /* BUILTIN_ALG_RSA_PKCS1V15_SIGN */
-
-#if defined(BUILTIN_ALG_RSA_PSS)
-    /* PSS requires a hash internally. */
-    if( PSA_ALG_IS_RSA_PSS( alg ) )
-    {
-        if( md_info == NULL )
-            return( PSA_ERROR_NOT_SUPPORTED );
-    }
-#endif /* BUILTIN_ALG_RSA_PSS */
 
     return( PSA_SUCCESS );
 }
@@ -517,7 +504,7 @@
         if( ret == 0 )
         {
             ret = mbedtls_rsa_rsassa_pss_verify( rsa,
-                                                 MBEDTLS_MD_NONE,
+                                                 md_alg,
                                                  (unsigned int) hash_length,
                                                  hash,
                                                  signature );
diff --git a/library/psa_crypto_se.h b/library/psa_crypto_se.h
index 7104261..549dfb6 100644
--- a/library/psa_crypto_se.h
+++ b/library/psa_crypto_se.h
@@ -21,11 +21,7 @@
 #ifndef PSA_CRYPTO_SE_H
 #define PSA_CRYPTO_SE_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "psa/crypto.h"
 #include "psa/crypto_se_driver.h"
diff --git a/library/psa_crypto_service_integration.h b/library/psa_crypto_service_integration.h
deleted file mode 100644
index 87889af..0000000
--- a/library/psa_crypto_service_integration.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Copyright The Mbed TLS Contributors
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef PSA_CRYPTO_SERVICE_INTEGRATION_H
-#define PSA_CRYPTO_SERVICE_INTEGRATION_H
-
-/*
- * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM
- * (Secure Partition Manager) integration which separates the code into two
- * parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing
- * Environment). When building for the SPE, an additional header file should be
- * included.
- */
-#if defined(MBEDTLS_PSA_CRYPTO_SPM)
-/*
- * PSA_CRYPTO_SECURE means that the file which included this file is being
- * compiled for SPE. The files crypto_structs.h and crypto_types.h have
- * different implementations for NSPE and SPE and are compiled according to this
- * flag.
- */
-#define PSA_CRYPTO_SECURE 1
-#include "crypto_spe.h"
-#endif // MBEDTLS_PSA_CRYPTO_SPM
-
-#endif // PSA_CRYPTO_SERVICE_INTEGRATION_H
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 4cf32db..4131e3c 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -22,7 +22,6 @@
 
 #if defined(MBEDTLS_PSA_CRYPTO_C)
 
-#include "psa_crypto_service_integration.h"
 #include "psa/crypto.h"
 
 #include "psa_crypto_core.h"
@@ -392,6 +391,10 @@
         if( status == PSA_ERROR_DOES_NOT_EXIST )
             status = PSA_ERROR_INVALID_HANDLE;
     }
+    else
+        /* Add implicit usage flags. */
+        psa_extend_key_usage_flags( &(*p_slot)->attr.policy.usage );
+
     return( status );
 #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
     return( PSA_ERROR_INVALID_HANDLE );
@@ -455,7 +458,10 @@
     {
         /* Persistent keys require storage support */
 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
-        return( PSA_SUCCESS );
+        if( PSA_KEY_LIFETIME_IS_READ_ONLY( lifetime ) )
+            return( PSA_ERROR_INVALID_ARGUMENT );
+        else
+            return( PSA_SUCCESS );
 #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
         return( PSA_ERROR_NOT_SUPPORTED );
 #endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
@@ -545,16 +551,17 @@
             ++stats->empty_slots;
             continue;
         }
-        if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE )
+        if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
             ++stats->volatile_slots;
-        else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT )
+        else
         {
             psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id );
             ++stats->persistent_slots;
             if( id > stats->max_open_internal_key_id )
                 stats->max_open_internal_key_id = id;
         }
-        else
+        if( PSA_KEY_LIFETIME_GET_LOCATION( slot->attr.lifetime ) !=
+            PSA_KEY_LOCATION_LOCAL_STORAGE )
         {
             psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id );
             ++stats->external_slots;
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index 575e992..09cbab4 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -25,7 +25,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "psa_crypto_service_integration.h"
 #include "psa/crypto.h"
 #include "psa_crypto_storage.h"
 #include "mbedtls/platform_util.h"
diff --git a/library/rsa.c b/library/rsa.c
index d4e63b6..ed1632a 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -1790,7 +1790,8 @@
         if( md_info == NULL )
             return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-        hashlen = mbedtls_md_get_size( md_info );
+        if( hashlen != mbedtls_md_get_size( md_info ) )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
     }
 
     md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
@@ -1925,14 +1926,13 @@
  * Parameters:
  * - md_alg:  Identifies the hash algorithm used to generate the given hash;
  *            MBEDTLS_MD_NONE if raw data is signed.
- * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE.
+ * - hashlen: Length of hash. Must match md_alg if that's not NONE.
  * - hash:    Buffer containing the hashed message or the raw data.
  * - dst_len: Length of the encoded message.
  * - dst:     Buffer to hold the encoded message.
  *
  * Assumptions:
- * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE.
- * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE.
+ * - hash has size hashlen.
  * - dst points to a buffer of size at least dst_len.
  *
  */
@@ -1957,7 +1957,8 @@
         if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
             return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-        hashlen = mbedtls_md_get_size( md_info );
+        if( hashlen != mbedtls_md_get_size( md_info ) )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
         /* Double-check that 8 + hashlen + oid_size can be used as a
          * 1-byte ASN.1 length encoding and that there's no overflow. */
@@ -2022,6 +2023,8 @@
      *                                 TAG-NULL + LEN [ NULL ] ]
      *                 TAG-OCTET + LEN [ HASH ] ]
      */
+    if( 0x08 + oid_size + hashlen >= 0x80 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
     *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
     *p++ = (unsigned char)( 0x08 + oid_size + hashlen );
     *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
@@ -2203,7 +2206,8 @@
         if( md_info == NULL )
             return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-        hashlen = mbedtls_md_get_size( md_info );
+        if( hashlen != mbedtls_md_get_size( md_info ) )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
     }
 
     md_info = mbedtls_md_info_from_type( mgf1_hash_id );
@@ -2674,7 +2678,7 @@
     }
 
     if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
-                                MBEDTLS_MD_SHA1, 0,
+                                MBEDTLS_MD_SHA1, 20,
                                 sha1sum, rsa_ciphertext ) != 0 )
     {
         if( verbose != 0 )
@@ -2687,7 +2691,7 @@
     if( verbose != 0 )
         mbedtls_printf( "passed\n  PKCS#1 sig. verify: " );
 
-    if( mbedtls_rsa_pkcs1_verify( &rsa, MBEDTLS_MD_SHA1, 0,
+    if( mbedtls_rsa_pkcs1_verify( &rsa, MBEDTLS_MD_SHA1, 20,
                                   sha1sum, rsa_ciphertext ) != 0 )
     {
         if( verbose != 0 )
diff --git a/library/rsa_alt_helpers.h b/library/rsa_alt_helpers.h
index 90c88a2..d6fc8e5 100644
--- a/library/rsa_alt_helpers.h
+++ b/library/rsa_alt_helpers.h
@@ -55,11 +55,7 @@
 #ifndef MBEDTLS_RSA_INTERNAL_H
 #define MBEDTLS_RSA_INTERNAL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/bignum.h"
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 30e64c4..ef391b3 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1390,7 +1390,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
     }
     else
@@ -1404,7 +1404,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
 
         ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
@@ -1431,8 +1431,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     return( 0 );
@@ -1453,16 +1453,16 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension unexpected" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     if( len == 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     peer_cid_len = *buf++;
@@ -1472,16 +1472,16 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+                                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     if( len != peer_cid_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
@@ -1508,8 +1508,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     ((void) buf);
@@ -1533,8 +1533,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     ((void) buf);
@@ -1558,8 +1558,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     ((void) buf);
@@ -1584,7 +1584,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     list_size = buf[0];
 
@@ -1612,7 +1612,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
     mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-    return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
 }
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
@@ -1665,8 +1665,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     /*
@@ -1684,7 +1684,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     list_len = ( buf[0] << 8 ) | buf[1];
@@ -1692,7 +1692,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     name_len = buf[2];
@@ -1700,7 +1700,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Check that the server chosen protocol was in our list and save it */
@@ -1717,7 +1717,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) );
     mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-    return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
@@ -1759,7 +1759,7 @@
      *                                      and optional srtp_mki
      */
     if( ( len < 5 ) || ( len != ( buf[4] + 5u ) ) )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     /*
      * get the server protection profile
@@ -1770,7 +1770,7 @@
      * one protection profile in server Hello
      */
     if( (  buf[0] != 0 ) || ( buf[1] != 2 ) )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
     server_protection = mbedtls_ssl_check_srtp_profile_value(
@@ -1804,7 +1804,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     /* If server does not use mki in its reply, make sure the client won't keep
@@ -1825,7 +1825,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 #if defined (MBEDTLS_DEBUG_C)
     if( len > 5 )
@@ -1860,7 +1860,7 @@
             ( "incoming HelloVerifyRequest message is too short" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -1887,7 +1887,7 @@
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
 
-        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
     }
 
     cookie_len = *p++;
@@ -1897,7 +1897,7 @@
             ( "cookie length does not match incoming message size" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
 
@@ -2005,7 +2005,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -2041,7 +2041,7 @@
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
 
-        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu",
@@ -2061,7 +2061,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n )
@@ -2077,7 +2077,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
     }
     else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n )
@@ -2089,7 +2089,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* ciphersuite (used later) */
@@ -2186,7 +2186,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         if( ssl->conf->ciphersuite_list[i++] ==
@@ -2205,8 +2205,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3,
@@ -2228,7 +2228,7 @@
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
     ssl->session_negotiate->compression = comp;
 
@@ -2250,7 +2250,7 @@
             mbedtls_ssl_send_alert_message(
                 ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         switch( ext_id )
@@ -2395,7 +2395,7 @@
         if( ext_len > 0 && ext_len < 4 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
     }
 
@@ -2443,7 +2443,7 @@
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
@@ -2482,7 +2482,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u",
                                     dhm_actual_bitlen,
                                     ssl->conf->dhm_min_bitlen ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P  );
@@ -2554,11 +2554,11 @@
      */
 
     if( end - *p < 4 )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     /* First byte is curve_type; only named_curve is handled */
     if( *(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
 
     /* Next two bytes are the namedcurve value */
     tls_id = *(*p)++;
@@ -2569,10 +2569,10 @@
     if( ( handshake->ecdh_psa_type =
           mbedtls_psa_parse_tls_ecc_group( tls_id, &ecdh_bits ) ) == 0 )
     {
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
     if( ecdh_bits > 0xffff )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     handshake->ecdh_bits = (uint16_t) ecdh_bits;
 
     /*
@@ -2581,7 +2581,7 @@
 
     ecpoint_len = *(*p)++;
     if( (size_t)( end - *p ) < ecpoint_len )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     if( mbedtls_psa_tls_ecpoint_to_psa_ec(
                                     *p, ecpoint_len,
@@ -2631,7 +2631,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "bad server key exchange message (ECDHE curve)" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     return( ret );
@@ -2658,7 +2658,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "bad server key exchange message (psk_identity_hint length)" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     len = (*p)[0] << 8 | (*p)[1];
     *p += 2;
@@ -2667,7 +2667,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "bad server key exchange message (psk_identity_hint length)" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -2791,7 +2791,7 @@
     }
 
     if( (*p) + 2 > end )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     /*
      * Get hash algorithm
@@ -2801,7 +2801,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "Server used unsupported HashAlgorithm %d", *(p)[0] ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     /*
@@ -2812,7 +2812,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     /*
@@ -2822,7 +2822,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "server used HashAlgorithm %d that was not offered", *(p)[0] ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d",
@@ -2876,7 +2876,7 @@
     if( ssl_check_server_ecdh_params( ssl ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
     }
 
 #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
@@ -3006,8 +3006,8 @@
             mbedtls_ssl_send_alert_message(
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
     } /* FALLTROUGH */
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
@@ -3032,7 +3032,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
     }
     else
@@ -3051,7 +3051,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
     }
     else
@@ -3072,7 +3072,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
     }
     else
@@ -3090,8 +3090,8 @@
             mbedtls_ssl_send_alert_message(
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
     }
     else
@@ -3129,7 +3129,7 @@
                     ssl,
                     MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-                return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+                return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
             }
 
             if( pk_alg !=
@@ -3141,7 +3141,7 @@
                     ssl,
                     MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-                return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+                return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
             }
         }
         else
@@ -3162,7 +3162,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
         sig_len = ( p[0] << 8 ) | p[1];
         p += 2;
@@ -3174,7 +3174,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
@@ -3363,7 +3363,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
     n = cert_type_len;
@@ -3383,7 +3383,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* supported_signature_algorithms */
@@ -3418,7 +3418,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
 #if defined(MBEDTLS_DEBUG_C)
@@ -3445,7 +3445,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
 exit:
@@ -3479,7 +3479,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     ssl->state++;
@@ -3948,6 +3948,11 @@
     mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
     size_t hashlen;
     void *rs_ctx = NULL;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+    size_t out_buf_len = ssl->out_buf_len - ( ssl->out_msg - ssl->out_buf );
+#else
+    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - ( ssl->out_msg - ssl->out_buf );
+#endif
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
 
@@ -4046,7 +4051,9 @@
 
     if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ),
                          md_alg, hash_start, hashlen,
-                         ssl->out_msg + 6 + offset, &n,
+                         ssl->out_msg + 6 + offset,
+                         out_buf_len - 6 - offset,
+                         &n,
                          ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
@@ -4121,7 +4128,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
@@ -4136,7 +4143,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len ) );
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index d25bc55..c93c88d 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_SSL_MISC_H
 #define MBEDTLS_SSL_MISC_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ssl.h"
 #include "mbedtls/cipher.h"
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 0fa206b..11896ca 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -3112,16 +3112,16 @@
         in[3] != 0 || in[4] != 0 ||
         in[19] != 0 || in[20] != 0 || in[21] != 0 )
     {
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     sid_len = in[59];
     if( sid_len > in_len - 61 )
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     cookie_len = in[60 + sid_len];
     if( cookie_len > in_len - 60 )
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
                         cli_id, cli_id_len ) == 0 )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 4715129..ad98850 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -91,7 +91,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( servername_list_size + 2 != len )
@@ -99,7 +99,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     p = buf + 2;
@@ -111,7 +111,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME )
@@ -123,7 +123,7 @@
                 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                         MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME );
             }
             return( 0 );
         }
@@ -136,8 +136,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     return( 0 );
@@ -202,7 +202,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
     }
     else
@@ -213,7 +213,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
 
         ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
@@ -253,7 +253,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( sig_alg_list_size + 2 != len ||
@@ -262,7 +262,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Currently we only guarantee signing the ServerKeyExchange message according
@@ -327,7 +327,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( list_size + 2 != len ||
@@ -336,7 +336,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Should never happen unless client duplicates the extension */
@@ -344,8 +344,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     /* Don't allow our peer to make us allocate too much memory,
@@ -393,7 +393,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     list_size = buf[0];
 
@@ -462,7 +462,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     ssl->session_negotiate->mfl_code = buf[0];
@@ -484,7 +484,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     /*
@@ -500,8 +500,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     peer_cid_len = *buf++;
@@ -511,8 +511,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Ignore CID if the user has disabled its use. */
@@ -529,7 +529,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
@@ -553,7 +553,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     ((void) buf);
@@ -577,7 +577,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     ((void) buf);
@@ -690,7 +690,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     list_len = ( buf[0] << 8 ) | buf[1];
@@ -698,7 +698,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -715,7 +715,7 @@
         {
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         /* Empty strings MUST NOT be included */
@@ -723,7 +723,7 @@
         {
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
     }
 
@@ -749,7 +749,7 @@
     /* If we get there, no match was found */
     mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                             MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
-    return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    return( MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL );
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
@@ -793,8 +793,8 @@
     if( len < size_of_lengths )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
@@ -808,8 +808,8 @@
         profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     /*
      * parse the extension list values are defined in
@@ -853,8 +853,8 @@
         mki_length + profile_length + size_of_lengths != len )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Parse the mki only if present and mki is supported locally */
@@ -1183,7 +1183,7 @@
     if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, message len.: %d",
@@ -1201,7 +1201,7 @@
     if( major < MBEDTLS_SSL_MAJOR_VERSION_3 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
     }
 
     /* For DTLS if this is the initial handshake, remember the client sequence
@@ -1217,7 +1217,7 @@
         if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
@@ -1251,7 +1251,7 @@
         if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         if( ( ret = mbedtls_ssl_fetch_input( ssl,
@@ -1287,7 +1287,7 @@
     if( msg_len < mbedtls_ssl_hs_hdr_len( ssl ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) );
@@ -1295,7 +1295,7 @@
     if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d",
@@ -1306,7 +1306,7 @@
         msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -1328,7 +1328,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: "
                                     "%u (expected %u)", cli_msg_seq,
                                     ssl->handshake->in_msg_seq ) );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
 
             ssl->handshake->in_msg_seq++;
@@ -1382,7 +1382,7 @@
     if( msg_len < 38 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -1405,7 +1405,7 @@
                             ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
-        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
     }
 
     if( ssl->major_ver > ssl->conf->max_major_ver )
@@ -1434,7 +1434,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 35, sess_len );
@@ -1458,8 +1458,8 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
@@ -1493,7 +1493,7 @@
             {
                 /* This may be an attacker's probe, so don't send an alert */
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
 
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification skipped" ) );
@@ -1518,7 +1518,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
@@ -1538,7 +1538,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression",
@@ -1561,7 +1561,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
 
             ext_len = ( buf[ext_offset + 0] << 8 )
@@ -1572,7 +1572,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
         }
         else
@@ -1589,7 +1589,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
             ext_id   = ( ( ext[0] <<  8 ) | ( ext[1] ) );
             ext_size = ( ( ext[2] <<  8 ) | ( ext[3] ) );
@@ -1599,7 +1599,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
             switch( ext_id )
             {
@@ -1785,7 +1785,7 @@
                                             "during renegotiation" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
             }
 #endif
             ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
@@ -1830,7 +1830,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     /*
@@ -1885,14 +1885,14 @@
                             "but none of them usable" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
     else
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
 have_ciphersuite:
@@ -2922,6 +2922,14 @@
     (void) signature_len;
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+    size_t out_buf_len = ssl->out_buf_len - ( ssl->out_msg - ssl->out_buf );
+#else
+    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - ( ssl->out_msg - ssl->out_buf );
+#endif
+#endif
+
     ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
 
     /*
@@ -3054,7 +3062,7 @@
         if( curve == NULL || *curve == NULL )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) );
-            return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
 
         MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
@@ -3224,6 +3232,7 @@
         if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ),
                                      md_alg, hash, hashlen,
                                      ssl->out_msg + ssl->out_msglen + 2,
+                                     out_buf_len - ssl->out_msglen - 2,
                                      signature_len,
                                      ssl->conf->f_rng,
                                      ssl->conf->p_rng ) ) != 0 )
@@ -3389,7 +3398,7 @@
     if( *p + 2 > end )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     n = ( (*p)[0] << 8 ) | (*p)[1];
@@ -3398,13 +3407,13 @@
     if( *p + n > end )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     if( ( ret = mbedtls_dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_read_public", ret );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     *p += n;
@@ -3466,20 +3475,20 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if ( p + 2 > end ) {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
         *p++ != ( ( len      ) & 0xFF ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 #endif
 
     if( p + len != end )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -3640,7 +3649,7 @@
     if( end - *p < 2 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     n = ( (*p)[0] << 8 ) | (*p)[1];
@@ -3649,7 +3658,7 @@
     if( n == 0 || n > end - *p )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     if( ssl->conf->f_psk != NULL )
@@ -3718,13 +3727,13 @@
     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
     if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
@@ -3739,7 +3748,7 @@
         if( p != end )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
@@ -3749,7 +3758,7 @@
                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
@@ -3769,7 +3778,7 @@
                                       p, end - p) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
@@ -3782,7 +3791,7 @@
                                        ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
@@ -3805,7 +3814,7 @@
         if( p != end )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -3890,7 +3899,7 @@
         if( p != end )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
@@ -3915,7 +3924,7 @@
                                        p, end - p ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -3955,7 +3964,7 @@
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
         }
 
         ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
@@ -4061,7 +4070,7 @@
         ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
     i = mbedtls_ssl_hs_hdr_len( ssl );
@@ -4089,7 +4098,7 @@
         if( i + 2 > ssl->in_hslen )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         /*
@@ -4101,7 +4110,7 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
                                 " for verify message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
 #if !defined(MBEDTLS_MD_SHA1)
@@ -4122,7 +4131,7 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
                                 " for verify message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         /*
@@ -4131,7 +4140,7 @@
         if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         i++;
@@ -4146,7 +4155,7 @@
     if( i + 2 > ssl->in_hslen )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1];
@@ -4155,7 +4164,7 @@
     if( i + sig_len != ssl->in_hslen )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Calculate hash and verify signature */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 1396400..1cfda4a 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1855,13 +1855,19 @@
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
-    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE ||
-        ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE  )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     i = mbedtls_ssl_hs_hdr_len( ssl );
@@ -1877,7 +1883,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
@@ -1892,7 +1898,7 @@
             mbedtls_ssl_send_alert_message( ssl,
                               MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                               MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
         /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
          * anything beyond 2**16 ~ 64K. */
@@ -1901,8 +1907,8 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
             mbedtls_ssl_send_alert_message( ssl,
                             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+                            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT );
+            return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
         }
 
         /* Read length of the next CRT in the chain. */
@@ -1916,7 +1922,7 @@
             mbedtls_ssl_send_alert_message( ssl,
                                  MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                  MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         /* Check if we're handling the first CRT in the chain. */
@@ -1938,7 +1944,7 @@
                 mbedtls_ssl_send_alert_message( ssl,
                                                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+                return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
             }
 
             /* Now we can safely free the original chain. */
@@ -2148,7 +2154,7 @@
 
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
             if( ret == 0 )
-                ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
+                ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
         }
     }
 #endif /* MBEDTLS_ECP_C */
@@ -2160,7 +2166,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
         if( ret == 0 )
-            ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
+            ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
     }
 
     /* mbedtls_x509_crt_verify_with_profile is supposed to report a
@@ -2171,7 +2177,7 @@
      * ssl_parse_certificate even if verification was optional. */
     if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
         ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
-          ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
+          ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE ) )
     {
         ret = 0;
     }
@@ -2903,13 +2909,19 @@
 
     hash_len = 12;
 
-    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
-        ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED  )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
@@ -2917,8 +2929,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
+                                        MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
diff --git a/library/threading.c b/library/threading.c
index 2de117f..bae6644 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -19,7 +19,7 @@
 
 /*
  * Ensure gmtime_r is available even with -std=c99; must be defined before
- * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ * mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms.
  */
 #if !defined(_POSIX_C_SOURCE)
 #define _POSIX_C_SOURCE 200112L
diff --git a/library/timing.c b/library/timing.c
index a85ce67..8a02c00 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -28,7 +28,7 @@
 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
     !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
     !defined(__HAIKU__) && !defined(__midipix__)
-#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h"
+#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in mbedtls_config.h"
 #endif
 
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
diff --git a/library/x509_crt.c b/library/x509_crt.c
index f12ac6b..c865444 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -167,6 +167,17 @@
 };
 
 /*
+ * Empty / all-forbidden profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_none =
+{
+    0,
+    0,
+    0,
+    (uint32_t) -1,
+};
+
+/*
  * Check md_alg against profile
  * Return 0 if md_alg is acceptable for this profile, -1 otherwise
  */
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index c90f8bc..c8169f1 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -474,7 +474,7 @@
     }
 
     if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg,
-                                 hash, 0, sig, &sig_len,
+                                 hash, 0, sig, sizeof( sig ), &sig_len,
                                  f_rng, p_rng ) ) != 0 )
     {
         return( ret );
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index 9f0ad93..555f296 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -136,7 +136,7 @@
 static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
                                  unsigned char *buf,
                                  size_t size,
-                                 unsigned char *sig,
+                                 unsigned char *sig, size_t sig_size,
                                  int (*f_rng)(void *, unsigned char *, size_t),
                                  void *p_rng )
 {
@@ -235,7 +235,8 @@
     if( ret != 0 )
         return( ret );
 #endif
-    if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
+    if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0,
+                                 sig, sig_size, &sig_len,
                                  f_rng, p_rng ) ) != 0 )
     {
         return( ret );
@@ -304,7 +305,9 @@
         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
     }
 
-    ret = x509write_csr_der_internal( ctx, buf, size, sig, f_rng, p_rng );
+    ret = x509write_csr_der_internal( ctx, buf, size,
+                                      sig, MBEDTLS_PK_SIGNATURE_MAX_SIZE,
+                                      f_rng, p_rng );
 
     mbedtls_free( sig );
 
diff --git a/programs/Makefile b/programs/Makefile
index dcdb8f3..997c198 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -153,12 +153,12 @@
 	$(PYTHON) ../scripts/generate_psa_constants.py
 
 test/query_config.c: ../scripts/generate_query_config.pl
-## The generated file only depends on the options that are present in config.h,
+## The generated file only depends on the options that are present in mbedtls_config.h,
 ## not on which options are set. To avoid regenerating this file all the time
-## when switching between configurations, don't declare config.h as a
+## when switching between configurations, don't declare mbedtls_config.h as a
 ## dependency. Remove this file from your working tree if you've just added or
-## removed an option in config.h.
-#test/query_config.c: ../include/mbedtls/config.h
+## removed an option in mbedtls_config.h.
+#test/query_config.c: ../include/mbedtls/mbedtls_config.h
 test/query_config.c: ../scripts/data_files/query_config.fmt
 test/query_config.c:
 	echo "  Gen   $@"
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index 0f97867..a8026a3 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -19,15 +19,11 @@
  */
 
 /* Enable definition of fileno() even when compiling with -std=c99. Must be
- * set before config.h, which pulls in glibc's features.h indirectly.
+ * set before mbedtls_config.h, which pulls in glibc's features.h indirectly.
  * Harmless on other platforms. */
 #define _POSIX_C_SOURCE 200112L
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/fuzz/onefile.c b/programs/fuzz/onefile.c
index c845149..efd8dbb 100644
--- a/programs/fuzz/onefile.c
+++ b/programs/fuzz/onefile.c
@@ -2,14 +2,10 @@
 #include <stdlib.h>
 #include <stdio.h>
 
-/* This file doesn't use any Mbed TLS function, but grab config.h anyway
+/* This file doesn't use any Mbed TLS function, but grab mbedtls_config.h anyway
  * in case it contains platform-specific #defines related to malloc or
  * stdio functions. */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
 
diff --git a/programs/hash/generic_sum.c b/programs/hash/generic_sum.c
index f73e5f8..9243f0a 100644
--- a/programs/hash/generic_sum.c
+++ b/programs/hash/generic_sum.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/hash/hello.c b/programs/hash/hello.c
index 18beb69..d2b6910 100644
--- a/programs/hash/hello.c
+++ b/programs/hash/hello.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index dbdee2d..eccb42a 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -221,7 +217,7 @@
     }
 
     if( ( ret = mbedtls_rsa_pkcs1_verify( &rsa, MBEDTLS_MD_SHA256,
-                                          0, hash, p ) ) != 0 )
+                                          32, hash, p ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_verify returned %d\n\n", ret );
         goto exit;
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index a481e32..174a363 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index 0d5be4e..0ddb85c 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -229,7 +225,7 @@
     buf[n + 1] = (unsigned char)( rsa.MBEDTLS_PRIVATE(len)      );
 
     if( ( ret = mbedtls_rsa_pkcs1_sign( &rsa, NULL, NULL, MBEDTLS_MD_SHA256,
-                                0, hash, buf + n + 2 ) ) != 0 )
+                                32, hash, buf + n + 2 ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_sign returned %d\n\n", ret );
         goto exit;
diff --git a/programs/pkey/ecdh_curve25519.c b/programs/pkey/ecdh_curve25519.c
index 1f4b8bc..ca046fd 100644
--- a/programs/pkey/ecdh_curve25519.c
+++ b/programs/pkey/ecdh_curve25519.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index 31b4584..6b6e951 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -184,7 +180,7 @@
 
     if( ( ret = mbedtls_ecdsa_write_signature( &ctx_sign, MBEDTLS_MD_SHA256,
                                        hash, sizeof( hash ),
-                                       sig, &sig_len,
+                                       sig, sizeof( sig ), &sig_len,
                                        mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ecdsa_write_signature returned %d\n", ret );
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index 9415530..4043dfa 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c
index 2145e07..4203902 100644
--- a/programs/pkey/key_app.c
+++ b/programs/pkey/key_app.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c
index 89c67ed..8a09af5 100644
--- a/programs/pkey/key_app_writer.c
+++ b/programs/pkey/key_app_writer.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/mpi_demo.c b/programs/pkey/mpi_demo.c
index 8245d01..6341752 100644
--- a/programs/pkey/mpi_demo.c
+++ b/programs/pkey/mpi_demo.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c
index e01f5d5..f1bfd8a 100644
--- a/programs/pkey/pk_decrypt.c
+++ b/programs/pkey/pk_decrypt.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c
index e629dc1..293c0a0 100644
--- a/programs/pkey/pk_encrypt.c
+++ b/programs/pkey/pk_encrypt.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index 422fa25..2ab428d 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -123,8 +119,9 @@
         goto exit;
     }
 
-    if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0, buf, &olen,
-                         mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
+    if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0,
+                                 buf, sizeof( buf ), &olen,
+                                 mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_pk_sign returned -0x%04x\n", (unsigned int) -ret );
         goto exit;
diff --git a/programs/pkey/pk_verify.c b/programs/pkey/pk_verify.c
index ee72243..5173507 100644
--- a/programs/pkey/pk_verify.c
+++ b/programs/pkey/pk_verify.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c
index bb3649f..42ec6a7 100644
--- a/programs/pkey/rsa_decrypt.c
+++ b/programs/pkey/rsa_decrypt.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c
index a000505..f7ff68f 100644
--- a/programs/pkey/rsa_encrypt.c
+++ b/programs/pkey/rsa_encrypt.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c
index 1dcfc52..e48050a 100644
--- a/programs/pkey/rsa_genkey.c
+++ b/programs/pkey/rsa_genkey.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c
index d9ba3bb..5aa592d 100644
--- a/programs/pkey/rsa_sign.c
+++ b/programs/pkey/rsa_sign.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -147,7 +143,7 @@
     }
 
     if( ( ret = mbedtls_rsa_pkcs1_sign( &rsa, NULL, NULL, MBEDTLS_MD_SHA256,
-                                20, hash, buf ) ) != 0 )
+                                32, hash, buf ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_sign returned -0x%0x\n\n", (unsigned int) -ret );
         goto exit;
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index bbbe0a9..7ec7335 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -139,8 +135,9 @@
         goto exit;
     }
 
-    if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0, buf, &olen,
-                         mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
+    if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0,
+                                 buf, sizeof( buf ), &olen,
+                                 mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_pk_sign returned %d\n\n", ret );
         goto exit;
diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c
index fff568a..1b3e193 100644
--- a/programs/pkey/rsa_verify.c
+++ b/programs/pkey/rsa_verify.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -141,7 +137,7 @@
     }
 
     if( ( ret = mbedtls_rsa_pkcs1_verify( &rsa, MBEDTLS_MD_SHA256,
-                                          20, hash, buf ) ) != 0 )
+                                          32, hash, buf ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_verify returned -0x%0x\n\n", (unsigned int) -ret );
         goto exit;
diff --git a/programs/pkey/rsa_verify_pss.c b/programs/pkey/rsa_verify_pss.c
index 527d799..d6634ba 100644
--- a/programs/pkey/rsa_verify_pss.c
+++ b/programs/pkey/rsa_verify_pss.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/psa/key_ladder_demo.c b/programs/psa/key_ladder_demo.c
index 5d64349..cad875e 100644
--- a/programs/psa/key_ladder_demo.c
+++ b/programs/psa/key_ladder_demo.c
@@ -50,11 +50,7 @@
 /* First include Mbed TLS headers to get the Mbed TLS configuration and
  * platform definitions that we'll use in this program. Also include
  * standard C headers for functions we'll use here. */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/programs/random/gen_entropy.c b/programs/random/gen_entropy.c
index 0f27aaa..4deb924 100644
--- a/programs/random/gen_entropy.c
+++ b/programs/random/gen_entropy.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/random/gen_random_ctr_drbg.c b/programs/random/gen_random_ctr_drbg.c
index 158a312..0a9e2dd 100644
--- a/programs/random/gen_random_ctr_drbg.c
+++ b/programs/random/gen_random_ctr_drbg.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index 1e97795..2bebb0d 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index d2cc450..f257049 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 42dbeac..1e0bef6 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -18,11 +18,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index 6624224..3f7256f 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c
index b04d4b5..5ad9120 100644
--- a/programs/ssl/ssl_context_info.c
+++ b/programs/ssl/ssl_context_info.c
@@ -19,11 +19,7 @@
 
 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 7419010..542a334 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index f223977..32960ad 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -18,17 +18,13 @@
  */
 
 /* Enable definition of gethostname() even when compiling with -std=c99. Must
- * be set before config.h, which pulls in glibc's features.h indirectly.
+ * be set before mbedtls_config.h, which pulls in glibc's features.h indirectly.
  * Harmless on other platforms. */
 
 #define _POSIX_C_SOURCE 200112L
 #define _XOPEN_SOURCE 600
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index a083e4b..a8db4d8 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -18,11 +18,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index aaccb58..ace657c 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index cf608b9..d2aa48a 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1131,7 +1131,7 @@
             ret = mbedtls_pk_sign( key_slot->pk,
                                    ctx->md_alg,
                                    ctx->input, ctx->input_len,
-                                   output, output_len,
+                                   output, output_size, output_len,
                                    config_data->f_rng, config_data->p_rng );
             break;
         default:
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
index bd303bc..f9e031b 100644
--- a/programs/ssl/ssl_test_lib.h
+++ b/programs/ssl/ssl_test_lib.h
@@ -20,11 +20,7 @@
 #ifndef MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H
 #define MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 6a53647..5985caf 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -19,11 +19,7 @@
 
 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/platform.h"
 #if !defined(MBEDTLS_PLATFORM_C)
@@ -1088,7 +1084,7 @@
                                               curve_info->name );
             TIME_PUBLIC( title, "sign",
                     ret = mbedtls_ecdsa_write_signature( &ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
-                                                tmp, &sig_len, myrand, NULL ) );
+                                                tmp, sizeof( tmp ), &sig_len, myrand, NULL ) );
 
             mbedtls_ecdsa_free( &ecdsa );
         }
@@ -1104,7 +1100,7 @@
 
             if( mbedtls_ecdsa_genkey( &ecdsa, curve_info->grp_id, myrand, NULL ) != 0 ||
                 mbedtls_ecdsa_write_signature( &ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
-                                               tmp, &sig_len, myrand, NULL ) != 0 )
+                                               tmp, sizeof( tmp ), &sig_len, myrand, NULL ) != 0 )
             {
                 mbedtls_exit( 1 );
             }
diff --git a/programs/test/cmake_package/.gitignore b/programs/test/cmake_package/.gitignore
new file mode 100644
index 0000000..9ae6b59
--- /dev/null
+++ b/programs/test/cmake_package/.gitignore
@@ -0,0 +1,3 @@
+build
+Makefile
+cmake_package
diff --git a/programs/test/cmake_package/CMakeLists.txt b/programs/test/cmake_package/CMakeLists.txt
new file mode 100644
index 0000000..518d2e9
--- /dev/null
+++ b/programs/test/cmake_package/CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+#
+# Simulate configuring and building Mbed TLS as the user might do it. We'll
+# skip installing it, and use the build directory directly instead.
+#
+
+set(MbedTLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../..")
+set(MbedTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
+
+execute_process(
+    COMMAND "${CMAKE_COMMAND}"
+        "-H${MbedTLS_SOURCE_DIR}"
+        "-B${MbedTLS_BINARY_DIR}"
+        "-DENABLE_PROGRAMS=NO"
+        "-DENABLE_TESTING=NO")
+
+execute_process(
+    COMMAND "${CMAKE_COMMAND}"
+        --build "${MbedTLS_BINARY_DIR}")
+
+#
+# Locate the package.
+#
+
+set(MbedTLS_DIR "${MbedTLS_BINARY_DIR}/cmake")
+find_package(MbedTLS REQUIRED)
+
+#
+# At this point, the Mbed TLS targets should have been imported, and we can now
+# link to them from our own program.
+#
+
+add_executable(cmake_package cmake_package.c)
+target_link_libraries(cmake_package
+    MbedTLS::mbedcrypto MbedTLS::mbedtls MbedTLS::mbedx509)
diff --git a/programs/test/cmake_package/cmake_package.c b/programs/test/cmake_package/cmake_package.c
new file mode 100644
index 0000000..1ae627d
--- /dev/null
+++ b/programs/test/cmake_package/cmake_package.c
@@ -0,0 +1,49 @@
+/*
+ *  Simple program to test that Mbed TLS builds correctly as a CMake package.
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "mbedtls/build_info.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_fprintf         fprintf
+#define mbedtls_printf          printf
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
+#endif /* MBEDTLS_PLATFORM_C */
+
+#include "mbedtls/version.h"
+
+/* The main reason to build this is for testing the CMake build, so the program
+ * doesn't need to do very much. It calls a single library function to ensure
+ * linkage works, but that is all. */
+int main()
+{
+    /* This version string is 18 bytes long, as advised by version.h. */
+    char version[18];
+
+    mbedtls_version_get_string_full( version );
+
+    mbedtls_printf( "Built against %s\n", version );
+
+    return( 0 );
+}
diff --git a/programs/test/cmake_package_install/.gitignore b/programs/test/cmake_package_install/.gitignore
new file mode 100644
index 0000000..b9b8282
--- /dev/null
+++ b/programs/test/cmake_package_install/.gitignore
@@ -0,0 +1,3 @@
+build
+Makefile
+cmake_package_install
diff --git a/programs/test/cmake_package_install/CMakeLists.txt b/programs/test/cmake_package_install/CMakeLists.txt
new file mode 100644
index 0000000..711a1e5
--- /dev/null
+++ b/programs/test/cmake_package_install/CMakeLists.txt
@@ -0,0 +1,39 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+#
+# Simulate configuring and building Mbed TLS as the user might do it. We'll
+# install into a directory inside our own build directory.
+#
+
+set(MbedTLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../..")
+set(MbedTLS_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
+set(MbedTLS_BINARY_DIR "${MbedTLS_INSTALL_DIR}${CMAKE_FILES_DIRECTORY}")
+
+execute_process(
+    COMMAND "${CMAKE_COMMAND}"
+        "-H${MbedTLS_SOURCE_DIR}"
+        "-B${MbedTLS_BINARY_DIR}"
+        "-DENABLE_PROGRAMS=NO"
+        "-DENABLE_TESTING=NO"
+        "-DCMAKE_INSTALL_PREFIX=${MbedTLS_INSTALL_DIR}")
+
+execute_process(
+    COMMAND "${CMAKE_COMMAND}"
+        --build "${MbedTLS_BINARY_DIR}"
+        --target install)
+
+#
+# Locate the package.
+#
+
+set(MbedTLS_DIR "${MbedTLS_INSTALL_DIR}/cmake")
+find_package(MbedTLS REQUIRED)
+
+#
+# At this point, the Mbed TLS targets should have been imported, and we can now
+# link to them from our own program.
+#
+
+add_executable(cmake_package_install cmake_package_install.c)
+target_link_libraries(cmake_package_install
+    MbedTLS::mbedcrypto MbedTLS::mbedtls MbedTLS::mbedx509)
diff --git a/programs/test/cmake_package_install/cmake_package_install.c b/programs/test/cmake_package_install/cmake_package_install.c
new file mode 100644
index 0000000..9d5d3e4
--- /dev/null
+++ b/programs/test/cmake_package_install/cmake_package_install.c
@@ -0,0 +1,50 @@
+/*
+ * Simple program to test that Mbed TLS builds correctly as an installable CMake
+ * package.
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "mbedtls/build_info.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_fprintf         fprintf
+#define mbedtls_printf          printf
+#define mbedtls_exit            exit
+#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
+#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
+#endif /* MBEDTLS_PLATFORM_C */
+
+#include "mbedtls/version.h"
+
+/* The main reason to build this is for testing the CMake build, so the program
+ * doesn't need to do very much. It calls a single library function to ensure
+ * linkage works, but that is all. */
+int main()
+{
+    /* This version string is 18 bytes long, as advised by version.h. */
+    char version[18];
+
+    mbedtls_version_get_string_full( version );
+
+    mbedtls_printf( "Built against %s\n", version );
+
+    return( 0 );
+}
diff --git a/programs/test/cmake_subproject/cmake_subproject.c b/programs/test/cmake_subproject/cmake_subproject.c
index 6d81830..ff6ebf0 100644
--- a/programs/test/cmake_subproject/cmake_subproject.c
+++ b/programs/test/cmake_subproject/cmake_subproject.c
@@ -18,11 +18,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/test/cpp_dummy_build.cpp b/programs/test/cpp_dummy_build.cpp
index 61a7e89..7f1efe8 100644
--- a/programs/test/cpp_dummy_build.cpp
+++ b/programs/test/cpp_dummy_build.cpp
@@ -18,11 +18,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/aes.h"
 #include "mbedtls/aria.h"
diff --git a/programs/test/query_compile_time_config.c b/programs/test/query_compile_time_config.c
index 0e356c8..a6eaf61 100644
--- a/programs/test/query_compile_time_config.c
+++ b/programs/test/query_compile_time_config.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/test/query_config.h b/programs/test/query_config.h
index 23009c4..0fad886 100644
--- a/programs/test/query_config.h
+++ b/programs/test/query_config.h
@@ -1,5 +1,5 @@
 /*
- *  Query Mbed TLS compile time configurations from config.h
+ *  Query Mbed TLS compile time configurations from mbedtls_config.h
  *
  *  Copyright The Mbed TLS Contributors
  *  SPDX-License-Identifier: Apache-2.0
@@ -20,17 +20,13 @@
 #ifndef MBEDTLS_PROGRAMS_TEST_QUERY_CONFIG_H
 #define MBEDTLS_PROGRAMS_TEST_QUERY_CONFIG_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 /** Check whether a given configuration symbol is enabled.
  *
  * \param config    The symbol to query (e.g. "MBEDTLS_RSA_C").
  * \return          \c 0 if the symbol was defined at compile time
- *                  (in MBEDTLS_CONFIG_FILE or config.h),
+ *                  (in MBEDTLS_CONFIG_FILE or mbedtls_config.h),
  *                  \c 1 otherwise.
  *
  * \note            This function is defined in `programs/test/query_config.c`
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 87d8a13..c7bcc53 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -19,11 +19,7 @@
 
 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/entropy.h"
 #include "mbedtls/hmac_drbg.h"
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index 91c231f..307fc74 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -25,11 +25,7 @@
 
 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/test/zeroize.c b/programs/test/zeroize.c
index 5e6b58e..a44099d 100644
--- a/programs/test/zeroize.c
+++ b/programs/test/zeroize.c
@@ -25,11 +25,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stdio.h>
 
diff --git a/programs/util/pem2der.c b/programs/util/pem2der.c
index a2fd0fc..e273200 100644
--- a/programs/util/pem2der.c
+++ b/programs/util/pem2der.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/util/strerror.c b/programs/util/strerror.c
index 6b7e448..4b776d3 100644
--- a/programs/util/strerror.c
+++ b/programs/util/strerror.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index 2adef39..aab15db 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index 0ea2607..ed42079 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index f1e5c6b..9a20d63 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/x509/crl_app.c b/programs/x509/crl_app.c
index db43c54..2720b1d 100644
--- a/programs/x509/crl_app.c
+++ b/programs/x509/crl_app.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/programs/x509/req_app.c b/programs/x509/req_app.c
index e151734..fd316e2 100644
--- a/programs/x509/req_app.c
+++ b/programs/x509/req_app.c
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
diff --git a/scripts/apidoc_full.sh b/scripts/apidoc_full.sh
index 03bbb64..cf01e1f 100755
--- a/scripts/apidoc_full.sh
+++ b/scripts/apidoc_full.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Generate doxygen documentation with a full config.h (this ensures that every
+# Generate doxygen documentation with a full mbedtls_config.h (this ensures that every
 # available flag is documented, and avoids warnings about documentation
 # without a corresponding #define).
 #
@@ -24,7 +24,7 @@
 
 set -eu
 
-CONFIG_H='include/mbedtls/config.h'
+CONFIG_H='include/mbedtls/mbedtls_config.h'
 
 if [ -r $CONFIG_H ]; then :; else
     echo "$CONFIG_H not found" >&2
diff --git a/scripts/config.py b/scripts/config.py
index cbce1eb..6d5edc7 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -26,14 +26,14 @@
 import re
 
 class Setting:
-    """Representation of one Mbed TLS config.h setting.
+    """Representation of one Mbed TLS mbedtls_config.h setting.
 
     Fields:
     * name: the symbol name ('MBEDTLS_xxx').
     * value: the value of the macro. The empty string for a plain #define
       with no value.
     * active: True if name is defined, False if a #define for name is
-      present in config.h but commented out.
+      present in mbedtls_config.h but commented out.
     * section: the name of the section that contains this symbol.
     """
     # pylint: disable=too-few-public-methods
@@ -321,7 +321,7 @@
     and modify the configuration.
     """
 
-    _path_in_tree = 'include/mbedtls/config.h'
+    _path_in_tree = 'include/mbedtls/mbedtls_config.h'
     default_path = [_path_in_tree,
                     os.path.join(os.path.dirname(__file__),
                                  os.pardir,
@@ -363,7 +363,7 @@
     _config_line_regexp = re.compile(r'|'.join([_define_line_regexp,
                                                 _section_line_regexp]))
     def _parse_line(self, line):
-        """Parse a line in config.h and return the corresponding template."""
+        """Parse a line in mbedtls_config.h and return the corresponding template."""
         line = line.rstrip('\r\n')
         m = re.match(self._config_line_regexp, line)
         if m is None:
@@ -384,7 +384,7 @@
             return template
 
     def _format_template(self, name, indent, middle):
-        """Build a line for config.h for the given setting.
+        """Build a line for mbedtls_config.h for the given setting.
 
         The line has the form "<indent>#define <name> <value>"
         where <middle> is "#define <name> ".
@@ -428,7 +428,7 @@
 
 if __name__ == '__main__':
     def main():
-        """Command line config.h manipulation tool."""
+        """Command line mbedtls_config.h manipulation tool."""
         parser = argparse.ArgumentParser(description="""
         Mbed TLS and Mbed Crypto configuration file manipulation tool.
         """)
diff --git a/scripts/data_files/query_config.fmt b/scripts/data_files/query_config.fmt
index c707e4c..ffa816e 100644
--- a/scripts/data_files/query_config.fmt
+++ b/scripts/data_files/query_config.fmt
@@ -1,5 +1,5 @@
 /*
- *  Query Mbed TLS compile time configurations from config.h
+ *  Query Mbed TLS compile time configurations from mbedtls_config.h
  *
  *  Copyright The Mbed TLS Contributors
  *  SPDX-License-Identifier: Apache-2.0
@@ -17,11 +17,7 @@
  *  limitations under the License.
  */
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "query_config.h"
 
@@ -34,7 +30,7 @@
 
 /*
  * Include all the headers with public APIs in case they define a macro to its
- * default value when that configuration is not set in the config.h.
+ * default value when that configuration is not set in the mbedtls_config.h.
  */
 #include "mbedtls/aes.h"
 #include "mbedtls/aria.h"
diff --git a/scripts/ecc-heap.sh b/scripts/ecc-heap.sh
index 8d1beee..acf51f2 100755
--- a/scripts/ecc-heap.sh
+++ b/scripts/ecc-heap.sh
@@ -24,7 +24,7 @@
 
 set -eu
 
-CONFIG_H='include/mbedtls/config.h'
+CONFIG_H='include/mbedtls/mbedtls_config.h'
 
 if [ -r $CONFIG_H ]; then :; else
     echo "$CONFIG_H not found" >&2
@@ -37,7 +37,7 @@
 fi
 
 if git status | grep -F $CONFIG_H >/dev/null 2>&1; then
-    echo "config.h not clean" >&2
+    echo "mbedtls_config.h not clean" >&2
     exit 1
 fi
 
@@ -66,8 +66,6 @@
 #define MBEDTLS_ECP_DP_SECP521R1_ENABLED
 #define MBEDTLS_ECP_DP_CURVE25519_ENABLED
 
-#include "check_config.h"
-
 //#define MBEDTLS_ECP_WINDOW_SIZE            6
 //#define MBEDTLS_ECP_FIXED_POINT_OPTIM      1
 EOF
diff --git a/scripts/ecp_comb_table.py b/scripts/ecp_comb_table.py
index bc11431..6719be1 100755
--- a/scripts/ecp_comb_table.py
+++ b/scripts/ecp_comb_table.py
@@ -126,7 +126,7 @@
     }
     if ( grp.T == NULL ) {
         fprintf( stderr, "grp.T is not generated. Please make sure"
-                         "MBEDTLS_ECP_FIXED_POINT_OPTIM is enabled in config.h\n" );
+                         "MBEDTLS_ECP_FIXED_POINT_OPTIM is enabled in mbedtls_config.h\n" );
         return 1;
     }
     dump_T( &grp );
diff --git a/scripts/footprint.sh b/scripts/footprint.sh
index 4d7be7a..6c0fc25 100755
--- a/scripts/footprint.sh
+++ b/scripts/footprint.sh
@@ -21,7 +21,7 @@
 # configurations, when built for a Cortex M3/M4 target.
 #
 # Configurations included:
-#   default    include/mbedtls/config.h
+#   default    include/mbedtls/mbedtls_config.h
 #   thread     configs/config-thread.h
 #   suite-b    configs/config-suite-b.h
 #   psk        configs/config-ccm-psk-tls1_2.h
@@ -30,7 +30,7 @@
 #
 set -eu
 
-CONFIG_H='include/mbedtls/config.h'
+CONFIG_H='include/mbedtls/mbedtls_config.h'
 
 if [ -r $CONFIG_H ]; then :; else
     echo "$CONFIG_H not found" >&2
@@ -112,7 +112,7 @@
 log "$( arm-none-eabi-gcc --version | head -n1 )"
 log "CFLAGS=$ARMGCC_FLAGS"
 
-doit default    include/mbedtls/config.h
+doit default    include/mbedtls/mbedtls_config.h
 doit thread     configs/config-thread.h
 doit suite-b    configs/config-suite-b.h
 doit psk        configs/config-ccm-psk-tls1_2.h
diff --git a/scripts/generate_features.pl b/scripts/generate_features.pl
index 6b1dcbf..b99c637 100755
--- a/scripts/generate_features.pl
+++ b/scripts/generate_features.pl
@@ -51,7 +51,7 @@
 
 $/ = $line_separator;
 
-open(CONFIG_H, '<:crlf', "$include_dir/config.h") || die("Failure when opening config.h: $!");
+open(CONFIG_H, '<:crlf', "$include_dir/mbedtls_config.h") || die("Failure when opening mbedtls_config.h: $!");
 
 my $feature_defines = "";
 my $in_section = 0;
diff --git a/scripts/generate_query_config.pl b/scripts/generate_query_config.pl
index 7276049..e3bbaa0 100755
--- a/scripts/generate_query_config.pl
+++ b/scripts/generate_query_config.pl
@@ -8,9 +8,9 @@
 # the library, for example, for testing.
 #
 # The query_config.c is generated from the current configuration at
-# include/mbedtls/config.h. The idea is that the config.h contains ALL the
+# include/mbedtls/mbedtls_config.h. The idea is that the mbedtls_config.h contains ALL the
 # compile time configurations available in Mbed TLS (commented or uncommented).
-# This script extracts the configuration macros from the config.h and this
+# This script extracts the configuration macros from the mbedtls_config.h and this
 # information is used to automatically generate the body of the query_config()
 # function by using the template in scripts/data_files/query_config.fmt.
 #
@@ -33,7 +33,7 @@
 
 use strict;
 
-my $config_file = "./include/mbedtls/config.h";
+my $config_file = "./include/mbedtls/mbedtls_config.h";
 
 my $query_config_format_file = "./scripts/data_files/query_config.fmt";
 my $query_config_file = "./programs/test/query_config.c";
@@ -63,9 +63,6 @@
     if ($line =~ /^(\/\/)?\s*#\s*define\s+(MBEDTLS_\w+).*/) {
         my $name = $2;
 
-        # Skip over the macro that prevents multiple inclusion
-        next if "MBEDTLS_CONFIG_H" eq $name;
-
         # Skip over the macro if it is in the ecluded list
         next if $name =~ /$excluded_re/;
 
diff --git a/scripts/mbedtls_dev/crypto_knowledge.py b/scripts/mbedtls_dev/crypto_knowledge.py
index 4b4e2df..c38955b 100644
--- a/scripts/mbedtls_dev/crypto_knowledge.py
+++ b/scripts/mbedtls_dev/crypto_knowledge.py
@@ -19,7 +19,7 @@
 # limitations under the License.
 
 import re
-from typing import Iterable, Optional, Tuple
+from typing import Dict, Iterable, Optional, Pattern, Tuple
 
 from mbedtls_dev.asymmetric_key_data import ASYMMETRIC_KEY_DATA
 
@@ -138,3 +138,18 @@
             return des3[:length]
         return b''.join([self.DATA_BLOCK] * (length // len(self.DATA_BLOCK)) +
                         [self.DATA_BLOCK[:length % len(self.DATA_BLOCK)]])
+
+    KEY_TYPE_FOR_SIGNATURE = {
+        'PSA_KEY_USAGE_SIGN_HASH': re.compile('.*KEY_PAIR'),
+        'PSA_KEY_USAGE_VERIFY_HASH': re.compile('.*KEY.*')
+    } #type: Dict[str, Pattern]
+    """Use a regexp to determine key types for which signature is possible
+       when using the actual usage flag.
+    """
+    def is_valid_for_signature(self, usage: str) -> bool:
+        """Determine if the key type is compatible with the specified
+           signitute type.
+
+        """
+        # This is just temporaly solution for the implicit usage flags.
+        return re.match(self.KEY_TYPE_FOR_SIGNATURE[usage], self.name) is not None
diff --git a/scripts/mbedtls_dev/macro_collector.py b/scripts/mbedtls_dev/macro_collector.py
index 395e038..f9ef5f9 100644
--- a/scripts/mbedtls_dev/macro_collector.py
+++ b/scripts/mbedtls_dev/macro_collector.py
@@ -81,11 +81,15 @@
     `self.arguments_for` for arguments that are not of a kind that is
     enumerated here.
     """
+    #pylint: disable=too-many-instance-attributes
 
     def __init__(self) -> None:
         """Set up an empty set of known constructor macros.
         """
         self.statuses = set() #type: Set[str]
+        self.lifetimes = set() #type: Set[str]
+        self.locations = set() #type: Set[str]
+        self.persistence_levels = set() #type: Set[str]
         self.algorithms = set() #type: Set[str]
         self.ecc_curves = set() #type: Set[str]
         self.dh_groups = set() #type: Set[str]
@@ -97,6 +101,7 @@
         self.kdf_algorithms = set() #type: Set[str]
         self.pake_algorithms = set() #type: Set[str]
         self.aead_algorithms = set() #type: Set[str]
+        self.sign_algorithms = set() #type: Set[str]
         # macro name -> list of argument names
         self.argspecs = {} #type: Dict[str, List[str]]
         # argument name -> list of values
@@ -131,8 +136,12 @@
         self.arguments_for['ka_alg'] = sorted(self.ka_algorithms)
         self.arguments_for['kdf_alg'] = sorted(self.kdf_algorithms)
         self.arguments_for['aead_alg'] = sorted(self.aead_algorithms)
+        self.arguments_for['sign_alg'] = sorted(self.sign_algorithms)
         self.arguments_for['curve'] = sorted(self.ecc_curves)
         self.arguments_for['group'] = sorted(self.dh_groups)
+        self.arguments_for['persistence'] = sorted(self.persistence_levels)
+        self.arguments_for['location'] = sorted(self.locations)
+        self.arguments_for['lifetime'] = sorted(self.lifetimes)
 
     @staticmethod
     def _format_arguments(name: str, arguments: Iterable[str]) -> str:
@@ -341,6 +350,9 @@
             'ALG': self.algorithms,
             'ECC_CURVE': self.ecc_curves,
             'DH_GROUP': self.dh_groups,
+            'KEY_LIFETIME': self.lifetimes,
+            'KEY_LOCATION': self.locations,
+            'KEY_PERSISTENCE': self.persistence_levels,
             'KEY_TYPE': self.key_types,
             'KEY_USAGE': self.key_usage_flags,
         } #type: Dict[str, Set[str]]
@@ -358,15 +370,16 @@
             'hash_algorithm': [self.hash_algorithms],
             'mac_algorithm': [self.mac_algorithms],
             'cipher_algorithm': [],
-            'hmac_algorithm': [self.mac_algorithms],
+            'hmac_algorithm': [self.mac_algorithms, self.sign_algorithms],
             'aead_algorithm': [self.aead_algorithms],
             'key_derivation_algorithm': [self.kdf_algorithms],
             'key_agreement_algorithm': [self.ka_algorithms],
-            'asymmetric_signature_algorithm': [],
+            'asymmetric_signature_algorithm': [self.sign_algorithms],
             'asymmetric_signature_wildcard': [self.algorithms],
             'asymmetric_encryption_algorithm': [],
             'pake_algorithm': [self.pake_algorithms],
             'other_algorithm': [],
+            'lifetime': [self.lifetimes],
         } #type: Dict[str, List[Set[str]]]
         self.arguments_for['mac_length'] += ['1', '63']
         self.arguments_for['min_mac_length'] += ['1', '63']
diff --git a/scripts/mbedtls_dev/psa_storage.py b/scripts/mbedtls_dev/psa_storage.py
index 3a74007..45f0380 100644
--- a/scripts/mbedtls_dev/psa_storage.py
+++ b/scripts/mbedtls_dev/psa_storage.py
@@ -164,6 +164,10 @@
         """
         return self.bytes().hex()
 
+    def location_value(self) -> int:
+        """The numerical value of the location encoded in the key's lifetime."""
+        return self.lifetime.value() >> 8
+
 
 class TestKey(unittest.TestCase):
     # pylint: disable=line-too-long
diff --git a/scripts/memory.sh b/scripts/memory.sh
index c05be74..e3ce9d6 100755
--- a/scripts/memory.sh
+++ b/scripts/memory.sh
@@ -23,7 +23,7 @@
 
 set -eu
 
-CONFIG_H='include/mbedtls/config.h'
+CONFIG_H='include/mbedtls/mbedtls_config.h'
 
 CLIENT='mini_client'
 
@@ -46,7 +46,7 @@
 fi
 
 if git status | grep -F $CONFIG_H >/dev/null 2>&1; then
-    echo "config.h not clean" >&2
+    echo "mbedtls_config.h not clean" >&2
     exit 1
 fi
 
diff --git a/tests/compat.sh b/tests/compat.sh
index 6c1e0d4..c2bef26 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -74,7 +74,7 @@
 # exclude:
 # - NULL: excluded from our default config
 #   avoid plain DES but keep 3DES-EDE-CBC (mbedTLS), DES-CBC3 (OpenSSL)
-# - ARIA: not in default config.h + requires OpenSSL >= 1.1.1
+# - ARIA: not in default mbedtls_config.h + requires OpenSSL >= 1.1.1
 # - ChachaPoly: requires OpenSSL >= 1.1.0
 # - 3DES: not in default config
 EXCLUDE='NULL\|DES\|ARIA\|CHACHA20-POLY1305'
diff --git a/tests/configs/config-wrapper-malloc-0-null.h b/tests/configs/config-wrapper-malloc-0-null.h
index 69a9578..e7bdbeb 100644
--- a/tests/configs/config-wrapper-malloc-0-null.h
+++ b/tests/configs/config-wrapper-malloc-0-null.h
@@ -1,4 +1,4 @@
-/* config.h wrapper that forces calloc(0) to return NULL.
+/* mbedtls_config.h wrapper that forces calloc(0) to return NULL.
  * Used for testing.
  */
 /*
@@ -18,10 +18,7 @@
  *  limitations under the License.
  */
 
-#ifndef MBEDTLS_CONFIG_H
-/* Don't #define MBEDTLS_CONFIG_H, let config.h do it. */
-
-#include "mbedtls/config.h"
+#include "mbedtls/mbedtls_config.h"
 
 #include <stdlib.h>
 static inline void *custom_calloc( size_t nmemb, size_t size )
@@ -33,5 +30,3 @@
 
 #define MBEDTLS_PLATFORM_MEMORY
 #define MBEDTLS_PLATFORM_STD_CALLOC custom_calloc
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/tests/include/spe/crypto_spe.h b/tests/include/spe/crypto_spe.h
new file mode 100644
index 0000000..f80fd86
--- /dev/null
+++ b/tests/include/spe/crypto_spe.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/**
+ * \file crypto_spe.h
+ *
+ * \brief When Mbed Crypto is built with the MBEDTLS_PSA_CRYPTO_SPM option
+ *        enabled, this header is included by all .c files in Mbed Crypto that
+ *        use PSA Crypto function names. This avoids duplication of symbols
+ *        between TF-M and Mbed Crypto.
+ *
+ * \note  This file should be included before including any PSA Crypto headers
+ *        from Mbed Crypto.
+ */
+
+#ifndef CRYPTO_SPE_H
+#define CRYPTO_SPE_H
+
+#define PSA_FUNCTION_NAME(x) mbedcrypto__ ## x
+
+#define psa_crypto_init \
+        PSA_FUNCTION_NAME(psa_crypto_init)
+#define psa_key_derivation_get_capacity \
+        PSA_FUNCTION_NAME(psa_key_derivation_get_capacity)
+#define psa_key_derivation_set_capacity \
+        PSA_FUNCTION_NAME(psa_key_derivation_set_capacity)
+#define psa_key_derivation_input_bytes \
+        PSA_FUNCTION_NAME(psa_key_derivation_input_bytes)
+#define psa_key_derivation_output_bytes \
+        PSA_FUNCTION_NAME(psa_key_derivation_output_bytes)
+#define psa_key_derivation_input_key \
+        PSA_FUNCTION_NAME(psa_key_derivation_input_key)
+#define psa_key_derivation_output_key \
+        PSA_FUNCTION_NAME(psa_key_derivation_output_key)
+#define psa_key_derivation_setup \
+        PSA_FUNCTION_NAME(psa_key_derivation_setup)
+#define psa_key_derivation_abort \
+        PSA_FUNCTION_NAME(psa_key_derivation_abort)
+#define psa_key_derivation_key_agreement \
+        PSA_FUNCTION_NAME(psa_key_derivation_key_agreement)
+#define psa_raw_key_agreement \
+        PSA_FUNCTION_NAME(psa_raw_key_agreement)
+#define psa_generate_random \
+        PSA_FUNCTION_NAME(psa_generate_random)
+#define psa_aead_encrypt \
+        PSA_FUNCTION_NAME(psa_aead_encrypt)
+#define psa_aead_decrypt \
+        PSA_FUNCTION_NAME(psa_aead_decrypt)
+#define psa_open_key \
+        PSA_FUNCTION_NAME(psa_open_key)
+#define psa_close_key \
+        PSA_FUNCTION_NAME(psa_close_key)
+#define psa_import_key \
+        PSA_FUNCTION_NAME(psa_import_key)
+#define psa_destroy_key \
+        PSA_FUNCTION_NAME(psa_destroy_key)
+#define psa_get_key_attributes \
+        PSA_FUNCTION_NAME(psa_get_key_attributes)
+#define psa_reset_key_attributes \
+        PSA_FUNCTION_NAME(psa_reset_key_attributes)
+#define psa_export_key \
+        PSA_FUNCTION_NAME(psa_export_key)
+#define psa_export_public_key \
+        PSA_FUNCTION_NAME(psa_export_public_key)
+#define psa_purge_key \
+        PSA_FUNCTION_NAME(psa_purge_key)
+#define psa_copy_key \
+        PSA_FUNCTION_NAME(psa_copy_key)
+#define psa_cipher_operation_init \
+        PSA_FUNCTION_NAME(psa_cipher_operation_init)
+#define psa_cipher_generate_iv \
+        PSA_FUNCTION_NAME(psa_cipher_generate_iv)
+#define psa_cipher_set_iv \
+        PSA_FUNCTION_NAME(psa_cipher_set_iv)
+#define psa_cipher_encrypt_setup \
+        PSA_FUNCTION_NAME(psa_cipher_encrypt_setup)
+#define psa_cipher_decrypt_setup \
+        PSA_FUNCTION_NAME(psa_cipher_decrypt_setup)
+#define psa_cipher_update \
+        PSA_FUNCTION_NAME(psa_cipher_update)
+#define psa_cipher_finish \
+        PSA_FUNCTION_NAME(psa_cipher_finish)
+#define psa_cipher_abort \
+        PSA_FUNCTION_NAME(psa_cipher_abort)
+#define psa_hash_operation_init \
+        PSA_FUNCTION_NAME(psa_hash_operation_init)
+#define psa_hash_setup \
+        PSA_FUNCTION_NAME(psa_hash_setup)
+#define psa_hash_update \
+        PSA_FUNCTION_NAME(psa_hash_update)
+#define psa_hash_finish \
+        PSA_FUNCTION_NAME(psa_hash_finish)
+#define psa_hash_verify \
+        PSA_FUNCTION_NAME(psa_hash_verify)
+#define psa_hash_abort \
+        PSA_FUNCTION_NAME(psa_hash_abort)
+#define psa_hash_clone \
+        PSA_FUNCTION_NAME(psa_hash_clone)
+#define psa_hash_compute \
+        PSA_FUNCTION_NAME(psa_hash_compute)
+#define psa_hash_compare \
+        PSA_FUNCTION_NAME(psa_hash_compare)
+#define psa_mac_operation_init \
+        PSA_FUNCTION_NAME(psa_mac_operation_init)
+#define psa_mac_sign_setup \
+        PSA_FUNCTION_NAME(psa_mac_sign_setup)
+#define psa_mac_verify_setup \
+        PSA_FUNCTION_NAME(psa_mac_verify_setup)
+#define psa_mac_update \
+        PSA_FUNCTION_NAME(psa_mac_update)
+#define psa_mac_sign_finish \
+        PSA_FUNCTION_NAME(psa_mac_sign_finish)
+#define psa_mac_verify_finish \
+        PSA_FUNCTION_NAME(psa_mac_verify_finish)
+#define psa_mac_abort \
+        PSA_FUNCTION_NAME(psa_mac_abort)
+#define psa_sign_hash \
+        PSA_FUNCTION_NAME(psa_sign_hash)
+#define psa_verify_hash \
+        PSA_FUNCTION_NAME(psa_verify_hash)
+#define psa_asymmetric_encrypt \
+        PSA_FUNCTION_NAME(psa_asymmetric_encrypt)
+#define psa_asymmetric_decrypt \
+        PSA_FUNCTION_NAME(psa_asymmetric_decrypt)
+#define psa_generate_key \
+        PSA_FUNCTION_NAME(psa_generate_key)
+
+#endif /* CRYPTO_SPE_H */
diff --git a/tests/include/test/certs.h b/tests/include/test/certs.h
index c93c741..03f0d03 100644
--- a/tests/include/test/certs.h
+++ b/tests/include/test/certs.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_CERTS_H
 #define MBEDTLS_CERTS_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
diff --git a/tests/include/test/constant_flow.h b/tests/include/test/constant_flow.h
index af64011..9626af9 100644
--- a/tests/include/test/constant_flow.h
+++ b/tests/include/test/constant_flow.h
@@ -24,11 +24,7 @@
 #ifndef TEST_CONSTANT_FLOW_H
 #define TEST_CONSTANT_FLOW_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 /*
  * This file defines the two macros
diff --git a/tests/include/test/drivers/aead.h b/tests/include/test/drivers/aead.h
index 2207cb3..0830229 100644
--- a/tests/include/test/drivers/aead.h
+++ b/tests/include/test/drivers/aead.h
@@ -20,11 +20,7 @@
 #ifndef PSA_CRYPTO_TEST_DRIVERS_AEAD_H
 #define PSA_CRYPTO_TEST_DRIVERS_AEAD_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 #include <psa/crypto_driver_common.h>
diff --git a/tests/include/test/drivers/cipher.h b/tests/include/test/drivers/cipher.h
index 4fe5596..142f3b7 100644
--- a/tests/include/test/drivers/cipher.h
+++ b/tests/include/test/drivers/cipher.h
@@ -20,11 +20,7 @@
 #ifndef PSA_CRYPTO_TEST_DRIVERS_CIPHER_H
 #define PSA_CRYPTO_TEST_DRIVERS_CIPHER_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 #include <psa/crypto_driver_common.h>
diff --git a/tests/include/test/drivers/hash.h b/tests/include/test/drivers/hash.h
index ebe83de..d202c8b 100644
--- a/tests/include/test/drivers/hash.h
+++ b/tests/include/test/drivers/hash.h
@@ -20,11 +20,7 @@
 #ifndef PSA_CRYPTO_TEST_DRIVERS_HASH_H
 #define PSA_CRYPTO_TEST_DRIVERS_HASH_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 #include <psa/crypto_driver_common.h>
diff --git a/tests/include/test/drivers/key_management.h b/tests/include/test/drivers/key_management.h
index 45814fd..16e1f75 100644
--- a/tests/include/test/drivers/key_management.h
+++ b/tests/include/test/drivers/key_management.h
@@ -20,11 +20,7 @@
 #ifndef PSA_CRYPTO_TEST_DRIVERS_KEY_MANAGEMENT_H
 #define PSA_CRYPTO_TEST_DRIVERS_KEY_MANAGEMENT_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 #include <psa/crypto_driver_common.h>
diff --git a/tests/include/test/drivers/mac.h b/tests/include/test/drivers/mac.h
index 7733dd3..5f6cd38 100644
--- a/tests/include/test/drivers/mac.h
+++ b/tests/include/test/drivers/mac.h
@@ -20,11 +20,7 @@
 #ifndef PSA_CRYPTO_TEST_DRIVERS_MAC_H
 #define PSA_CRYPTO_TEST_DRIVERS_MAC_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 #include <psa/crypto_driver_common.h>
diff --git a/tests/include/test/drivers/signature.h b/tests/include/test/drivers/signature.h
index 5e64edc..67f2b29 100644
--- a/tests/include/test/drivers/signature.h
+++ b/tests/include/test/drivers/signature.h
@@ -20,11 +20,7 @@
 #ifndef PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H
 #define PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 #include <psa/crypto_driver_common.h>
diff --git a/tests/include/test/drivers/size.h b/tests/include/test/drivers/size.h
index b2665bd..4e3301c 100644
--- a/tests/include/test/drivers/size.h
+++ b/tests/include/test/drivers/size.h
@@ -20,11 +20,7 @@
 #ifndef PSA_CRYPTO_TEST_DRIVERS_SIZE_H
 #define PSA_CRYPTO_TEST_DRIVERS_SIZE_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 #include <psa/crypto_driver_common.h>
diff --git a/tests/include/test/fake_external_rng_for_test.h b/tests/include/test/fake_external_rng_for_test.h
index faeef22..9d56dab 100644
--- a/tests/include/test/fake_external_rng_for_test.h
+++ b/tests/include/test/fake_external_rng_for_test.h
@@ -22,11 +22,7 @@
 #ifndef FAKE_EXTERNAL_RNG_FOR_TEST_H
 #define FAKE_EXTERNAL_RNG_FOR_TEST_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
 /** Enable the insecure implementation of mbedtls_psa_external_get_random().
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index ab9a0c3..27e5599 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -30,11 +30,7 @@
  * directly (without using the MBEDTLS_PRIVATE wrapper). */
 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_PTHREAD) && \
     defined(MBEDTLS_TEST_HOOKS)
@@ -59,6 +55,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
 typedef enum
 {
     MBEDTLS_TEST_RESULT_SUCCESS = 0,
@@ -210,4 +210,25 @@
                                  const char *file, int line);
 #endif
 
+#if defined(MBEDTLS_BIGNUM_C)
+/** Read an MPI from a string.
+ *
+ * Like mbedtls_mpi_read_string(), but size the resulting bignum based
+ * on the number of digits in the string. In particular, construct a
+ * bignum with 0 limbs for an empty string, and a bignum with leading 0
+ * limbs if the string has sufficiently many leading 0 digits.
+ *
+ * This is important so that the "0 (null)" and "0 (1 limb)" and
+ * "leading zeros" test cases do what they claim.
+ *
+ * \param[out] X        The MPI object to populate. It must be initialized.
+ * \param radix         The radix (2 to 16).
+ * \param[in] s         The null-terminated string to read from.
+ *
+ * \return \c 0 on success, an \c MBEDTLS_ERR_MPI_xxx error code otherwise.
+ */
+/* Since the library has exactly the desired behavior, this is trivial. */
+int mbedtls_test_read_mpi( mbedtls_mpi *X, int radix, const char *s );
+#endif /* MBEDTLS_BIGNUM_C */
+
 #endif /* TEST_HELPERS_H */
diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h
index 87e86d3..9b3fc9c 100644
--- a/tests/include/test/macros.h
+++ b/tests/include/test/macros.h
@@ -24,11 +24,7 @@
 #ifndef TEST_MACROS_H
 #define TEST_MACROS_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stdlib.h>
 
diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h
index 9881eae..8a8c37e 100644
--- a/tests/include/test/psa_crypto_helpers.h
+++ b/tests/include/test/psa_crypto_helpers.h
@@ -186,6 +186,14 @@
 
 #endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */
 
+/** Return extended key usage policies.
+ *
+ * Do a key policy permission extension on key usage policies always involves
+ * permissions of other usage policies
+ * (like PSA_KEY_USAGE_SIGN_HASH involves PSA_KEY_USAGE_SIGN_MESSGAE).
+ */
+psa_key_usage_t mbedtls_test_update_key_usage_flags( psa_key_usage_t usage_flags );
+
 /** Skip a test case if the given key is a 192 bits AES key and the AES
  *  implementation is at least partially provided by an accelerator or
  *  alternative implementation.
diff --git a/tests/include/test/random.h b/tests/include/test/random.h
index 6428280..58548a2 100644
--- a/tests/include/test/random.h
+++ b/tests/include/test/random.h
@@ -25,11 +25,7 @@
 #ifndef TEST_RANDOM_H
 #define TEST_RANDOM_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 #include <stdint.h>
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index fe53669..f8e43c8 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -34,7 +34,7 @@
 # Warning: the test is destructive. It includes various build modes and
 # configurations, and can and will arbitrarily change the current CMake
 # configuration. The following files must be committed into git:
-#    * include/mbedtls/config.h
+#    * include/mbedtls/mbedtls_config.h
 #    * Makefile, library/Makefile, programs/Makefile, tests/Makefile,
 #      programs/fuzz/Makefile
 # After running this script, the CMake cache will be lost and CMake
@@ -85,7 +85,7 @@
 # means that components can assume that the working directory is in a
 # cleaned-up state, and don't need to perform the cleanup themselves.
 # * Run `make clean`.
-# * Restore `include/mbedtks/config.h` from a backup made before running
+# * Restore `include/mbedtls/mbedtls_config.h` from a backup made before running
 #   the component.
 # * Check out `Makefile`, `library/Makefile`, `programs/Makefile`,
 #   `tests/Makefile` and `programs/fuzz/Makefile` from git.
@@ -125,7 +125,7 @@
 }
 
 pre_initialize_variables () {
-    CONFIG_H='include/mbedtls/config.h'
+    CONFIG_H='include/mbedtls/mbedtls_config.h'
     CONFIG_BAK="$CONFIG_H.bak"
     CRYPTO_CONFIG_H='include/psa/crypto_config.h'
     CRYPTO_CONFIG_BAK="$CRYPTO_CONFIG_H.bak"
@@ -273,7 +273,7 @@
            -iname CMakeFiles -exec rm -rf {} \+ -o \
            \( -iname cmake_install.cmake -o \
               -iname CTestTestfile.cmake -o \
-              -iname CMakeCache.txt \) -exec rm {} \+
+              -iname CMakeCache.txt \) -exec rm -f {} \+
     # Recover files overwritten by in-tree CMake builds
     rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile
     git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile programs/fuzz/Makefile
@@ -284,6 +284,16 @@
     rm -f programs/test/cmake_subproject/Makefile
     rm -f programs/test/cmake_subproject/cmake_subproject
 
+    # Remove any artifacts from the component_test_cmake_as_package test.
+    rm -rf programs/test/cmake_package/build
+    rm -f programs/test/cmake_package/Makefile
+    rm -f programs/test/cmake_package/cmake_package
+
+    # Remove any artifacts from the component_test_cmake_as_installed_package test.
+    rm -rf programs/test/cmake_package_install/build
+    rm -f programs/test/cmake_package_install/Makefile
+    rm -f programs/test/cmake_package_install/cmake_package_install
+
     if [ -f "$CONFIG_BAK" ]; then
         mv "$CONFIG_BAK" "$CONFIG_H"
     fi
@@ -453,8 +463,8 @@
             exit 1
         fi
 
-        if ! git diff --quiet include/mbedtls/config.h; then
-            err_msg "Warning - the configuration file 'include/mbedtls/config.h' has been edited. "
+        if ! git diff --quiet include/mbedtls/mbedtls_config.h; then
+            err_msg "Warning - the configuration file 'include/mbedtls/mbedtls_config.h' has been edited. "
             echo "You can either delete or preserve your work, or force the test by rerunning the"
             echo "script as: $0 --force"
             exit 1
@@ -820,6 +830,32 @@
     make test
 }
 
+# check_renamed_symbols HEADER LIB
+# Check that if HEADER contains '#define MACRO ...' then MACRO is not a symbol
+# name is LIB.
+check_renamed_symbols () {
+    ! nm "$2" | sed 's/.* //' |
+      grep -x -F "$(sed -n 's/^ *# *define  *\([A-Z_a-z][0-9A-Z_a-z]*\)..*/\1/p' "$1")"
+}
+
+component_build_psa_crypto_spm () {
+    msg "build: full config - USE_PSA_CRYPTO + PSA_CRYPTO_KEY_ID_ENCODES_OWNER + PSA_CRYPTO_SPM, make, gcc"
+    scripts/config.py full
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_SPM
+    # We can only compile, not link, since our test and sample programs
+    # aren't equipped for the modified names used when MBEDTLS_PSA_CRYPTO_SPM
+    # is active.
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -I../tests/include/spe' lib
+
+    # Check that if a symbol is renamed by crypto_spe.h, the non-renamed
+    # version is not present.
+    echo "Checking for renamed symbols in the library"
+    if_build_succeeded check_renamed_symbols tests/include/spe/crypto_spe.h library/libmbedcrypto.a
+}
+
 component_test_psa_crypto_client () {
     msg "build: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT, make"
     scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
@@ -2514,6 +2550,32 @@
     unset MBEDTLS_ROOT_DIR
 }
 
+component_test_cmake_as_package () {
+    msg "build: cmake 'as-package' build"
+    MBEDTLS_ROOT_DIR="$PWD"
+
+    cd programs/test/cmake_package
+    cmake .
+    make
+    if_build_succeeded ./cmake_package
+
+    cd "$MBEDTLS_ROOT_DIR"
+    unset MBEDTLS_ROOT_DIR
+}
+
+component_test_cmake_as_package_install () {
+    msg "build: cmake 'as-installed-package' build"
+    MBEDTLS_ROOT_DIR="$PWD"
+
+    cd programs/test/cmake_package_install
+    cmake .
+    make
+    if_build_succeeded ./cmake_package_install
+
+    cd "$MBEDTLS_ROOT_DIR"
+    unset MBEDTLS_ROOT_DIR
+}
+
 component_test_zeroize () {
     # Test that the function mbedtls_platform_zeroize() is not optimized away by
     # different combinations of compilers and optimization flags by using an
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
index 8fcde6f..83aa87a 100755
--- a/tests/scripts/basic-build-test.sh
+++ b/tests/scripts/basic-build-test.sh
@@ -30,7 +30,7 @@
 #
 # The tests focus on functionality and do not consider performance.
 #
-# Note the tests self-adapt due to configurations in include/mbedtls/config.h
+# Note the tests self-adapt due to configurations in include/mbedtls/mbedtls_config.h
 # which can lead to some tests being skipped, and can cause the number of
 # available tests to fluctuate.
 #
@@ -68,7 +68,7 @@
 export GNUTLS_CLI="$GNUTLS_CLI"
 export GNUTLS_SERV="$GNUTLS_SERV"
 
-CONFIG_H='include/mbedtls/config.h'
+CONFIG_H='include/mbedtls/mbedtls_config.h'
 CONFIG_BAK="$CONFIG_H.bak"
 
 # Step 0 - print build environment info
diff --git a/tests/scripts/curves.pl b/tests/scripts/curves.pl
index 2572e93..47196f4 100755
--- a/tests/scripts/curves.pl
+++ b/tests/scripts/curves.pl
@@ -36,7 +36,7 @@
 #
 # This script should be executed from the root of the project directory.
 #
-# Only curves that are enabled in config.h will be tested.
+# Only curves that are enabled in mbedtls_config.h will be tested.
 #
 # For best effect, run either with cmake disabled, or cmake enabled in a mode
 # that includes -Werror.
@@ -47,7 +47,7 @@
 -d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
 
 my $sed_cmd = 's/^#define \(MBEDTLS_ECP_DP.*_ENABLED\)/\1/p';
-my $config_h = 'include/mbedtls/config.h';
+my $config_h = 'include/mbedtls/mbedtls_config.h';
 my @curves = split( /\s+/, `sed -n -e '$sed_cmd' $config_h` );
 
 # Determine which curves support ECDSA by checking the dependencies of
diff --git a/tests/scripts/depends-hashes.pl b/tests/scripts/depends-hashes.pl
index c5f1521..cd17066 100755
--- a/tests/scripts/depends-hashes.pl
+++ b/tests/scripts/depends-hashes.pl
@@ -42,7 +42,7 @@
 
 -d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
 
-my $config_h = 'include/mbedtls/config.h';
+my $config_h = 'include/mbedtls/mbedtls_config.h';
 
 # as many SSL options depend on specific hashes,
 # and SSL is not in the test suites anyways,
diff --git a/tests/scripts/depends-pkalgs.pl b/tests/scripts/depends-pkalgs.pl
index 2ad4a7c..6eb7269 100755
--- a/tests/scripts/depends-pkalgs.pl
+++ b/tests/scripts/depends-pkalgs.pl
@@ -43,7 +43,7 @@
 
 -d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
 
-my $config_h = 'include/mbedtls/config.h';
+my $config_h = 'include/mbedtls/mbedtls_config.h';
 
 # Some algorithms can't be disabled on their own as others depend on them, so
 # we list those reverse-dependencies here to keep check_config.h happy.
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index 8c53414..b59ed74 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -233,9 +233,50 @@
 class StorageKey(psa_storage.Key):
     """Representation of a key for storage format testing."""
 
-    def __init__(self, *, description: str, **kwargs) -> None:
+    IMPLICIT_USAGE_FLAGS = {
+        'PSA_KEY_USAGE_SIGN_HASH': 'PSA_KEY_USAGE_SIGN_MESSAGE',
+        'PSA_KEY_USAGE_VERIFY_HASH': 'PSA_KEY_USAGE_VERIFY_MESSAGE'
+    } #type: Dict[str, str]
+    """Mapping of usage flags to the flags that they imply."""
+
+    def __init__(
+            self,
+            usage: str,
+            without_implicit_usage: Optional[bool] = False,
+            **kwargs
+    ) -> None:
+        """Prepare to generate a key.
+
+        * `usage`                 : The usage flags used for the key.
+        * `without_implicit_usage`: Flag to defide to apply the usage extension
+        """
+        super().__init__(usage=usage, **kwargs)
+
+        if not without_implicit_usage:
+            for flag, implicit in self.IMPLICIT_USAGE_FLAGS.items():
+                if self.usage.value() & psa_storage.Expr(flag).value() and \
+                   self.usage.value() & psa_storage.Expr(implicit).value() == 0:
+                    self.usage = psa_storage.Expr(self.usage.string + ' | ' + implicit)
+
+class StorageTestData(StorageKey):
+    """Representation of test case data for storage format testing."""
+
+    def __init__(
+            self,
+            description: str,
+            expected_usage: Optional[str] = None,
+            **kwargs
+    ) -> None:
+        """Prepare to generate test data
+
+        * `description`   : used for the the test case names
+        * `expected_usage`: the usage flags generated as the expected usage flags
+                            in the test cases. CAn differ from the usage flags
+                            stored in the keys because of the usage flags extension.
+        """
         super().__init__(**kwargs)
         self.description = description #type: str
+        self.expected_usage = expected_usage if expected_usage else self.usage.string #type: str
 
 class StorageFormat:
     """Storage format stability test cases."""
@@ -250,11 +291,11 @@
           generate backward compatibility test cases which inject a key
           representation and check that it can be read and used.
         """
-        self.constructors = info.constructors
-        self.version = version
-        self.forward = forward
+        self.constructors = info.constructors #type: macro_collector.PSAMacroEnumerator
+        self.version = version #type: int
+        self.forward = forward #type: bool
 
-    def make_test_case(self, key: StorageKey) -> test_case.TestCase:
+    def make_test_case(self, key: StorageTestData) -> test_case.TestCase:
         """Construct a storage format test case for the given key.
 
         If ``forward`` is true, generate a forward compatibility test case:
@@ -268,7 +309,7 @@
         tc.set_description('PSA storage {}: {}'.format(verb, key.description))
         dependencies = automatic_dependencies(
             key.lifetime.string, key.type.string,
-            key.usage.string, key.alg.string, key.alg2.string,
+            key.expected_usage, key.alg.string, key.alg2.string,
         )
         dependencies = finish_family_dependencies(dependencies, key.bits)
         tc.set_dependencies(dependencies)
@@ -289,46 +330,99 @@
             extra_arguments = [' | '.join(flags) if flags else '0']
         tc.set_arguments([key.lifetime.string,
                           key.type.string, str(key.bits),
-                          key.usage.string, key.alg.string, key.alg2.string,
+                          key.expected_usage, key.alg.string, key.alg2.string,
                           '"' + key.material.hex() + '"',
                           '"' + key.hex() + '"',
                           *extra_arguments])
         return tc
 
-    def key_for_usage_flags(
+    def key_for_lifetime(
+            self,
+            lifetime: str,
+    ) -> StorageTestData:
+        """Construct a test key for the given lifetime."""
+        short = lifetime
+        short = re.sub(r'PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION',
+                       r'', short)
+        short = re.sub(r'PSA_KEY_[A-Z]+_', r'', short)
+        description = 'lifetime: ' + short
+        key = StorageTestData(version=self.version,
+                              id=1, lifetime=lifetime,
+                              type='PSA_KEY_TYPE_RAW_DATA', bits=8,
+                              usage='PSA_KEY_USAGE_EXPORT', alg=0, alg2=0,
+                              material=b'L',
+                              description=description)
+        return key
+
+    def all_keys_for_lifetimes(self) -> Iterator[StorageTestData]:
+        """Generate test keys covering lifetimes."""
+        lifetimes = sorted(self.constructors.lifetimes)
+        expressions = self.constructors.generate_expressions(lifetimes)
+        for lifetime in expressions:
+            # Don't attempt to create or load a volatile key in storage
+            if 'VOLATILE' in lifetime:
+                continue
+            # Don't attempt to create a read-only key in storage,
+            # but do attempt to load one.
+            if 'READ_ONLY' in lifetime and self.forward:
+                continue
+            yield self.key_for_lifetime(lifetime)
+
+    def keys_for_usage_flags(
             self,
             usage_flags: List[str],
-            short: Optional[str] = None
-    ) -> StorageKey:
+            short: Optional[str] = None,
+            test_implicit_usage: Optional[bool] = False
+    ) -> Iterator[StorageTestData]:
         """Construct a test key for the given key usage."""
         usage = ' | '.join(usage_flags) if usage_flags else '0'
         if short is None:
             short = re.sub(r'\bPSA_KEY_USAGE_', r'', usage)
-        description = 'usage: ' + short
-        key = StorageKey(version=self.version,
-                         id=1, lifetime=0x00000001,
-                         type='PSA_KEY_TYPE_RAW_DATA', bits=8,
-                         usage=usage, alg=0, alg2=0,
-                         material=b'K',
-                         description=description)
-        return key
+        extra_desc = ' with implication' if test_implicit_usage else ''
+        description = 'usage' + extra_desc + ': ' + short
+        key1 = StorageTestData(version=self.version,
+                               id=1, lifetime=0x00000001,
+                               type='PSA_KEY_TYPE_RAW_DATA', bits=8,
+                               expected_usage=usage,
+                               usage=usage, alg=0, alg2=0,
+                               material=b'K',
+                               description=description)
+        yield key1
 
-    def all_keys_for_usage_flags(self) -> Iterator[StorageKey]:
+        if test_implicit_usage:
+            description = 'usage without implication' + ': ' + short
+            key2 = StorageTestData(version=self.version,
+                                   id=1, lifetime=0x00000001,
+                                   type='PSA_KEY_TYPE_RAW_DATA', bits=8,
+                                   without_implicit_usage=True,
+                                   usage=usage, alg=0, alg2=0,
+                                   material=b'K',
+                                   description=description)
+            yield key2
+
+    def generate_keys_for_usage_flags(self, **kwargs) -> Iterator[StorageTestData]:
         """Generate test keys covering usage flags."""
         known_flags = sorted(self.constructors.key_usage_flags)
-        yield self.key_for_usage_flags(['0'])
+        yield from self.keys_for_usage_flags(['0'], **kwargs)
         for usage_flag in known_flags:
-            yield self.key_for_usage_flags([usage_flag])
+            yield from self.keys_for_usage_flags([usage_flag], **kwargs)
         for flag1, flag2 in zip(known_flags,
                                 known_flags[1:] + [known_flags[0]]):
-            yield self.key_for_usage_flags([flag1, flag2])
-        yield self.key_for_usage_flags(known_flags, short='all known')
+            yield from self.keys_for_usage_flags([flag1, flag2], **kwargs)
+
+    def generate_key_for_all_usage_flags(self) -> Iterator[StorageTestData]:
+        known_flags = sorted(self.constructors.key_usage_flags)
+        yield from self.keys_for_usage_flags(known_flags, short='all known')
+
+    def all_keys_for_usage_flags(self) -> Iterator[StorageTestData]:
+        yield from self.generate_keys_for_usage_flags()
+        yield from self.generate_key_for_all_usage_flags()
 
     def keys_for_type(
             self,
             key_type: str,
             params: Optional[Iterable[str]] = None
-    ) -> Iterator[StorageKey]:
+    ) -> Iterator[StorageTestData]:
         """Generate test keys for the given key type.
 
         For key types that depend on a parameter (e.g. elliptic curve family),
@@ -345,21 +439,21 @@
                                       r'',
                                       kt.expression)
             description = 'type: {} {}-bit'.format(short_expression, bits)
-            key = StorageKey(version=self.version,
-                             id=1, lifetime=0x00000001,
-                             type=kt.expression, bits=bits,
-                             usage=usage_flags, alg=alg, alg2=alg2,
-                             material=key_material,
-                             description=description)
+            key = StorageTestData(version=self.version,
+                                  id=1, lifetime=0x00000001,
+                                  type=kt.expression, bits=bits,
+                                  usage=usage_flags, alg=alg, alg2=alg2,
+                                  material=key_material,
+                                  description=description)
             yield key
 
-    def all_keys_for_types(self) -> Iterator[StorageKey]:
+    def all_keys_for_types(self) -> Iterator[StorageTestData]:
         """Generate test keys covering key types and their representations."""
         key_types = sorted(self.constructors.key_types)
         for key_type in self.constructors.generate_expressions(key_types):
             yield from self.keys_for_type(key_type)
 
-    def keys_for_algorithm(self, alg: str) -> Iterator[StorageKey]:
+    def keys_for_algorithm(self, alg: str) -> Iterator[StorageTestData]:
         """Generate test keys for the specified algorithm."""
         # For now, we don't have information on the compatibility of key
         # types and algorithms. So we just test the encoding of algorithms,
@@ -367,41 +461,167 @@
         descr = re.sub(r'PSA_ALG_', r'', alg)
         descr = re.sub(r',', r', ', re.sub(r' +', r'', descr))
         usage = 'PSA_KEY_USAGE_EXPORT'
-        key1 = StorageKey(version=self.version,
-                          id=1, lifetime=0x00000001,
-                          type='PSA_KEY_TYPE_RAW_DATA', bits=8,
-                          usage=usage, alg=alg, alg2=0,
-                          material=b'K',
-                          description='alg: ' + descr)
+        key1 = StorageTestData(version=self.version,
+                               id=1, lifetime=0x00000001,
+                               type='PSA_KEY_TYPE_RAW_DATA', bits=8,
+                               usage=usage, alg=alg, alg2=0,
+                               material=b'K',
+                               description='alg: ' + descr)
         yield key1
-        key2 = StorageKey(version=self.version,
-                          id=1, lifetime=0x00000001,
-                          type='PSA_KEY_TYPE_RAW_DATA', bits=8,
-                          usage=usage, alg=0, alg2=alg,
-                          material=b'L',
-                          description='alg2: ' + descr)
+        key2 = StorageTestData(version=self.version,
+                               id=1, lifetime=0x00000001,
+                               type='PSA_KEY_TYPE_RAW_DATA', bits=8,
+                               usage=usage, alg=0, alg2=alg,
+                               material=b'L',
+                               description='alg2: ' + descr)
         yield key2
 
-    def all_keys_for_algorithms(self) -> Iterator[StorageKey]:
+    def all_keys_for_algorithms(self) -> Iterator[StorageTestData]:
         """Generate test keys covering algorithm encodings."""
         algorithms = sorted(self.constructors.algorithms)
         for alg in self.constructors.generate_expressions(algorithms):
             yield from self.keys_for_algorithm(alg)
 
+    def generate_all_keys(self) -> Iterator[StorageTestData]:
+        """Generate all keys for the test cases."""
+        yield from self.all_keys_for_lifetimes()
+        yield from self.all_keys_for_usage_flags()
+        yield from self.all_keys_for_types()
+        yield from self.all_keys_for_algorithms()
+
     def all_test_cases(self) -> Iterator[test_case.TestCase]:
         """Generate all storage format test cases."""
         # First build a list of all keys, then construct all the corresponding
         # test cases. This allows all required information to be obtained in
         # one go, which is a significant performance gain as the information
         # includes numerical values obtained by compiling a C program.
-        keys = [] #type: List[StorageKey]
-        keys += self.all_keys_for_usage_flags()
-        keys += self.all_keys_for_types()
-        keys += self.all_keys_for_algorithms()
-        for key in keys:
+        for key in self.generate_all_keys():
+            if key.location_value() != 0:
+                # Skip keys with a non-default location, because they
+                # require a driver and we currently have no mechanism to
+                # determine whether a driver is available.
+                continue
             yield self.make_test_case(key)
-        # To do: vary id, lifetime
 
+class StorageFormatForward(StorageFormat):
+    """Storage format stability test cases for forward compatibility."""
+
+    def __init__(self, info: Information, version: int) -> None:
+        super().__init__(info, version, True)
+
+class StorageFormatV0(StorageFormat):
+    """Storage format stability test cases for version 0 compatibility."""
+
+    def __init__(self, info: Information) -> None:
+        super().__init__(info, 0, False)
+
+    def all_keys_for_usage_flags(self) -> Iterator[StorageTestData]:
+        """Generate test keys covering usage flags."""
+        yield from self.generate_keys_for_usage_flags(test_implicit_usage=True)
+        yield from self.generate_key_for_all_usage_flags()
+
+    def keys_for_implicit_usage(
+            self,
+            implyer_usage: str,
+            alg: str,
+            key_type: crypto_knowledge.KeyType
+    ) -> StorageTestData:
+        # pylint: disable=too-many-locals
+        """Generate test keys for the specified implicit usage flag,
+           algorithm and key type combination.
+        """
+        bits = key_type.sizes_to_test()[0]
+        implicit_usage = StorageKey.IMPLICIT_USAGE_FLAGS[implyer_usage]
+        usage_flags = 'PSA_KEY_USAGE_EXPORT'
+        material_usage_flags = usage_flags + ' | ' + implyer_usage
+        expected_usage_flags = material_usage_flags + ' | ' + implicit_usage
+        alg2 = 0
+        key_material = key_type.key_material(bits)
+        usage_expression = re.sub(r'PSA_KEY_USAGE_', r'', implyer_usage)
+        alg_expression = re.sub(r'PSA_ALG_', r'', alg)
+        alg_expression = re.sub(r',', r', ', re.sub(r' +', r'', alg_expression))
+        key_type_expression = re.sub(r'\bPSA_(?:KEY_TYPE|ECC_FAMILY)_',
+                                     r'',
+                                     key_type.expression)
+        description = 'implied by {}: {} {} {}-bit'.format(
+            usage_expression, alg_expression, key_type_expression, bits)
+        key = StorageTestData(version=self.version,
+                              id=1, lifetime=0x00000001,
+                              type=key_type.expression, bits=bits,
+                              usage=material_usage_flags,
+                              expected_usage=expected_usage_flags,
+                              without_implicit_usage=True,
+                              alg=alg, alg2=alg2,
+                              material=key_material,
+                              description=description)
+        return key
+
+    def gather_key_types_for_sign_alg(self) -> Dict[str, List[str]]:
+        # pylint: disable=too-many-locals
+        """Match possible key types for sign algorithms."""
+        # To create a valid combinaton both the algorithms and key types
+        # must be filtered. Pair them with keywords created from its names.
+        incompatible_alg_keyword = frozenset(['RAW', 'ANY', 'PURE'])
+        incompatible_key_type_keywords = frozenset(['MONTGOMERY'])
+        keyword_translation = {
+            'ECDSA': 'ECC',
+            'ED[0-9]*.*' : 'EDWARDS'
+        }
+        exclusive_keywords = {
+            'EDWARDS': 'ECC'
+        }
+        key_types = set(self.constructors.generate_expressions(self.constructors.key_types))
+        algorithms = set(self.constructors.generate_expressions(self.constructors.sign_algorithms))
+        alg_with_keys = {} #type: Dict[str, List[str]]
+        translation_table = str.maketrans('(', '_', ')')
+        for alg in algorithms:
+            # Generate keywords from the name of the algorithm
+            alg_keywords = set(alg.partition('(')[0].split(sep='_')[2:])
+            # Translate keywords for better matching with the key types
+            for keyword in alg_keywords.copy():
+                for pattern, replace in keyword_translation.items():
+                    if re.match(pattern, keyword):
+                        alg_keywords.remove(keyword)
+                        alg_keywords.add(replace)
+            # Filter out incompatible algortihms
+            if not alg_keywords.isdisjoint(incompatible_alg_keyword):
+                continue
+
+            for key_type in key_types:
+                # Generate keywords from the of the key type
+                key_type_keywords = set(key_type.translate(translation_table).split(sep='_')[3:])
+
+                # Remove ambigious keywords
+                for keyword1, keyword2 in exclusive_keywords.items():
+                    if keyword1 in key_type_keywords:
+                        key_type_keywords.remove(keyword2)
+
+                if key_type_keywords.isdisjoint(incompatible_key_type_keywords) and\
+                   not key_type_keywords.isdisjoint(alg_keywords):
+                    if alg in alg_with_keys:
+                        alg_with_keys[alg].append(key_type)
+                    else:
+                        alg_with_keys[alg] = [key_type]
+        return alg_with_keys
+
+    def all_keys_for_implicit_usage(self) -> Iterator[StorageTestData]:
+        """Generate test keys for usage flag extensions."""
+        # Generate a key type and algorithm pair for each extendable usage
+        # flag to generate a valid key for exercising. The key is generated
+        # without usage extension to check the extension compatiblity.
+        alg_with_keys = self.gather_key_types_for_sign_alg()
+
+        for usage in sorted(StorageKey.IMPLICIT_USAGE_FLAGS, key=str):
+            for alg in sorted(alg_with_keys):
+                for key_type in sorted(alg_with_keys[alg]):
+                    # The key types must be filtered to fit the specific usage flag.
+                    kt = crypto_knowledge.KeyType(key_type)
+                    if kt.is_valid_for_signature(usage):
+                        yield self.keys_for_implicit_usage(usage, alg, kt)
+
+    def generate_all_keys(self) -> Iterator[StorageTestData]:
+        yield from super().generate_all_keys()
+        yield from self.all_keys_for_implicit_usage()
 
 class TestGenerator:
     """Generate test data."""
@@ -433,9 +653,9 @@
         'test_suite_psa_crypto_not_supported.generated':
         lambda info: NotSupported(info).test_cases_for_not_supported(),
         'test_suite_psa_crypto_storage_format.current':
-        lambda info: StorageFormat(info, 0, True).all_test_cases(),
+        lambda info: StorageFormatForward(info, 0).all_test_cases(),
         'test_suite_psa_crypto_storage_format.v0':
-        lambda info: StorageFormat(info, 0, False).all_test_cases(),
+        lambda info: StorageFormatV0(info).all_test_cases(),
     } #type: Dict[str, Callable[[Information], Iterable[test_case.TestCase]]]
 
     def generate_target(self, name: str) -> None:
diff --git a/tests/scripts/key-exchanges.pl b/tests/scripts/key-exchanges.pl
index 20f3aa6..46f1b97 100755
--- a/tests/scripts/key-exchanges.pl
+++ b/tests/scripts/key-exchanges.pl
@@ -40,7 +40,7 @@
 -d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
 
 my $sed_cmd = 's/^#define \(MBEDTLS_KEY_EXCHANGE_.*_ENABLED\)/\1/p';
-my $config_h = 'include/mbedtls/config.h';
+my $config_h = 'include/mbedtls/mbedtls_config.h';
 my @kexes = split( /\s+/, `sed -n -e '$sed_cmd' $config_h` );
 
 system( "cp $config_h $config_h.bak" ) and die;
diff --git a/tests/scripts/list-symbols.sh b/tests/scripts/list-symbols.sh
index 8bdc55f..4a5d035 100755
--- a/tests/scripts/list-symbols.sh
+++ b/tests/scripts/list-symbols.sh
@@ -27,7 +27,7 @@
     exit 1
 fi
 
-cp include/mbedtls/config.h include/mbedtls/config.h.bak
+cp include/mbedtls/mbedtls_config.h include/mbedtls/mbedtls_config.h.bak
 scripts/config.py full
 make clean
 make_ret=
@@ -39,7 +39,7 @@
     cat list-symbols.make.log >&2
   }
 rm list-symbols.make.log
-mv include/mbedtls/config.h.bak include/mbedtls/config.h
+mv include/mbedtls/mbedtls_config.h.bak include/mbedtls/mbedtls_config.h
 if [ -n "$make_ret" ]; then
     exit "$make_ret"
 fi
diff --git a/tests/scripts/set_psa_test_dependencies.py b/tests/scripts/set_psa_test_dependencies.py
index 2705f06..7f4ebeb 100755
--- a/tests/scripts/set_psa_test_dependencies.py
+++ b/tests/scripts/set_psa_test_dependencies.py
@@ -23,7 +23,7 @@
 import sys
 
 CLASSIC_DEPENDENCIES = frozenset([
-    # This list is manually filtered from config.h.
+    # This list is manually filtered from mbedtls_config.h.
 
     # Mbed TLS feature support.
     # Only features that affect what can be done are listed here.
diff --git a/tests/scripts/test-ref-configs.pl b/tests/scripts/test-ref-configs.pl
index a79604e..dd24db7 100755
--- a/tests/scripts/test-ref-configs.pl
+++ b/tests/scripts/test-ref-configs.pl
@@ -60,7 +60,7 @@
 
 -d 'library' && -d 'include' && -d 'tests' or die "Must be run from root\n";
 
-my $config_h = 'include/mbedtls/config.h';
+my $config_h = 'include/mbedtls/mbedtls_config.h';
 
 system( "cp $config_h $config_h.bak" ) and die;
 sub abort {
diff --git a/tests/scripts/test_config_script.py b/tests/scripts/test_config_script.py
index 8ca4103..e230e3c 100755
--- a/tests/scripts/test_config_script.py
+++ b/tests/scripts/test_config_script.py
@@ -8,7 +8,7 @@
 Sample usage:
 
     test_config_script.py -d old
-    ## Modify config.py and/or config.h ##
+    ## Modify config.py and/or mbedtls_config.h ##
     test_config_script.py -d new
     diff -ru old new
 """
@@ -170,7 +170,7 @@
                         dest='output_directory', required=True,
                         help="""Output directory.""")
     parser.add_argument('-f', metavar='FILE',
-                        dest='input_file', default='include/mbedtls/config.h',
+                        dest='input_file', default='include/mbedtls/mbedtls_config.h',
                         help="""Config file (default: %(default)s).""")
     parser.add_argument('-p', metavar='PRESET,...',
                         dest='presets',
diff --git a/tests/src/drivers/test_driver_cipher.c b/tests/src/drivers/test_driver_cipher.c
index 9c95cc8..89a7b59 100644
--- a/tests/src/drivers/test_driver_cipher.c
+++ b/tests/src/drivers/test_driver_cipher.c
@@ -35,26 +35,19 @@
 mbedtls_test_driver_cipher_hooks_t mbedtls_test_driver_cipher_hooks =
     MBEDTLS_TEST_DRIVER_CIPHER_INIT;
 
-static psa_status_t mbedtls_test_transparent_cipher_oneshot(
-    mbedtls_operation_t direction,
+psa_status_t mbedtls_test_transparent_cipher_encrypt(
     const psa_key_attributes_t *attributes,
-    const uint8_t *key, size_t key_length,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
-    const uint8_t *input, size_t input_length,
-    uint8_t *output, size_t output_size, size_t *output_length)
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
 {
     mbedtls_test_driver_cipher_hooks.hits++;
 
-    /* Test driver supports AES-CTR only, to verify operation calls. */
-    if( alg != PSA_ALG_CTR ||
-        psa_get_key_type( attributes ) != PSA_KEY_TYPE_AES )
-        return( PSA_ERROR_NOT_SUPPORTED );
-
-    /* If test driver response code is not SUCCESS, we can return early */
-    if( mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS )
-        return( mbedtls_test_driver_cipher_hooks.forced_status );
-
-    /* If test driver output is overridden, we don't need to do actual crypto */
     if( mbedtls_test_driver_cipher_hooks.forced_output != NULL )
     {
         if( output_size < mbedtls_test_driver_cipher_hooks.forced_output_length )
@@ -68,133 +61,50 @@
         return( mbedtls_test_driver_cipher_hooks.forced_status );
     }
 
-    /* Run AES-CTR using the cipher module */
-    {
-        mbedtls_test_rnd_pseudo_info rnd_info;
-        memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
+    if( mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS )
+        return( mbedtls_test_driver_cipher_hooks.forced_status );
 
-        const mbedtls_cipher_info_t *cipher_info =
-            mbedtls_cipher_info_from_values( MBEDTLS_CIPHER_ID_AES,
-                                             key_length * 8,
-                                             MBEDTLS_MODE_CTR );
-        mbedtls_cipher_context_t cipher;
-        int ret = 0;
-        uint8_t temp_output_buffer[16] = {0};
-        size_t temp_output_length = 0;
+    psa_generate_random( output, PSA_CIPHER_IV_LENGTH( attributes->core.type, alg ) );
 
-        if( direction == MBEDTLS_ENCRYPT )
-        {
-            /* Oneshot encrypt needs to prepend the IV to the output */
-            if( output_size < ( input_length + 16 ) )
-                return( PSA_ERROR_BUFFER_TOO_SMALL );
-        }
-        else
-        {
-            /* Oneshot decrypt has the IV prepended to the input */
-            if( output_size < ( input_length - 16 ) )
-                return( PSA_ERROR_BUFFER_TOO_SMALL );
-        }
-
-        if( cipher_info == NULL )
-            return( PSA_ERROR_NOT_SUPPORTED );
-
-        mbedtls_cipher_init( &cipher );
-        ret = mbedtls_cipher_setup( &cipher, cipher_info );
-        if( ret != 0 )
-            goto exit;
-
-        ret = mbedtls_cipher_setkey( &cipher,
-                                     key,
-                                     key_length * 8, direction );
-        if( ret != 0 )
-            goto exit;
-
-        if( direction == MBEDTLS_ENCRYPT )
-        {
-            mbedtls_test_rnd_pseudo_info rnd_info;
-            memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
-
-            ret = mbedtls_test_rnd_pseudo_rand( &rnd_info,
-                                                temp_output_buffer,
-                                                16 );
-            if( ret != 0 )
-                goto exit;
-
-            ret = mbedtls_cipher_set_iv( &cipher, temp_output_buffer, 16 );
-        }
-        else
-            ret = mbedtls_cipher_set_iv( &cipher, input, 16 );
-
-        if( ret != 0 )
-            goto exit;
-
-        if( direction == MBEDTLS_ENCRYPT )
-        {
-            ret = mbedtls_cipher_update( &cipher,
-                                         input, input_length,
-                                         &output[16], output_length );
-            if( ret == 0 )
-            {
-                memcpy( output, temp_output_buffer, 16 );
-                *output_length += 16;
-            }
-        }
-        else
-            ret = mbedtls_cipher_update( &cipher,
-                                         &input[16], input_length - 16,
-                                         output, output_length );
-
-        if( ret != 0 )
-            goto exit;
-
-        ret = mbedtls_cipher_finish( &cipher,
-                                     temp_output_buffer,
-                                     &temp_output_length );
-
-exit:
-        if( ret != 0 )
-        {
-            *output_length = 0;
-            memset(output, 0, output_size);
-        }
-
-        mbedtls_cipher_free( &cipher );
-        return( mbedtls_to_psa_error( ret ) );
-    }
-}
-
-psa_status_t mbedtls_test_transparent_cipher_encrypt(
-    const psa_key_attributes_t *attributes,
-    const uint8_t *key, size_t key_length,
-    psa_algorithm_t alg,
-    const uint8_t *input, size_t input_length,
-    uint8_t *output, size_t output_size, size_t *output_length)
-{
-    return (
-        mbedtls_test_transparent_cipher_oneshot(
-            MBEDTLS_ENCRYPT,
-            attributes,
-            key, key_length,
-            alg,
-            input, input_length,
-            output, output_size, output_length) );
+    return( mbedtls_transparent_test_driver_cipher_encrypt(
+                attributes, key_buffer, key_buffer_size,
+                alg, input, input_length,
+                output, output_size, output_length ) );
 }
 
 psa_status_t mbedtls_test_transparent_cipher_decrypt(
     const psa_key_attributes_t *attributes,
-    const uint8_t *key, size_t key_length,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
-    const uint8_t *input, size_t input_length,
-    uint8_t *output, size_t output_size, size_t *output_length)
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
 {
-    return (
-        mbedtls_test_transparent_cipher_oneshot(
-            MBEDTLS_DECRYPT,
-            attributes,
-            key, key_length,
-            alg,
-            input, input_length,
-            output, output_size, output_length) );
+   mbedtls_test_driver_cipher_hooks.hits++;
+
+    if( mbedtls_test_driver_cipher_hooks.forced_output != NULL )
+    {
+        if( output_size < mbedtls_test_driver_cipher_hooks.forced_output_length )
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+
+        memcpy( output,
+                mbedtls_test_driver_cipher_hooks.forced_output,
+                mbedtls_test_driver_cipher_hooks.forced_output_length );
+        *output_length = mbedtls_test_driver_cipher_hooks.forced_output_length;
+
+        return( mbedtls_test_driver_cipher_hooks.forced_status );
+    }
+
+    if( mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS )
+        return( mbedtls_test_driver_cipher_hooks.forced_status );
+
+    return( mbedtls_transparent_test_driver_cipher_decrypt(
+                attributes, key_buffer, key_buffer_size,
+                alg, input, input_length,
+                output, output_size, output_length ) );
 }
 
 psa_status_t mbedtls_test_transparent_cipher_encrypt_setup(
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index cac6d4c..4d3d53d 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -259,3 +259,18 @@
     }
 }
 #endif /* MBEDTLS_TEST_HOOKS */
+
+#if defined(MBEDTLS_BIGNUM_C)
+int mbedtls_test_read_mpi( mbedtls_mpi *X, int radix, const char *s )
+{
+    /* mbedtls_mpi_read_string() currently retains leading zeros.
+     * It always allocates at least one limb for the value 0. */
+    if( s[0] == 0 )
+    {
+        mbedtls_mpi_free( X );
+        return( 0 );
+    }
+    else
+        return( mbedtls_mpi_read_string( X, radix, s ) );
+}
+#endif
diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c
index f2222cb..d9d841a 100644
--- a/tests/src/psa_crypto_helpers.c
+++ b/tests/src/psa_crypto_helpers.c
@@ -114,4 +114,17 @@
 }
 #endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */
 
+psa_key_usage_t mbedtls_test_update_key_usage_flags( psa_key_usage_t usage_flags )
+{
+    psa_key_usage_t updated_usage = usage_flags;
+
+    if( usage_flags & PSA_KEY_USAGE_SIGN_HASH )
+        updated_usage |= PSA_KEY_USAGE_SIGN_MESSAGE;
+
+    if( usage_flags & PSA_KEY_USAGE_VERIFY_HASH )
+        updated_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
+
+    return( updated_usage );
+}
+
 #endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c
index f48a64e..e4e55c9 100644
--- a/tests/src/psa_exercise_key.c
+++ b/tests/src/psa_exercise_key.c
@@ -316,13 +316,14 @@
     #endif
         }
 
+        /* Some algorithms require the payload to have the size of
+         * the hash encoded in the algorithm. Use this input size
+         * even for algorithms that allow other input sizes. */
+        if( hash_alg != 0 )
+            payload_length = PSA_HASH_LENGTH( hash_alg );
+
         if( usage & PSA_KEY_USAGE_SIGN_HASH )
         {
-            /* Some algorithms require the payload to have the size of
-             * the hash encoded in the algorithm. Use this input size
-             * even for algorithms that allow other input sizes. */
-            if( hash_alg != 0 )
-                payload_length = PSA_HASH_LENGTH( hash_alg );
             PSA_ASSERT( psa_sign_hash( key, alg,
                                        payload, payload_length,
                                        signature, sizeof( signature ),
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index c8e4985..0729755 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -51,7 +51,7 @@
 : ${PERL:=perl}
 
 guess_config_name() {
-    if git diff --quiet ../include/mbedtls/config.h 2>/dev/null; then
+    if git diff --quiet ../include/mbedtls/mbedtls_config.h 2>/dev/null; then
         echo "default"
     else
         echo "unknown"
@@ -93,7 +93,7 @@
 FAILS=0
 SKIPS=0
 
-CONFIG_H='../include/mbedtls/config.h'
+CONFIG_H='../include/mbedtls/mbedtls_config.h'
 
 MEMCHECK=0
 FILTER='.*'
@@ -178,7 +178,7 @@
         ;;
 esac
 
-# Read boolean configuration options from config.h for easy and quick
+# Read boolean configuration options from mbedtls_config.h for easy and quick
 # testing. Skip non-boolean options (with something other than spaces
 # and a comment after "#define SYMBOL"). The variable contains a
 # space-separated list of symbols.
@@ -194,7 +194,7 @@
     SKIP_NEXT="YES"
 }
 
-# skip next test if the flag is not enabled in config.h
+# skip next test if the flag is not enabled in mbedtls_config.h
 requires_config_enabled() {
     case $CONFIGS_ENABLED in
         *" $1 "*) :;;
@@ -202,7 +202,7 @@
     esac
 }
 
-# skip next test if the flag is enabled in config.h
+# skip next test if the flag is enabled in mbedtls_config.h
 requires_config_disabled() {
     case $CONFIGS_ENABLED in
         *" $1 "*) SKIP_NEXT="YES";;
@@ -257,8 +257,7 @@
 # maybe_requires_ciphersuite_enabled CMD [RUN_TEST_OPTION...]
 # If CMD (call to a TLS client or server program) requires a specific
 # ciphersuite, arrange to only run the test case if this ciphersuite is
-# enabled. As an exception, do run the test case if it expects a ciphersuite
-# mismatch.
+# enabled.
 maybe_requires_ciphersuite_enabled() {
     case "$1" in
         *\ force_ciphersuite=*) :;;
@@ -268,15 +267,7 @@
     ciphersuite="${ciphersuite%%[!-0-9A-Z_a-z]*}"
     shift
 
-    case "$*" in
-        *"-s SSL - The server has no ciphersuites in common"*)
-            # This test case expects a ciphersuite mismatch, so it doesn't
-            # require the ciphersuite to be enabled.
-            ;;
-        *)
-            requires_ciphersuite_enabled "$ciphersuite"
-            ;;
-    esac
+    requires_ciphersuite_enabled "$ciphersuite"
 
     unset ciphersuite
 }
@@ -3146,7 +3137,7 @@
 
 # Checks that no Signature Algorithm with SHA-1 gets negotiated. Negotiating SHA-1 would mean that
 # the server did not parse the Signature Algorithm extension. This test is valid only if an MD
-# algorithm stronger than SHA-1 is enabled in config.h
+# algorithm stronger than SHA-1 is enabled in mbedtls_config.h
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Renegotiation: Signature Algorithms parsing, client-initiated" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional" \
@@ -3164,7 +3155,7 @@
 
 # Checks that no Signature Algorithm with SHA-1 gets negotiated. Negotiating SHA-1 would mean that
 # the server did not parse the Signature Algorithm extension. This test is valid only if an MD
-# algorithm stronger than SHA-1 is enabled in config.h
+# algorithm stronger than SHA-1 is enabled in mbedtls_config.h
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Renegotiation: Signature Algorithms parsing, server-initiated" \
             "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional renegotiate=1" \
@@ -5132,7 +5123,7 @@
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123" \
             0 \
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5146,7 +5137,7 @@
             -S "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5160,7 +5151,7 @@
             -S "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5174,7 +5165,7 @@
             -S "skip PMS generation for opaque PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5188,7 +5179,7 @@
             -S "skip PMS generation for opaque PSK"\
             -c "session hash for extended master secret"\
             -s "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5202,7 +5193,7 @@
             -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5216,7 +5207,7 @@
             -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5231,7 +5222,7 @@
             -s "session hash for extended master secret"\
             -C "skip PMS generation for opaque PSK"\
             -s "skip PMS generation for opaque PSK"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5246,7 +5237,7 @@
             -s "session hash for extended master secret"\
             -C "skip PMS generation for opaque PSK"\
             -s "skip PMS generation for opaque PSK"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5260,7 +5251,7 @@
             -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5274,7 +5265,7 @@
             -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5289,7 +5280,7 @@
             -s "session hash for extended master secret"\
             -C "skip PMS generation for opaque PSK"\
             -s "skip PMS generation for opaque PSK"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5304,7 +5295,7 @@
             -s "session hash for extended master secret"\
             -C "skip PMS generation for opaque PSK"\
             -s "skip PMS generation for opaque PSK"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5318,7 +5309,7 @@
             -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5332,7 +5323,7 @@
             -s "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5345,7 +5336,7 @@
             -C "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5358,7 +5349,7 @@
             -C "skip PMS generation for opaque PSK"\
             -C "session hash for extended master secret"\
             -S "session hash for extended master secret"\
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5375,7 +5366,7 @@
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123" \
             1 \
-            -s "SSL - None of the common ciphersuites is usable" \
+            -s "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5384,7 +5375,7 @@
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=foo psk=abc123" \
             1 \
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -s "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5393,7 +5384,7 @@
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=abc psk=dead" \
             0 \
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5402,7 +5393,7 @@
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=def psk=beef" \
             0 \
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5411,7 +5402,7 @@
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=ghi psk=beef" \
             1 \
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -s "SSL - Unknown identity received" \
             -S "SSL - Verification of the message MAC failed"
 
@@ -5420,7 +5411,7 @@
             "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
             psk_identity=abc psk=beef" \
             1 \
-            -S "SSL - None of the common ciphersuites is usable" \
+            -S "SSL - The handshake negotiation failed" \
             -S "SSL - Unknown identity received" \
             -s "SSL - Verification of the message MAC failed"
 
@@ -5438,7 +5429,7 @@
             -S "ciphersuite mismatch: ecjpake not configured" \
             -S "server hello, ecjpake kkpp extension" \
             -C "found ecjpake_kkpp extension" \
-            -S "None of the common ciphersuites is usable"
+            -S "SSL - The handshake negotiation failed"
 
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: server not configured" \
@@ -5453,7 +5444,7 @@
             -s "ciphersuite mismatch: ecjpake not configured" \
             -S "server hello, ecjpake kkpp extension" \
             -C "found ecjpake_kkpp extension" \
-            -s "None of the common ciphersuites is usable"
+            -s "SSL - The handshake negotiation failed"
 
 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: working, TLS" \
@@ -5469,11 +5460,11 @@
             -S "ciphersuite mismatch: ecjpake not configured" \
             -s "server hello, ecjpake kkpp extension" \
             -c "found ecjpake_kkpp extension" \
-            -S "None of the common ciphersuites is usable" \
+            -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
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: password mismatch, TLS" \
             "$P_SRV debug_level=3 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 ecjpake_pw=bad \
@@ -5482,7 +5473,7 @@
             -C "re-using cached ecjpake parameters" \
             -s "SSL - Verification of the message MAC failed"
 
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: working, DTLS" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bla \
@@ -5491,7 +5482,7 @@
             -c "re-using cached ecjpake parameters" \
             -S "SSL - Verification of the message MAC failed"
 
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: working, DTLS, no cookie" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla cookies=0" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bla \
@@ -5501,7 +5492,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 server_needs_more_time 1
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: password mismatch, DTLS" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bad \
@@ -5511,7 +5502,7 @@
             -s "SSL - Verification of the message MAC failed"
 
 # for tests with configs/config-thread.h
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: working, DTLS, nolog" \
             "$P_SRV dtls=1 ecjpake_pw=bla" \
             "$P_CLI dtls=1 ecjpake_pw=bla \
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 1278d95..52b586e 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -23,11 +23,7 @@
 #endif
 #endif
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include <mbedtls/config.h>
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 /* Test code may use deprecated identifiers only if the preprocessor symbol
  * MBEDTLS_TEST_DEPRECATED is defined. When building tests, set
diff --git a/tests/suites/test_suite_asn1parse.function b/tests/suites/test_suite_asn1parse.function
index abcd1db..535274b 100644
--- a/tests/suites/test_suite_asn1parse.function
+++ b/tests/suites/test_suite_asn1parse.function
@@ -417,7 +417,7 @@
     }
 
 #if defined(MBEDTLS_BIGNUM_C)
-    ret = mbedtls_mpi_read_string( &expected_mpi, 16, expected_hex );
+    ret = mbedtls_test_read_mpi( &expected_mpi, 16, expected_hex );
     TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
     if( ret == MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
     {
diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function
index fda6939..197a7ef 100644
--- a/tests/suites/test_suite_debug.function
+++ b/tests/suites/test_suite_debug.function
@@ -179,9 +179,7 @@
 
     TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
 
-    /* If value is empty, keep val->n == 0. */
-    if( value[0] != 0 )
-        TEST_ASSERT( mbedtls_mpi_read_string( &val, radix, value ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &val, radix, value ) == 0 );
 
     mbedtls_ssl_conf_dbg( &conf, string_debug, &buffer);
 
diff --git a/tests/suites/test_suite_dhm.data b/tests/suites/test_suite_dhm.data
index e5fb428..f18db2e 100644
--- a/tests/suites/test_suite_dhm.data
+++ b/tests/suites/test_suite_dhm.data
@@ -70,18 +70,36 @@
 Diffie-Hellman full exchange: 286-bit
 dhm_do_dhm:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":36:10:"9345098309485093845098340962223981329819812792137312973297123912791271":0
 
-Diffie-Hellman trivial subgroup #1
-dhm_do_dhm:10:"23":1:10:"1":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
-
-Diffie-Hellman trivial subgroup #2
-dhm_do_dhm:10:"23":1:10:"-1":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
-
 Diffie-Hellman small modulus
 dhm_do_dhm:10:"3":1:10:"5":MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED+MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
 Diffie-Hellman zero modulus
 dhm_do_dhm:10:"0":1:10:"5":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
 
+Diffie-Hellman with G=0
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"0":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"1":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=-1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"-1":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=P-1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409622":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=P-2
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409621":0
+
+Diffie-Hellman with G=P
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409623":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=P+1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409624":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=P+2
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409625":0
+
 Diffie-Hellman: x_size < 0
 dhm_do_dhm:10:"93450983094850938450983409623":-1:10:"9345098304850938450983409622":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
 
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index 5286bc7..bc43016 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -116,8 +116,8 @@
     /*
      * Set params
      */
-    TEST_ASSERT( mbedtls_mpi_read_string( &ctx_srv.P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &ctx_srv.G, radix_G, input_G ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.G, radix_G, input_G ) == 0 );
     pub_cli_len = mbedtls_mpi_size( &ctx_srv.P );
     TEST_ASSERT( check_get_value( &ctx_srv, MBEDTLS_DHM_PARAM_P, &ctx_srv.P ) );
     TEST_ASSERT( check_get_value( &ctx_srv, MBEDTLS_DHM_PARAM_G, &ctx_srv.G ) );
@@ -239,7 +239,7 @@
     TEST_ASSERT( mbedtls_mpi_shift_l( &P, ( P_bytes * 8 ) - 1 ) == 0 );
     TEST_ASSERT( mbedtls_mpi_set_bit( &P, 0, 1 ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &G, radix_G, input_G ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &G, radix_G, input_G ) == 0 );
 
     TEST_ASSERT( mbedtls_dhm_set_group( &ctx, &P, &G ) == 0 );
     TEST_ASSERT( mbedtls_dhm_make_public( &ctx, (int) mbedtls_mpi_size( &P ),
@@ -263,8 +263,8 @@
     mbedtls_dhm_init( &ctx );
     mbedtls_mpi_init( &P ); mbedtls_mpi_init( &G );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, 16, p ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &G, 16, g ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, 16, p ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &G, 16, g ) == 0 );
 
     TEST_ASSERT( mbedtls_dhm_parse_dhmfile( &ctx, filename ) == 0 );
 
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index 94030d8..6893bcf 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -157,21 +157,21 @@
                                           mbedtls_test_rnd_buffer_rand,
                                           &rnd_info_A ) == 0 );
     TEST_ASSERT( ! mbedtls_ecp_is_zero( &qA ) );
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, xA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, xA_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qA.X, &check ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, yA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, yA_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qA.Y, &check ) == 0 );
 
     TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dB, &qB,
                                           mbedtls_test_rnd_buffer_rand,
                                           &rnd_info_B ) == 0 );
     TEST_ASSERT( ! mbedtls_ecp_is_zero( &qB ) );
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, xB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, xB_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.X, &check ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, yB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, yB_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.Y, &check ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, z_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, z_str ) == 0 );
     TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zA, &qB, &dA,
                                               &mbedtls_test_rnd_pseudo_rand,
                                               &rnd_info ) == 0 );
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index 354f178..4496812 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -92,9 +92,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
     TEST_ASSERT( mbedtls_ecp_point_read_string( &Q, 16, xQ_str, yQ_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, d_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &r_check, 16, r_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &s_check, 16, s_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &d, 16, d_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &r_check, 16, r_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &s_check, 16, s_str ) == 0 );
     rnd_info.fallback_f_rng = mbedtls_test_rnd_std_rand;
     rnd_info.fallback_p_rng = NULL;
     rnd_info.buf = rnd_buf->x;
@@ -157,9 +157,9 @@
     memset( hash, 0, sizeof( hash ) );
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, d_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &r_check, 16, r_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &s_check, 16, s_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &d, 16, d_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &r_check, 16, r_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &s_check, 16, s_str ) == 0 );
 
     md_info = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md_info != NULL );
@@ -205,7 +205,7 @@
     /* generate and write signature, then read and verify it */
     TEST_ASSERT( mbedtls_ecdsa_write_signature( &ctx, MBEDTLS_MD_SHA256,
                  hash, sizeof( hash ),
-                 sig, &sig_len, &mbedtls_test_rnd_pseudo_rand,
+                 sig, sizeof( sig ), &sig_len, &mbedtls_test_rnd_pseudo_rand,
                  &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
                  sig, sig_len ) == 0 );
@@ -269,7 +269,7 @@
     /* generate and write signature, then read and verify it */
     TEST_ASSERT( mbedtls_ecdsa_write_signature( &ctx, MBEDTLS_MD_SHA256,
                  hash, sizeof( hash ),
-                 sig, &sig_len, &mbedtls_test_rnd_pseudo_rand,
+                 sig, sizeof( sig ), &sig_len, &mbedtls_test_rnd_pseudo_rand,
                  &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
                  sig, sig_len ) == 0 );
@@ -388,7 +388,7 @@
     memset( sig, 0, sizeof( sig ) );
 
     TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.d, 16, d_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &ctx.d, 16, d_str ) == 0 );
 
     md_info = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md_info != NULL );
@@ -404,8 +404,8 @@
     cnt_restart = 0;
     do {
         ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
-                md_alg, hash, hlen, sig, &slen, mbedtls_test_rnd_std_rand, NULL,
-                &rs_ctx );
+                md_alg, hash, hlen, sig, sizeof( sig ), &slen,
+                mbedtls_test_rnd_std_rand, NULL, &rs_ctx );
     } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
 
     TEST_ASSERT( ret == 0 );
@@ -420,8 +420,8 @@
     if( min_restart > 0 )
     {
         ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
-                md_alg, hash, hlen, sig, &slen, mbedtls_test_rnd_std_rand, NULL,
-                &rs_ctx );
+                md_alg, hash, hlen, sig, sizeof( sig ), &slen,
+                mbedtls_test_rnd_std_rand, NULL, &rs_ctx );
         TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
     }
 
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index d795fe2..2afc355 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -82,9 +82,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, grp_id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.X, 16, x_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.Y, 16, y_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.Z, 16, z_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.X, 16, x_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.Y, 16, y_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.Z, 16, z_hex ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &P ) == ret );
 
@@ -135,13 +135,13 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yA, 16, yA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dA, 16, dA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xA, 16, xA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yA, 16, yA_str ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xZ, 16, xZ_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yZ, 16, yZ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dB, 16, dB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xZ, 16, xZ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yZ, 16, yZ_str ) == 0 );
 
     mbedtls_ecp_set_max_ops( (unsigned) max_ops );
 
@@ -222,13 +222,13 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &u1, 16, u1_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &u2, 16, u2_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xR, 16, xR_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yR, 16, yR_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &u1, 16, u1_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &u2, 16, u2_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xR, 16, xR_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yR, 16, yR_str ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q.X, 16, xQ_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q.Y, 16, yQ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q.X, 16, xQ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q.Y, 16, yQ_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_lset( &Q.Z, 1 ) == 0 );
 
     mbedtls_ecp_set_max_ops( (unsigned) max_ops );
@@ -285,14 +285,14 @@
 
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &grp.G ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yA, 16, yA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xB, 16, xB_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yB, 16, yB_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xZ, 16, xZ_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yZ, 16, yZ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dA, 16, dA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xA, 16, xA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yA, 16, yA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dB, 16, dB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xB, 16, xB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yB, 16, yB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xZ, 16, xZ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yZ, 16, yZ_str ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &grp.G,
                           &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == 0 );
@@ -342,11 +342,11 @@
 
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &grp.G ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xB, 16, xB_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xS, 16, xS_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dA, 16, dA_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dB, 16, dB_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xA, 16, xA_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xB, 16, xB_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xS, 16, xS_hex ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &grp.G,
                           &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == 0 );
@@ -508,7 +508,7 @@
     mbedtls_mpi_init( &N ); mbedtls_mpi_init( &R );
     mbedtls_ecp_group_init( &grp );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, 16, N_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, 16, N_str ) == 0 );
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
     TEST_ASSERT( grp.modp != NULL );
 
@@ -547,9 +547,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.X, 16, x ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.Y, 16, y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.Z, 16, z ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.X, 16, x ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.Y, 16, y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.Z, 16, z ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_point_write_binary( &grp, &P, format,
                                    &olen, buf, blen ) == ret );
@@ -579,9 +579,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Z, 16, z ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, x ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Z, 16, z ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_point_read_binary( &grp, &P, buf->x, buf->len ) == ret );
 
@@ -623,9 +623,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Z, 16, z ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, x ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Z, 16, z ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_tls_read_point( &grp, &P, &vbuf, buf->len ) == ret );
 
@@ -760,7 +760,7 @@
     mbedtls_mpi_init( &d );
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, key_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &d, 16, key_hex ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_check_privkey( &grp, &d ) == ret );
 
@@ -789,7 +789,7 @@
     if( id != MBEDTLS_ECP_DP_NONE )
         TEST_ASSERT( mbedtls_ecp_group_load( &prv.grp, id ) == 0 );
     TEST_ASSERT( mbedtls_ecp_point_read_string( &prv.Q, 16, Qx, Qy ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &prv.d, 16, d ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &prv.d, 16, d ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_check_pub_priv( &pub, &prv,
                           &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == ret );
diff --git a/tests/suites/test_suite_gcm.aes128_de.data b/tests/suites/test_suite_gcm.aes128_de.data
index c865b0c..3df31e5 100644
--- a/tests/suites/test_suite_gcm.aes128_de.data
+++ b/tests/suites/test_suite_gcm.aes128_de.data
@@ -670,6 +670,58 @@
 depends_on:MBEDTLS_AES_C
 gcm_decrypt_and_verify:MBEDTLS_CIPHER_ID_AES:"659b9e729d12f68b73fdc2f7260ab114":"fd0732a38224c3f16f58de3a7f333da2ecdb6eec92b469544a891966dd4f8fb64a711a793f1ef6a90e49765eacaccdd8cc438c2b57c51902d27a82ee4f24925a864a9513a74e734ddbf77204a99a3c0060fcfbaccae48fe509bc95c3d6e1b1592889c489801265715e6e4355a45357ce467c1caa2f1c3071bd3a9168a7d223e3":"459df18e2dfbd66d6ad04978432a6d97":"ee0b0b52a729c45b899cc924f46eb1908e55aaaeeaa0c4cdaacf57948a7993a6debd7b6cd7aa426dc3b3b6f56522ba3d5700a820b1697b8170bad9ca7caf1050f13d54fb1ddeb111086cb650e1c5f4a14b6a927205a83bf49f357576fd0f884a83b068154352076a6e36a5369436d2c8351f3e6bfec65b4816e3eb3f144ed7f9":32:"8e5a6a79":"FAIL":"":0
 
+AES-GCM NIST CAVS 14.0 - empty ciphertext, AD length: 128 bytes, ciphertext updates: 0
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_cipher:MBEDTLS_CIPHER_ID_AES:"63c3f81500746eaf383fe3975d84f849":"0799d4152fd73c1604b4610cf7171fe1":"cb8248e5f904cc9ccccf6f273fe621eee1b4d7ed98480f9e806a48b84e2d6a733772ecf8fb7fe91805715cddab2b462b89f6e6c7cf873f65031f13c357d5f57b00b7c391c39e78ad1ed94be236ca0ae316bce11bc33c5d701fdfc58abbe918b9c42f7b3d6e89d46f9784b388a6e6daf47730b9fa665d755a17e89932fa669c44":"c53d01e53ee4a6ea106ea4a66538265e":0
+
+AES-GCM NIST CAVS 14.0 - empty ciphertext, AD length: 128 bytes, ciphertext updates: 1
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_cipher:MBEDTLS_CIPHER_ID_AES:"63c3f81500746eaf383fe3975d84f849":"0799d4152fd73c1604b4610cf7171fe1":"cb8248e5f904cc9ccccf6f273fe621eee1b4d7ed98480f9e806a48b84e2d6a733772ecf8fb7fe91805715cddab2b462b89f6e6c7cf873f65031f13c357d5f57b00b7c391c39e78ad1ed94be236ca0ae316bce11bc33c5d701fdfc58abbe918b9c42f7b3d6e89d46f9784b388a6e6daf47730b9fa665d755a17e89932fa669c44":"c53d01e53ee4a6ea106ea4a66538265e":1
+
+AES-GCM NIST CAVS 14.0 - empty ciphertext, AD length: 128 bytes, ciphertext updates: 2
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_cipher:MBEDTLS_CIPHER_ID_AES:"63c3f81500746eaf383fe3975d84f849":"0799d4152fd73c1604b4610cf7171fe1":"cb8248e5f904cc9ccccf6f273fe621eee1b4d7ed98480f9e806a48b84e2d6a733772ecf8fb7fe91805715cddab2b462b89f6e6c7cf873f65031f13c357d5f57b00b7c391c39e78ad1ed94be236ca0ae316bce11bc33c5d701fdfc58abbe918b9c42f7b3d6e89d46f9784b388a6e6daf47730b9fa665d755a17e89932fa669c44":"c53d01e53ee4a6ea106ea4a66538265e":2
+
+AES-GCM NIST CAVS 14.0 - empty ciphertext, AD length: 90 bytes, ciphertext updates: 0
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_cipher:MBEDTLS_CIPHER_ID_AES:"42c6e06f7f07c793864f6033f9022a41":"bd1258f14570dc663f81c31916bcb45490a7df15c95d827fd9e36aaf12f8fc51b8c0bc823faf1cccf9e6d6d3b132e874993325a1a2b1b61f9dacbb4a458de8d25dbf0ba4282d64a06686ddd0f099300b98e91362ffbeb44ebd22ad3c92ee06b230e234f85363642f57d0154aee09ff08d0e560b5728a5db8a18b26438177c45f":"ef675d5e33198af58e72d7f379dd35bd7234aa7a52ae28531ee2e77d6bf30f05c507b8cc72361f11e70017b30c0e374dd283d29c324c67d43d92868485b0ac2cc4e0dfef362df74c927f935d630611fa26c5be9bea49291d3875":"6640b62190bb4a11d4c7b37039bba6fb":0
+
+AES-GCM NIST CAVS 14.0 - empty ciphertext, AD length: 90 bytes, ciphertext updates: 1
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_cipher:MBEDTLS_CIPHER_ID_AES:"42c6e06f7f07c793864f6033f9022a41":"bd1258f14570dc663f81c31916bcb45490a7df15c95d827fd9e36aaf12f8fc51b8c0bc823faf1cccf9e6d6d3b132e874993325a1a2b1b61f9dacbb4a458de8d25dbf0ba4282d64a06686ddd0f099300b98e91362ffbeb44ebd22ad3c92ee06b230e234f85363642f57d0154aee09ff08d0e560b5728a5db8a18b26438177c45f":"ef675d5e33198af58e72d7f379dd35bd7234aa7a52ae28531ee2e77d6bf30f05c507b8cc72361f11e70017b30c0e374dd283d29c324c67d43d92868485b0ac2cc4e0dfef362df74c927f935d630611fa26c5be9bea49291d3875":"6640b62190bb4a11d4c7b37039bba6fb":1
+
+AES-GCM NIST CAVS 14.0 - empty ciphertext, AD length: 90 bytes, ciphertext updates: 2
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_cipher:MBEDTLS_CIPHER_ID_AES:"42c6e06f7f07c793864f6033f9022a41":"bd1258f14570dc663f81c31916bcb45490a7df15c95d827fd9e36aaf12f8fc51b8c0bc823faf1cccf9e6d6d3b132e874993325a1a2b1b61f9dacbb4a458de8d25dbf0ba4282d64a06686ddd0f099300b98e91362ffbeb44ebd22ad3c92ee06b230e234f85363642f57d0154aee09ff08d0e560b5728a5db8a18b26438177c45f":"ef675d5e33198af58e72d7f379dd35bd7234aa7a52ae28531ee2e77d6bf30f05c507b8cc72361f11e70017b30c0e374dd283d29c324c67d43d92868485b0ac2cc4e0dfef362df74c927f935d630611fa26c5be9bea49291d3875":"6640b62190bb4a11d4c7b37039bba6fb":2
+
+AES-GCM NIST CAVS 14.0 - empty AD, ciphertext length: 128 bytes, AD updates: 0
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_ad:MBEDTLS_CIPHER_ID_AES:"c58583f6479d9bc9f1bffddefee66e59":"cee448b48d3506ff3ecc227a87987846":"564a9f700cbc1f895e4f4fa6426f73b4956896a15e6127e7560d74e3fd0b980d2ee45b7a6a3884fa613d91d13921e3f90967d7132bdafcd146dd8ff7147ed1964c2bdb3e12f4133d3dbbc3bf030ff37b1d2147c493ce885068d9ba5bebae24903aaac004aa0ab73fe789e4150e75ddc2bde2700db02e6398d53e88ac652964ac":"361fc2896d7ee986ecef7cbe665bc60c":"9cce7db3fc087d8cb384f6b1a81f03b3fafa2e3281e9f0fcf08a8283929f32439bb0d302516f0ab65b79181fc223a42345bad6e46ff8bcb55add90207f74481227f71a6230a3e13739ef2d015f5003638234b01e58537b7cfab5a8edac19721f41d46948987d1bb1b1d9485a672647bb3b5cb246a1d753a0d107bff036ac7d95":0
+
+AES-GCM NIST CAVS 14.0 - empty AD, ciphertext length: 128 bytes, AD updates: 1
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_ad:MBEDTLS_CIPHER_ID_AES:"c58583f6479d9bc9f1bffddefee66e59":"cee448b48d3506ff3ecc227a87987846":"564a9f700cbc1f895e4f4fa6426f73b4956896a15e6127e7560d74e3fd0b980d2ee45b7a6a3884fa613d91d13921e3f90967d7132bdafcd146dd8ff7147ed1964c2bdb3e12f4133d3dbbc3bf030ff37b1d2147c493ce885068d9ba5bebae24903aaac004aa0ab73fe789e4150e75ddc2bde2700db02e6398d53e88ac652964ac":"361fc2896d7ee986ecef7cbe665bc60c":"9cce7db3fc087d8cb384f6b1a81f03b3fafa2e3281e9f0fcf08a8283929f32439bb0d302516f0ab65b79181fc223a42345bad6e46ff8bcb55add90207f74481227f71a6230a3e13739ef2d015f5003638234b01e58537b7cfab5a8edac19721f41d46948987d1bb1b1d9485a672647bb3b5cb246a1d753a0d107bff036ac7d95":1
+
+AES-GCM NIST CAVS 14.0 - empty AD, ciphertext length: 128 bytes, AD updates: 2
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_ad:MBEDTLS_CIPHER_ID_AES:"c58583f6479d9bc9f1bffddefee66e59":"cee448b48d3506ff3ecc227a87987846":"564a9f700cbc1f895e4f4fa6426f73b4956896a15e6127e7560d74e3fd0b980d2ee45b7a6a3884fa613d91d13921e3f90967d7132bdafcd146dd8ff7147ed1964c2bdb3e12f4133d3dbbc3bf030ff37b1d2147c493ce885068d9ba5bebae24903aaac004aa0ab73fe789e4150e75ddc2bde2700db02e6398d53e88ac652964ac":"361fc2896d7ee986ecef7cbe665bc60c":"9cce7db3fc087d8cb384f6b1a81f03b3fafa2e3281e9f0fcf08a8283929f32439bb0d302516f0ab65b79181fc223a42345bad6e46ff8bcb55add90207f74481227f71a6230a3e13739ef2d015f5003638234b01e58537b7cfab5a8edac19721f41d46948987d1bb1b1d9485a672647bb3b5cb246a1d753a0d107bff036ac7d95":2
+
+AES-GCM NIST CAVS 14.0 - empty AD, ciphertext length: 51 bytes, AD updates: 0
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_ad:MBEDTLS_CIPHER_ID_AES:"24168b48b45759c8d4f9b061f0cbc16a":"b8e5ede75254cc4542191c7e7b0319ad81651451b639caf81c81c98301a4a0af70e291a4e35b448917be1e400fc64a22edf32913162558c2591ee3e80f397d73dfbc68b82da49bda9bcbb6aaf26919e21c1773cf51f6c5b71784f47978cc0d593b4be0259ab22b0b48de733a884c50a8c148c495973a8f5f84f2e93755666bf5":"be19c7e3d3e63f73d833c967d8d62f388ab9617a2adebe5abd99b5ec64599c46bc28bc62770e08995b0bbf27089e3e17b80424":"4aec633d4daed9ce76d697c11f66f34e":"cb7f10bda7da8a2569ed1f3b667127a1e0fb197283aa16ab8cddd43186bd126b118e671cab3e325877fe0e79f1863f89122c8f":0
+
+AES-GCM NIST CAVS 14.0 - empty AD, ciphertext length: 51 bytes, AD updates: 1
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_ad:MBEDTLS_CIPHER_ID_AES:"24168b48b45759c8d4f9b061f0cbc16a":"b8e5ede75254cc4542191c7e7b0319ad81651451b639caf81c81c98301a4a0af70e291a4e35b448917be1e400fc64a22edf32913162558c2591ee3e80f397d73dfbc68b82da49bda9bcbb6aaf26919e21c1773cf51f6c5b71784f47978cc0d593b4be0259ab22b0b48de733a884c50a8c148c495973a8f5f84f2e93755666bf5":"be19c7e3d3e63f73d833c967d8d62f388ab9617a2adebe5abd99b5ec64599c46bc28bc62770e08995b0bbf27089e3e17b80424":"4aec633d4daed9ce76d697c11f66f34e":"cb7f10bda7da8a2569ed1f3b667127a1e0fb197283aa16ab8cddd43186bd126b118e671cab3e325877fe0e79f1863f89122c8f":1
+
+AES-GCM NIST CAVS 14.0 - empty AD, ciphertext length: 51 bytes, AD updates: 2
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_empty_ad:MBEDTLS_CIPHER_ID_AES:"24168b48b45759c8d4f9b061f0cbc16a":"b8e5ede75254cc4542191c7e7b0319ad81651451b639caf81c81c98301a4a0af70e291a4e35b448917be1e400fc64a22edf32913162558c2591ee3e80f397d73dfbc68b82da49bda9bcbb6aaf26919e21c1773cf51f6c5b71784f47978cc0d593b4be0259ab22b0b48de733a884c50a8c148c495973a8f5f84f2e93755666bf5":"be19c7e3d3e63f73d833c967d8d62f388ab9617a2adebe5abd99b5ec64599c46bc28bc62770e08995b0bbf27089e3e17b80424":"4aec633d4daed9ce76d697c11f66f34e":"cb7f10bda7da8a2569ed1f3b667127a1e0fb197283aa16ab8cddd43186bd126b118e671cab3e325877fe0e79f1863f89122c8f":2
+
+AES-GCM NIST - empty AD, empty ciphertext
+depends_on:MBEDTLS_AES_C
+gcm_decrypt_and_verify_no_ad_no_cipher:MBEDTLS_CIPHER_ID_AES:"cf063a34d4a9a76c2c86787d3f96db71":"113b9785971864c83b01c787":"72ac8493e3a5228b5d130a69d2510e42"
+
 AES-GCM Bad IV (AES-128,128,0,0,32) #0
 depends_on:MBEDTLS_AES_C
 gcm_bad_parameters:MBEDTLS_CIPHER_ID_AES:MBEDTLS_GCM_DECRYPT:"d0194b6ee68f0ed8adc4b22ed15dbf14":"":"":"":32:MBEDTLS_ERR_GCM_BAD_INPUT
diff --git a/tests/suites/test_suite_gcm.aes128_en.data b/tests/suites/test_suite_gcm.aes128_en.data
index b1dae75..d60c458 100644
--- a/tests/suites/test_suite_gcm.aes128_en.data
+++ b/tests/suites/test_suite_gcm.aes128_en.data
@@ -670,6 +670,58 @@
 depends_on:MBEDTLS_AES_C
 gcm_encrypt_and_tag:MBEDTLS_CIPHER_ID_AES:"fe481476fce76efcfc78ed144b0756f1":"246e1f2babab8da98b17cc928bd49504d7d87ea2cc174f9ffb7dbafe5969ff824a0bcb52f35441d22f3edcd10fab0ec04c0bde5abd3624ca25cbb4541b5d62a3deb52c00b75d68aaf0504d51f95b8dcbebdd8433f4966c584ac7f8c19407ca927a79fa4ead2688c4a7baafb4c31ef83c05e8848ec2b4f657aab84c109c91c277":"1a2c18c6bf13b3b2785610c71ccd98ca":"b0ab3cb5256575774b8242b89badfbe0dfdfd04f5dd75a8e5f218b28d3f6bc085a013defa5f5b15dfb46132db58ed7a9ddb812d28ee2f962796ad988561a381c02d1cf37dca5fd33e081d61cc7b3ab0b477947524a4ca4cb48c36f48b302c440be6f5777518a60585a8a16cea510dbfc5580b0daac49a2b1242ff55e91a8eae8":"5587620bbb77f70afdf3cdb7ae390edd0473286d86d3f862ad70902d90ff1d315947c959f016257a8fe1f52cc22a54f21de8cb60b74808ac7b22ea7a15945371e18b77c9571aad631aa080c60c1e472019fa85625fc80ed32a51d05e397a8987c8fece197a566689d24d05361b6f3a75616c89db6123bf5902960b21a18bc03a":32:"bd4265a8":0
 
+AES-GCM NIST CAVS 14.0 - empty plaintext, AD length: 128 bytes, ciphertext updates: 0
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_cipher:MBEDTLS_CIPHER_ID_AES:"e28c435211743a7872e4a0bd7602336a":"2ddbee94fcbfacea080ded468f67180c":"63190ef542656cc2b69a9b0daf8dbd2d38cd75f17b92d6d891c17b0337ad4fe4539d9154722fa430782a1d79620e974661918166e39c453c5a98759a13d2766138c7750e6cbdc7b6d7cbe44f3f4de7bb562d9bce6e6e2e815444842b89ba8b73454218c483e574ca886a84e8c9aa6f56dd1541a7e35a4a5b8f6a05ad5bb013e9":"2ce6d74cda466354a736636bf18acfc0":0
+
+AES-GCM NIST CAVS 14.0 - empty plaintext, AD length: 128 bytes, ciphertext updates: 1
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_cipher:MBEDTLS_CIPHER_ID_AES:"e28c435211743a7872e4a0bd7602336a":"2ddbee94fcbfacea080ded468f67180c":"63190ef542656cc2b69a9b0daf8dbd2d38cd75f17b92d6d891c17b0337ad4fe4539d9154722fa430782a1d79620e974661918166e39c453c5a98759a13d2766138c7750e6cbdc7b6d7cbe44f3f4de7bb562d9bce6e6e2e815444842b89ba8b73454218c483e574ca886a84e8c9aa6f56dd1541a7e35a4a5b8f6a05ad5bb013e9":"2ce6d74cda466354a736636bf18acfc0":1
+
+AES-GCM NIST CAVS 14.0 - empty plaintext, AD length: 128 bytes, ciphertext updates: 2
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_cipher:MBEDTLS_CIPHER_ID_AES:"e28c435211743a7872e4a0bd7602336a":"2ddbee94fcbfacea080ded468f67180c":"63190ef542656cc2b69a9b0daf8dbd2d38cd75f17b92d6d891c17b0337ad4fe4539d9154722fa430782a1d79620e974661918166e39c453c5a98759a13d2766138c7750e6cbdc7b6d7cbe44f3f4de7bb562d9bce6e6e2e815444842b89ba8b73454218c483e574ca886a84e8c9aa6f56dd1541a7e35a4a5b8f6a05ad5bb013e9":"2ce6d74cda466354a736636bf18acfc0":2
+
+AES-GCM NIST CAVS 14.0 - empty plaintext, AD length: 90 bytes, ciphertext updates: 0
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_cipher:MBEDTLS_CIPHER_ID_AES:"20b5b6b854e187b058a84d57bc1538b6":"94c1935afc061cbf254b936f":"ca418e71dbf810038174eaa3719b3fcb80531c7110ad9192d105eeaafa15b819ac005668752b344ed1b22faf77048baf03dbddb3b47d6b00e95c4f005e0cc9b7627ccafd3f21b3312aa8d91d3fa0893fe5bff7d44ca46f23afe0":"b37286ebaf4a54e0ffc2a1deafc9f6db":0
+
+AES-GCM NIST CAVS 14.0 - empty plaintext, AD length: 90 bytes, ciphertext updates: 1
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_cipher:MBEDTLS_CIPHER_ID_AES:"20b5b6b854e187b058a84d57bc1538b6":"94c1935afc061cbf254b936f":"ca418e71dbf810038174eaa3719b3fcb80531c7110ad9192d105eeaafa15b819ac005668752b344ed1b22faf77048baf03dbddb3b47d6b00e95c4f005e0cc9b7627ccafd3f21b3312aa8d91d3fa0893fe5bff7d44ca46f23afe0":"b37286ebaf4a54e0ffc2a1deafc9f6db":1
+
+AES-GCM NIST CAVS 14.0 - empty plaintext, AD length: 90 bytes, ciphertext updates: 2
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_cipher:MBEDTLS_CIPHER_ID_AES:"20b5b6b854e187b058a84d57bc1538b6":"94c1935afc061cbf254b936f":"ca418e71dbf810038174eaa3719b3fcb80531c7110ad9192d105eeaafa15b819ac005668752b344ed1b22faf77048baf03dbddb3b47d6b00e95c4f005e0cc9b7627ccafd3f21b3312aa8d91d3fa0893fe5bff7d44ca46f23afe0":"b37286ebaf4a54e0ffc2a1deafc9f6db":2
+
+AES-GCM NIST CAVS 14.0 - empty AD, plaintext length: 128 bytes, AD updates: 0
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_ad:MBEDTLS_CIPHER_ID_AES:"ce0f8cfe9d64c4f4c045d11b97c2d918":"ad4c3627a494fc628316dc03faf81db8":"dfff250d380f363880963b42d6913c1ba11e8edf7c4ab8b76d79ccbaac628f548ee542f48728a9a2620a0d69339c8291e8d398440d740e310908cdee7c273cc91275ce7271ba12f69237998b07b789b3993aaac8dc4ec1914432a30f5172f79ea0539bd1f70b36d437e5170bc63039a5280816c05e1e41760b58e35696cebd55":"0de73d9702d9357c9e8619b7944e40732ac2f4dd3f1b42d8d7f36acb1f1497990d0ec3d626082cdb1384ec72a4c1d98955ba2a3aae6d81b24e9ce533eb5ede7210ae4a06d43f750138b8914d754d43bce416fee799cc4dd03949acedc34def7d6bde6ba41a4cf03d209689a3ad181f1b6dcf76ca25c87eb1c7459cc9f95ddc57":"5f6a3620e59fe8977286f502d0da7517":0
+
+AES-GCM NIST CAVS 14.0 - empty AD, plaintext length: 128 bytes, AD updates: 1
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_ad:MBEDTLS_CIPHER_ID_AES:"ce0f8cfe9d64c4f4c045d11b97c2d918":"ad4c3627a494fc628316dc03faf81db8":"dfff250d380f363880963b42d6913c1ba11e8edf7c4ab8b76d79ccbaac628f548ee542f48728a9a2620a0d69339c8291e8d398440d740e310908cdee7c273cc91275ce7271ba12f69237998b07b789b3993aaac8dc4ec1914432a30f5172f79ea0539bd1f70b36d437e5170bc63039a5280816c05e1e41760b58e35696cebd55":"0de73d9702d9357c9e8619b7944e40732ac2f4dd3f1b42d8d7f36acb1f1497990d0ec3d626082cdb1384ec72a4c1d98955ba2a3aae6d81b24e9ce533eb5ede7210ae4a06d43f750138b8914d754d43bce416fee799cc4dd03949acedc34def7d6bde6ba41a4cf03d209689a3ad181f1b6dcf76ca25c87eb1c7459cc9f95ddc57":"5f6a3620e59fe8977286f502d0da7517":1
+
+AES-GCM NIST CAVS 14.0 - empty AD, plaintext length: 128 bytes, AD updates: 2
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_ad:MBEDTLS_CIPHER_ID_AES:"ce0f8cfe9d64c4f4c045d11b97c2d918":"ad4c3627a494fc628316dc03faf81db8":"dfff250d380f363880963b42d6913c1ba11e8edf7c4ab8b76d79ccbaac628f548ee542f48728a9a2620a0d69339c8291e8d398440d740e310908cdee7c273cc91275ce7271ba12f69237998b07b789b3993aaac8dc4ec1914432a30f5172f79ea0539bd1f70b36d437e5170bc63039a5280816c05e1e41760b58e35696cebd55":"0de73d9702d9357c9e8619b7944e40732ac2f4dd3f1b42d8d7f36acb1f1497990d0ec3d626082cdb1384ec72a4c1d98955ba2a3aae6d81b24e9ce533eb5ede7210ae4a06d43f750138b8914d754d43bce416fee799cc4dd03949acedc34def7d6bde6ba41a4cf03d209689a3ad181f1b6dcf76ca25c87eb1c7459cc9f95ddc57":"5f6a3620e59fe8977286f502d0da7517":2
+
+AES-GCM NIST CAVS 14.0 - empty AD, plaintext length: 51 bytes, AD updates: 0
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_ad:MBEDTLS_CIPHER_ID_AES:"594157ec4693202b030f33798b07176d":"49b12054082660803a1df3df":"3feef98a976a1bd634f364ac428bb59cd51fb159ec1789946918dbd50ea6c9d594a3a31a5269b0da6936c29d063a5fa2cc8a1c":"c1b7a46a335f23d65b8db4008a49796906e225474f4fe7d39e55bf2efd97fd82d4167de082ae30fa01e465a601235d8d68bc69":"ba92d3661ce8b04687e8788d55417dc2":0
+
+AES-GCM NIST CAVS 14.0 - empty AD, plaintext length: 51 bytes, AD updates: 1
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_ad:MBEDTLS_CIPHER_ID_AES:"594157ec4693202b030f33798b07176d":"49b12054082660803a1df3df":"3feef98a976a1bd634f364ac428bb59cd51fb159ec1789946918dbd50ea6c9d594a3a31a5269b0da6936c29d063a5fa2cc8a1c":"c1b7a46a335f23d65b8db4008a49796906e225474f4fe7d39e55bf2efd97fd82d4167de082ae30fa01e465a601235d8d68bc69":"ba92d3661ce8b04687e8788d55417dc2":1
+
+AES-GCM NIST CAVS 14.0 - empty AD, plaintext length: 51 bytes, AD updates: 2
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_tag_empty_ad:MBEDTLS_CIPHER_ID_AES:"594157ec4693202b030f33798b07176d":"49b12054082660803a1df3df":"3feef98a976a1bd634f364ac428bb59cd51fb159ec1789946918dbd50ea6c9d594a3a31a5269b0da6936c29d063a5fa2cc8a1c":"c1b7a46a335f23d65b8db4008a49796906e225474f4fe7d39e55bf2efd97fd82d4167de082ae30fa01e465a601235d8d68bc69":"ba92d3661ce8b04687e8788d55417dc2":2
+
+AES-GCM NIST - empty AD, empty plaintext
+depends_on:MBEDTLS_AES_C
+gcm_encrypt_and_verify_no_ad_no_cipher:MBEDTLS_CIPHER_ID_AES:"11754cd72aec309bf52f7687212e8957":"3c819d9a9bed087615030b65":"250327c674aaf477aef2675748cf6971"
+
 AES-GCM Bad IV (AES-128,128,0,0,32) #0
 depends_on:MBEDTLS_AES_C
 gcm_bad_parameters:MBEDTLS_CIPHER_ID_AES:MBEDTLS_GCM_ENCRYPT:"d0194b6ee68f0ed8adc4b22ed15dbf14":"":"":"":32:MBEDTLS_ERR_GCM_BAD_INPUT
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index a6b0a4c..c530e6b 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -11,20 +11,24 @@
                             const data_t *input,
                             const data_t *expected_output,
                             const data_t *tag,
-                            size_t n1 )
+                            size_t n1,
+                            size_t n1_add)
 {
     int ok = 0;
     uint8_t *output = NULL;
     size_t n2 = input->len - n1;
+    size_t n2_add = add->len - n1_add;
     size_t olen;
 
     /* Sanity checks on the test data */
     TEST_ASSERT( n1 <= input->len );
+    TEST_ASSERT( n1_add <= add->len );
     TEST_EQUAL( input->len, expected_output->len );
 
     TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
                                          iv->x, iv->len ) );
-    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, add->len ) );
+    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, n1_add ) );
+    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x + n1_add, n2_add ) );
 
     /* Allocate a tight buffer for each update call. This way, if the function
      * tries to write beyond the advertised required buffer size, this will
@@ -46,7 +50,8 @@
     output = NULL;
 
     ASSERT_ALLOC( output, tag->len );
-    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, output, tag->len ) );
+    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
+    TEST_EQUAL( 0, olen );
     ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
     mbedtls_free( output );
     output = NULL;
@@ -57,6 +62,99 @@
     return( ok );
 }
 
+static void check_cipher_with_empty_ad( mbedtls_gcm_context *ctx,
+                                        int mode,
+                                        const data_t *iv,
+                                        const data_t *input,
+                                        const data_t *expected_output,
+                                        const data_t *tag,
+                                        size_t ad_update_count)
+{
+    size_t n;
+    uint8_t *output = NULL;
+    size_t olen;
+
+    /* Sanity checks on the test data */
+    TEST_EQUAL( input->len, expected_output->len );
+
+    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
+                                       iv->x, iv->len ) );
+
+    for( n = 0; n < ad_update_count; n++ )
+    {
+        TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, NULL, 0 ) );
+    }
+
+    /* Allocate a tight buffer for each update call. This way, if the function
+     * tries to write beyond the advertised required buffer size, this will
+     * count as an overflow for memory sanitizers and static checkers. */
+    ASSERT_ALLOC( output, input->len );
+    olen = 0xdeadbeef;
+    TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x, input->len, output, input->len, &olen ) );
+    TEST_EQUAL( input->len, olen );
+    ASSERT_COMPARE( output, olen, expected_output->x, input->len );
+    mbedtls_free( output );
+    output = NULL;
+
+    ASSERT_ALLOC( output, tag->len );
+    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
+    TEST_EQUAL( 0, olen );
+    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
+
+exit:
+    mbedtls_free( output );
+}
+
+static void check_empty_cipher_with_ad( mbedtls_gcm_context *ctx,
+                                       int mode,
+                                       const data_t *iv,
+                                       const data_t *add,
+                                       const data_t *tag,
+                                       size_t cipher_update_count)
+{
+    size_t olen;
+    size_t n;
+    uint8_t* output_tag = NULL;
+
+    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode, iv->x, iv->len ) );
+    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, add->len ) );
+
+    for( n = 0; n < cipher_update_count; n++ )
+    {
+        olen = 0xdeadbeef;
+        TEST_EQUAL( 0, mbedtls_gcm_update( ctx, NULL, 0, NULL, 0, &olen ) );
+        TEST_EQUAL( 0, olen );
+    }
+
+    ASSERT_ALLOC( output_tag, tag->len );
+    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen,
+                                       output_tag, tag->len ) );
+    TEST_EQUAL( 0, olen );
+    ASSERT_COMPARE( output_tag, tag->len, tag->x, tag->len );
+
+exit:
+    mbedtls_free( output_tag );
+}
+
+static void check_no_cipher_no_ad( mbedtls_gcm_context *ctx,
+                                   int mode,
+                                   const data_t *iv,
+                                   const data_t *tag )
+{
+    uint8_t *output = NULL;
+    size_t olen = 0;
+
+    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
+                                       iv->x, iv->len ) );
+    ASSERT_ALLOC( output, tag->len );
+    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
+    TEST_EQUAL( 0, olen );
+    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
+
+exit:
+    mbedtls_free( output );
+}
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -101,6 +199,7 @@
     mbedtls_gcm_context ctx;
     size_t tag_len = tag_len_bits / 8;
     size_t n1;
+    size_t n1_add;
 
     mbedtls_gcm_init( &ctx );
 
@@ -118,12 +217,15 @@
 
         for( n1 = 0; n1 <= src_str->len; n1 += 1 )
         {
-            mbedtls_test_set_step( n1 );
-            if( !check_multipart( &ctx, MBEDTLS_GCM_ENCRYPT,
-                                  iv_str, add_str, src_str,
-                                  dst, tag,
-                                  n1 ) )
-                goto exit;
+            for( n1_add = 0; n1_add <= add_str->len; n1_add += 1 )
+            {
+                mbedtls_test_set_step( n1 * 10000 + n1_add );
+                if( !check_multipart( &ctx, MBEDTLS_GCM_ENCRYPT,
+                                    iv_str, add_str, src_str,
+                                    dst, tag,
+                                    n1, n1_add ) )
+                    goto exit;
+            }
         }
     }
 
@@ -144,6 +246,7 @@
     int ret;
     size_t tag_len = tag_len_bits / 8;
     size_t n1;
+    size_t n1_add;
 
     mbedtls_gcm_init( &ctx );
 
@@ -166,12 +269,15 @@
 
             for( n1 = 0; n1 <= src_str->len; n1 += 1 )
             {
-                mbedtls_test_set_step( n1 );
-                if( !check_multipart( &ctx, MBEDTLS_GCM_DECRYPT,
-                                      iv_str, add_str, src_str,
-                                      pt_result, tag_str,
-                                      n1 ) )
-                    goto exit;
+                for( n1_add = 0; n1_add <= add_str->len; n1_add += 1 )
+                {
+                    mbedtls_test_set_step( n1 * 10000 + n1_add );
+                    if( !check_multipart( &ctx, MBEDTLS_GCM_DECRYPT,
+                                        iv_str, add_str, src_str,
+                                        pt_result, tag_str,
+                                        n1, n1_add ) )
+                        goto exit;
+                }
             }
         }
     }
@@ -181,6 +287,130 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void gcm_decrypt_and_verify_empty_cipher( int cipher_id,
+                                          data_t * key_str,
+                                          data_t * iv_str,
+                                          data_t * add_str,
+                                          data_t * tag_str,
+                                          int cipher_update_calls )
+{
+    mbedtls_gcm_context ctx;
+
+    mbedtls_gcm_init( &ctx );
+
+    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
+    check_empty_cipher_with_ad( &ctx, MBEDTLS_GCM_DECRYPT,
+                                iv_str, add_str, tag_str,
+                                cipher_update_calls );
+
+    mbedtls_gcm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void gcm_decrypt_and_verify_empty_ad( int cipher_id,
+                                      data_t * key_str,
+                                      data_t * iv_str,
+                                      data_t * src_str,
+                                      data_t * tag_str,
+                                      data_t * pt_result,
+                                      int ad_update_calls )
+{
+    mbedtls_gcm_context ctx;
+
+    mbedtls_gcm_init( &ctx );
+
+    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
+    check_cipher_with_empty_ad( &ctx, MBEDTLS_GCM_DECRYPT,
+                                iv_str, src_str, pt_result, tag_str,
+                                ad_update_calls );
+
+    mbedtls_gcm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void gcm_decrypt_and_verify_no_ad_no_cipher( int cipher_id,
+                                             data_t * key_str,
+                                             data_t * iv_str,
+                                             data_t * tag_str )
+{
+    mbedtls_gcm_context ctx;
+
+    mbedtls_gcm_init( &ctx );
+
+    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
+    check_no_cipher_no_ad( &ctx, MBEDTLS_GCM_DECRYPT,
+                           iv_str, tag_str );
+
+    mbedtls_gcm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void gcm_encrypt_and_tag_empty_cipher( int cipher_id,
+                                       data_t * key_str,
+                                       data_t * iv_str,
+                                       data_t * add_str,
+                                       data_t * tag_str,
+                                       int cipher_update_calls )
+{
+    mbedtls_gcm_context ctx;
+
+    mbedtls_gcm_init( &ctx );
+
+    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
+    check_empty_cipher_with_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
+                                iv_str, add_str, tag_str,
+                                cipher_update_calls );
+
+exit:
+    mbedtls_gcm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void gcm_encrypt_and_tag_empty_ad( int cipher_id,
+                                   data_t * key_str,
+                                   data_t * iv_str,
+                                   data_t * src_str,
+                                   data_t * dst,
+                                   data_t * tag_str,
+                                   int ad_update_calls )
+{
+    mbedtls_gcm_context ctx;
+
+    mbedtls_gcm_init( &ctx );
+
+    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
+    check_cipher_with_empty_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
+                                iv_str, src_str, dst, tag_str,
+                                ad_update_calls );
+
+exit:
+    mbedtls_gcm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void gcm_encrypt_and_verify_no_ad_no_cipher( int cipher_id,
+                                             data_t * key_str,
+                                             data_t * iv_str,
+                                             data_t * tag_str )
+{
+    mbedtls_gcm_context ctx;
+
+    mbedtls_gcm_init( &ctx );
+
+    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
+    check_no_cipher_no_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
+                           iv_str, tag_str );
+
+    mbedtls_gcm_free( &ctx );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:NOT_DEFINED */
 void gcm_invalid_param( )
 {
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 553b8eb..02a11c8 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -62,13 +62,13 @@
 mpi_read_write_string:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":16:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":200:0:0
 
 Test mpi_read_write_string #8 (Empty MPI hex -> hex)
-mpi_read_write_string:16:"":16:"00":4:0:0
+mpi_read_write_string:16:"":16:"":4:0:0
 
 Test mpi_read_write_string #9 (Empty MPI hex -> dec)
 mpi_read_write_string:16:"":10:"0":4:0:0
 
 Test mpi_read_write_string #8 (Empty MPI dec -> hex)
-mpi_read_write_string:10:"":16:"00":4:0:0
+mpi_read_write_string:10:"":16:"":4:0:0
 
 Test mpi_read_write_string #9 (Empty MPI dec -> dec)
 mpi_read_write_string:10:"":10:"0":4:0:0
@@ -115,6 +115,12 @@
 Base test mbedtls_mpi_write_file #1
 mbedtls_mpi_write_file:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":16:"data_files/mpi_write"
 
+Test mbedtls_mpi_lsb: 0 (null)
+mbedtls_mpi_lsb:16:"":0
+
+Test mbedtls_mpi_lsb: 0 (1 limb)
+mbedtls_mpi_lsb:16:"0":0
+
 Base test mbedtls_mpi_lsb #1
 mbedtls_mpi_lsb:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":2
 
@@ -145,7 +151,10 @@
 Base test mbedtls_mpi_bitlen #6
 mbedtls_mpi_bitlen:10:"10":4
 
-Base test mbedtls_mpi_bitlen #7
+Base test mbedtls_mpi_bitlen: 0 (null)
+mbedtls_mpi_bitlen:10:"":0
+
+Base test mbedtls_mpi_bitlen: 0 (1 limb)
 mbedtls_mpi_bitlen:10:"0":0
 
 Base test mbedtls_mpi_cmp_int #1
@@ -193,6 +202,90 @@
 Base test mbedtls_mpi_cmp_mpi (Mixed values) #6
 mbedtls_mpi_cmp_mpi:10:"-2":10:"31231231289798":-1
 
+Test mbedtls_mpi_cmp_mpi: 0 (null) = 0 (null)
+mbedtls_mpi_cmp_mpi:10:"":10:"":0
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) = 0 (1 limb)
+mbedtls_mpi_cmp_mpi:10:"":10:"0":0
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) = 0 (null)
+mbedtls_mpi_cmp_mpi:10:"0":10:"":0
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) = 0 (1 limb)
+mbedtls_mpi_cmp_mpi:10:"0":10:"0":0
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) < positive
+mbedtls_mpi_cmp_mpi:10:"":10:"123":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) < positive
+mbedtls_mpi_cmp_mpi:10:"0":10:"123":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) > negative
+mbedtls_mpi_cmp_mpi:10:"":10:"-123":1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) > negative
+mbedtls_mpi_cmp_mpi:10:"0":10:"-123":1
+
+Test mbedtls_mpi_cmp_mpi: positive > 0 (null)
+mbedtls_mpi_cmp_mpi:10:"123":10:"":1
+
+Test mbedtls_mpi_cmp_mpi: positive > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:10:"123":10:"0":1
+
+Test mbedtls_mpi_cmp_mpi: negative < 0 (null)
+mbedtls_mpi_cmp_mpi:10:"-123":10:"":-1
+
+Test mbedtls_mpi_cmp_mpi: negative < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:10:"-123":10:"0":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) < positive with leading zero limb
+mbedtls_mpi_cmp_mpi:16:"":16:"0000000000000000123":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) < positive with leading zero limb
+mbedtls_mpi_cmp_mpi:16:"0":16:"0000000000000000123":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:16:"":16:"-0000000000000000123":1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:16:"0":16:"-0000000000000000123":1
+
+Test mbedtls_mpi_cmp_mpi: positive with leading zero limb > 0 (null)
+mbedtls_mpi_cmp_mpi:16:"0000000000000000123":16:"":1
+
+Test mbedtls_mpi_cmp_mpi: positive with leading zero limb > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:16:"0000000000000000123":16:"0":1
+
+Test mbedtls_mpi_cmp_mpi: negative with leading zero limb < 0 (null)
+mbedtls_mpi_cmp_mpi:16:"-0000000000000000123":16:"":-1
+
+Test mbedtls_mpi_cmp_mpi: negative with leading zero limb < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:16:"-0000000000000000123":16:"0":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) < large positive
+mbedtls_mpi_cmp_mpi:16:"":16:"1230000000000000000":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) < large positive
+mbedtls_mpi_cmp_mpi:16:"0":16:"1230000000000000000":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) > large negative
+mbedtls_mpi_cmp_mpi:16:"":16:"-1230000000000000000":1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) > large negative
+mbedtls_mpi_cmp_mpi:16:"0":16:"-1230000000000000000":1
+
+Test mbedtls_mpi_cmp_mpi: large positive > 0 (null)
+mbedtls_mpi_cmp_mpi:16:"1230000000000000000":16:"":1
+
+Test mbedtls_mpi_cmp_mpi: large positive > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:16:"1230000000000000000":16:"0":1
+
+Test mbedtls_mpi_cmp_mpi: large negative < 0 (null)
+mbedtls_mpi_cmp_mpi:16:"-1230000000000000000":16:"":-1
+
+Test mbedtls_mpi_cmp_mpi: large negative < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:16:"-1230000000000000000":16:"0":-1
+
 Base test mbedtls_mpi_lt_mpi_ct #1
 mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B5":0:0
 
@@ -226,6 +319,9 @@
 Base test mbedtls_mpi_lt_mpi_ct (Y is longer in storage)
 mbedtls_mpi_lt_mpi_ct:3:"2B5":4:"2B5":0:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+Base test mbedtls_mpi_lt_mpi_ct (length=0)
+mbedtls_mpi_lt_mpi_ct:0:"":0:"":0:0
+
 Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #1
 mbedtls_mpi_lt_mpi_ct:2:"7FFFFFFFFFFFFFFF":2:"FF":0:0
 
@@ -298,7 +394,16 @@
 Base test mbedtls_mpi_cmp_abs (Negative values) #3
 mbedtls_mpi_cmp_abs:10:"-2":10:"-1":1
 
-Base test mbedtls_mpi_cmp_abs (Zero and Zero) #4
+Test mbedtls_mpi_cmp_abs: 0 (null) = 0 (null)
+mbedtls_mpi_cmp_abs:10:"":10:"":0
+
+Test mbedtls_mpi_cmp_abs: 0 (null) = 0 (1 limb)
+mbedtls_mpi_cmp_abs:10:"":10:"0":0
+
+Test mbedtls_mpi_cmp_abs: 0 (1 limb) = 0 (null)
+mbedtls_mpi_cmp_abs:10:"0":10:"":0
+
+Test mbedtls_mpi_cmp_abs: 0 (1 limb) = 0 (1 limb)
 mbedtls_mpi_cmp_abs:10:"0":10:"0":0
 
 Base test mbedtls_mpi_cmp_abs (Mix values) #1
@@ -310,84 +415,261 @@
 Base test mbedtls_mpi_cmp_abs (Mix values) #3
 mbedtls_mpi_cmp_abs:10:"-2":10:"1":1
 
-Copy zero (1 limb) to positive (1 limb)
-mbedtls_mpi_copy_sint:0:1500
+Copy large negative to large negative
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"-face1e55ca11ab1ecab005e5"
 
-Copy zero (1 limb) to negative (1 limb)
-mbedtls_mpi_copy_sint:0:-1500
+Copy large negative to large positive
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"face1e55ca11ab1ecab005e5"
 
-Copy positive (1 limb) to zero (1 limb)
-mbedtls_mpi_copy_sint:1500:0
+Copy large negative to small negative
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"-beef"
 
-Copy negative (1 limb) to zero (1 limb)
-mbedtls_mpi_copy_sint:-1500:0
+Copy large negative to small positive
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"beef"
 
-Copy positive (1 limb) to negative (1 limb)
-mbedtls_mpi_copy_sint:1500:-42
+Copy large negative to zero (1 limb)
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"0"
 
-Copy negative (1 limb) to positive (1 limb)
-mbedtls_mpi_copy_sint:-42:1500
+Copy large negative to zero (null)
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":""
+
+Copy large positive to large negative
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"-face1e55ca11ab1ecab005e5"
+
+Copy large positive to large positive
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"face1e55ca11ab1ecab005e5"
+
+Copy large positive to small negative
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"-beef"
+
+Copy large positive to small positive
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"beef"
+
+Copy large positive to zero (1 limb)
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"0"
+
+Copy large positive to zero (null)
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":""
+
+Copy small negative to large negative
+mbedtls_mpi_copy:"-bead":"-face1e55ca11ab1ecab005e5"
+
+Copy small negative to large positive
+mbedtls_mpi_copy:"-bead":"face1e55ca11ab1ecab005e5"
+
+Copy small negative to small negative
+mbedtls_mpi_copy:"-bead":"-beef"
+
+Copy small negative to small positive
+mbedtls_mpi_copy:"-bead":"beef"
+
+Copy small negative to zero (1 limb)
+mbedtls_mpi_copy:"-bead":"0"
+
+Copy small negative to zero (null)
+mbedtls_mpi_copy:"-bead":""
+
+Copy small positive to large negative
+mbedtls_mpi_copy:"bead":"-face1e55ca11ab1ecab005e5"
+
+Copy small positive to large positive
+mbedtls_mpi_copy:"bead":"face1e55ca11ab1ecab005e5"
+
+Copy small positive to small negative
+mbedtls_mpi_copy:"bead":"-beef"
+
+Copy small positive to small positive
+mbedtls_mpi_copy:"bead":"beef"
+
+Copy small positive to zero (1 limb)
+mbedtls_mpi_copy:"bead":"0"
+
+Copy small positive to zero (null)
+mbedtls_mpi_copy:"bead":""
+
+Copy zero (1 limb) to large negative
+mbedtls_mpi_copy:"0":"-face1e55ca11ab1ecab005e5"
+
+Copy zero (1 limb) to large positive
+mbedtls_mpi_copy:"0":"face1e55ca11ab1ecab005e5"
+
+Copy zero (1 limb) to small negative
+mbedtls_mpi_copy:"0":"-beef"
+
+Copy zero (1 limb) to small positive
+mbedtls_mpi_copy:"0":"beef"
+
+Copy zero (1 limb) to zero (1 limb)
+mbedtls_mpi_copy:"0":"0"
+
+Copy zero (1 limb) to zero (null)
+mbedtls_mpi_copy:"0":""
+
+Copy zero (null) to large negative
+mbedtls_mpi_copy:"":"-face1e55ca11ab1ecab005e5"
+
+Copy zero (null) to large positive
+mbedtls_mpi_copy:"":"face1e55ca11ab1ecab005e5"
+
+Copy zero (null) to small negative
+mbedtls_mpi_copy:"":"-beef"
+
+Copy zero (null) to small positive
+mbedtls_mpi_copy:"":"beef"
+
+Copy zero (null) to zero (1 limb)
+mbedtls_mpi_copy:"":"0"
 
 Copy zero (null) to zero (null)
-mbedtls_mpi_copy_binary:"":""
+mbedtls_mpi_copy:"":""
 
-Copy zero (null) to positive (1 limb)
-mbedtls_mpi_copy_binary:"":"1234"
+Copy self: large negative
+mpi_copy_self:"-ca5cadedb01dfaceacc01ade"
 
-Copy positive (1 limb) to zero (null)
-mbedtls_mpi_copy_binary:"1234":""
+Copy self: large positive
+mpi_copy_self:"ca5cadedb01dfaceacc01ade"
 
-Copy positive to larger
-mbedtls_mpi_copy_binary:"bead":"ca5cadedb01dfaceacc01ade"
+Copy self: small negative
+mpi_copy_self:"-bead"
 
-Copy positive to smaller
-mbedtls_mpi_copy_binary:"ca5cadedb01dfaceacc01ade":"bead"
-
-Copy self: positive (1 limb)
-mpi_copy_self:14
+Copy self: small positive
+mpi_copy_self:"bead"
 
 Copy self: zero (1 limb)
-mpi_copy_self:0
+mpi_copy_self:"0"
 
-Swap zero (1 limb) with positive (1 limb)
-mbedtls_mpi_swap_sint:0:1500
+Copy self: zero (null)
+mpi_copy_self:""
 
-Swap zero (1 limb) with negative (1 limb)
-mbedtls_mpi_swap_sint:0:-1500
+Swap large negative with large negative
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"-face1e55ca11ab1ecab005e5"
 
-Swap positive (1 limb) with zero (1 limb)
-mbedtls_mpi_swap_sint:1500:0
+Swap large negative with large positive
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"face1e55ca11ab1ecab005e5"
 
-Swap negative (1 limb) with zero (1 limb)
-mbedtls_mpi_swap_sint:-1500:0
+Swap large negative with small negative
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"-beef"
 
-Swap positive (1 limb) with negative (1 limb)
-mbedtls_mpi_swap_sint:1500:-42
+Swap large negative with small positive
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"beef"
 
-Swap negative (1 limb) with positive (1 limb)
-mbedtls_mpi_swap_sint:-42:1500
+Swap large negative with zero (1 limb)
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"0"
+
+Swap large negative with zero (null)
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":""
+
+Swap large positive with large negative
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"-face1e55ca11ab1ecab005e5"
+
+Swap large positive with large positive
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"face1e55ca11ab1ecab005e5"
+
+Swap large positive with small negative
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"-beef"
+
+Swap large positive with small positive
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"beef"
+
+Swap large positive with zero (1 limb)
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"0"
+
+Swap large positive with zero (null)
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":""
+
+Swap small negative with large negative
+mbedtls_mpi_swap:"-bead":"-face1e55ca11ab1ecab005e5"
+
+Swap small negative with large positive
+mbedtls_mpi_swap:"-bead":"face1e55ca11ab1ecab005e5"
+
+Swap small negative with small negative
+mbedtls_mpi_swap:"-bead":"-beef"
+
+Swap small negative with small positive
+mbedtls_mpi_swap:"-bead":"beef"
+
+Swap small negative with zero (1 limb)
+mbedtls_mpi_swap:"-bead":"0"
+
+Swap small negative with zero (null)
+mbedtls_mpi_swap:"-bead":""
+
+Swap small positive with large negative
+mbedtls_mpi_swap:"bead":"-face1e55ca11ab1ecab005e5"
+
+Swap small positive with large positive
+mbedtls_mpi_swap:"bead":"face1e55ca11ab1ecab005e5"
+
+Swap small positive with small negative
+mbedtls_mpi_swap:"bead":"-beef"
+
+Swap small positive with small positive
+mbedtls_mpi_swap:"bead":"beef"
+
+Swap small positive with zero (1 limb)
+mbedtls_mpi_swap:"bead":"0"
+
+Swap small positive with zero (null)
+mbedtls_mpi_swap:"bead":""
+
+Swap zero (1 limb) with large negative
+mbedtls_mpi_swap:"0":"-face1e55ca11ab1ecab005e5"
+
+Swap zero (1 limb) with large positive
+mbedtls_mpi_swap:"0":"face1e55ca11ab1ecab005e5"
+
+Swap zero (1 limb) with small negative
+mbedtls_mpi_swap:"0":"-beef"
+
+Swap zero (1 limb) with small positive
+mbedtls_mpi_swap:"0":"beef"
+
+Swap zero (1 limb) with zero (1 limb)
+mbedtls_mpi_swap:"0":"0"
+
+Swap zero (1 limb) with zero (null)
+mbedtls_mpi_swap:"0":""
+
+Swap zero (null) with large negative
+mbedtls_mpi_swap:"":"-face1e55ca11ab1ecab005e5"
+
+Swap zero (null) with large positive
+mbedtls_mpi_swap:"":"face1e55ca11ab1ecab005e5"
+
+Swap zero (null) with small negative
+mbedtls_mpi_swap:"":"-beef"
+
+Swap zero (null) with small positive
+mbedtls_mpi_swap:"":"beef"
+
+Swap zero (null) with zero (1 limb)
+mbedtls_mpi_swap:"":"0"
 
 Swap zero (null) with zero (null)
-mbedtls_mpi_swap_binary:"":""
+mbedtls_mpi_swap:"":""
 
-Swap zero (null) with positive (1 limb)
-mbedtls_mpi_swap_binary:"":"1234"
+Swap self: large negative
+mpi_swap_self:"-ca5cadedb01dfaceacc01ade"
 
-Swap positive (1 limb) with zero (null)
-mbedtls_mpi_swap_binary:"1234":""
+Swap self: large positive
+mpi_swap_self:"ca5cadedb01dfaceacc01ade"
 
-Swap positive with larger
-mbedtls_mpi_swap_binary:"bead":"ca5cadedb01dfaceacc01ade"
+Swap self: small negative
+mpi_swap_self:"-bead"
 
-Swap positive with smaller
-mbedtls_mpi_swap_binary:"ca5cadedb01dfaceacc01ade":"bead"
+Swap self: small positive
+mpi_swap_self:"bead"
 
-Swap self: 1 limb
-mpi_swap_self:"face"
+Swap self: zero (1 limb)
+mpi_swap_self:"0"
 
-Swap self: null
+Swap self: zero (null)
 mpi_swap_self:""
 
+Shrink 0 limbs in a buffer of size 0 to 0
+mbedtls_mpi_shrink:0:0:0:0
+
 Shrink 2 limbs in a buffer of size 2 to 4
 mbedtls_mpi_shrink:2:2:4:4
 
@@ -412,42 +694,6 @@
 Shrink 0 limbs in a buffer of size 4 to 0 yielding 1
 mbedtls_mpi_shrink:4:0:0:1
 
-Test mbedtls_mpi_safe_cond_assign #1
-mbedtls_mpi_safe_cond_assign:+1:"01":+1:"02"
-
-Test mbedtls_mpi_safe_cond_assign #2
-mbedtls_mpi_safe_cond_assign:+1:"FF000000000000000001":+1:"02"
-
-Test mbedtls_mpi_safe_cond_assign #3
-mbedtls_mpi_safe_cond_assign:+1:"01":+1:"FF000000000000000002"
-
-Test mbedtls_mpi_safe_cond_assign #4
-mbedtls_mpi_safe_cond_assign:+1:"01":-1:"02"
-
-Test mbedtls_mpi_safe_cond_assign #5
-mbedtls_mpi_safe_cond_assign:-1:"01":+1:"02"
-
-Test mbedtls_mpi_safe_cond_assign #6
-mbedtls_mpi_safe_cond_assign:-1:"01":-1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #1
-mbedtls_mpi_safe_cond_swap:+1:"01":+1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #2
-mbedtls_mpi_safe_cond_swap:+1:"FF000000000000000001":+1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #3
-mbedtls_mpi_safe_cond_swap:+1:"01":+1:"FF000000000000000002"
-
-Test mbedtls_mpi_safe_cond_swap #4
-mbedtls_mpi_safe_cond_swap:+1:"01":-1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #5
-mbedtls_mpi_safe_cond_swap:-1:"01":+1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #6
-mbedtls_mpi_safe_cond_swap:-1:"01":-1:"02"
-
 Base test mbedtls_mpi_add_abs #1
 mbedtls_mpi_add_abs:10:"12345678":10:"642531":10:"12988209"
 
@@ -460,6 +706,15 @@
 Base test mbedtls_mpi_add_abs #4
 mbedtls_mpi_add_abs:10:"-12345678":10:"-642531":10:"12988209"
 
+Test mbedtls_mpi_add_abs: 0 (null) + 0 (null)
+mbedtls_mpi_add_abs:16:"":16:"":16:"0"
+
+Test mbedtls_mpi_add_abs: 0 (null) + 1
+mbedtls_mpi_add_abs:16:"":16:"01":16:"01"
+
+Test mbedtls_mpi_add_abs: 1 + 0 (null)
+mbedtls_mpi_add_abs:16:"01":16:"":16:"01"
+
 Test mbedtls_mpi_add_abs #1
 mbedtls_mpi_add_abs:10:"-643808006803554439230129854961492699151386107534013432918073439524138264842370630061369715394739134090922937332590384720397133335969549256322620979036686633213903952966175107096769180017646161851573147596390153":10:"56125680981752282333498088313568935051383833838594899821664631784577337171193624243181360054669678410455329112434552942717084003541384594864129940145043086760031292483340068923506115878221189886491132772739661669044958531131327771":10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924"
 
@@ -481,6 +736,21 @@
 Base test mbedtls_mpi_add_mpi #4
 mbedtls_mpi_add_mpi:10:"-12345678":10:"-642531":10:"-12988209"
 
+Test mbedtls_mpi_add_mpi: 0 (null) + 0 (null)
+mbedtls_mpi_add_mpi:16:"":16:"":16:"0"
+
+Test mbedtls_mpi_add_mpi: 0 (null) + 1
+mbedtls_mpi_add_mpi:16:"":16:"01":16:"01"
+
+Test mbedtls_mpi_add_mpi: 1 + 0 (null)
+mbedtls_mpi_add_mpi:16:"01":16:"":16:"01"
+
+Test mbedtls_mpi_add_mpi: 0 (null) + -1
+mbedtls_mpi_add_mpi:16:"":16:"-01":16:"-01"
+
+Test mbedtls_mpi_add_mpi: -1 + 0 (null)
+mbedtls_mpi_add_mpi:16:"-01":16:"":16:"-01"
+
 Test mbedtls_mpi_add_mpi #1
 mbedtls_mpi_add_mpi:10:"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123":10:"531872289054204184185084734375133399408303613982130856645299464930952178606045848877129147820387996428175564228204785846141207532462936339834139412401975338705794646595487324365194792822189473092273993580587964571659678084484152603881094176995594813302284232006001752128168901293560051833646881436219":10:"735829167410606161590850601304167976688497607296479119740072111384235241328747126510065763883532084601487937110881909725679916932621242907172467691556475037071866553361927361439411910627880345885122142692610250903804554267860479115964668998643528806263534149325837971432443181537363155848647445226342"
 
@@ -502,6 +772,12 @@
 Test mbedtls_mpi_add_int #2
 mbedtls_mpi_add_int:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":-9871232:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227002905097"
 
+Test mbedtls_mpi_add_int: 0 (null) + 0
+mbedtls_mpi_add_int:16:"":0:16:"0"
+
+Test mbedtls_mpi_add_int: 0 (null) + 1
+mbedtls_mpi_add_int:16:"":1:16:"1"
+
 Base test mbedtls_mpi_sub_abs #1 (|B| > |A|)
 mbedtls_mpi_sub_abs:10:"5":10:"7":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
 
@@ -538,6 +814,24 @@
 Base test mbedtls_mpi_sub_abs #4
 mbedtls_mpi_sub_abs:10:"7":10:"-5":10:"2":0
 
+Test mbedtls_mpi_sub_abs: 0 (null) - 0 (null)
+mbedtls_mpi_sub_abs:16:"":16:"":16:"":0
+
+Test mbedtls_mpi_sub_abs: 0 (null) - 0 (1 limb)
+mbedtls_mpi_sub_abs:16:"":16:"00":16:"":0
+
+Test mbedtls_mpi_sub_abs: 0 (1 limb) - 0 (null)
+mbedtls_mpi_sub_abs:16:"00":16:"":16:"":0
+
+Test mbedtls_mpi_sub_abs: 0 (1 limb) - 0 (1 limb)
+mbedtls_mpi_sub_abs:16:"00":16:"00":16:"":0
+
+Test mbedtls_mpi_sub_abs: 1 - 0 (null)
+mbedtls_mpi_sub_abs:16:"01":16:"":16:"01":0
+
+Test mbedtls_mpi_sub_abs: 0 (null) - 1
+mbedtls_mpi_sub_abs:16:"":16:"01":16:"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
 Test mbedtls_mpi_sub_abs #1
 mbedtls_mpi_sub_abs:16:"FFFFFFFFFF":16:"01":16:"FFFFFFFFFE":0
 
@@ -562,6 +856,27 @@
 Base test mbedtls_mpi_sub_mpi #4 (Test with negative subtraction)
 mbedtls_mpi_sub_mpi:10:"5":10:"-7":10:"12"
 
+Test mbedtls_mpi_sub_mpi: 0 (null) - 0 (null)
+mbedtls_mpi_sub_mpi:16:"":16:"":16:"0"
+
+Test mbedtls_mpi_sub_mpi: 0 (null) - 0 (1 limb)
+mbedtls_mpi_sub_mpi:16:"":16:"00":16:"0"
+
+Test mbedtls_mpi_sub_mpi: 0 (null) - 1
+mbedtls_mpi_sub_mpi:16:"":16:"1":16:"-1"
+
+Test mbedtls_mpi_sub_mpi: 0 (null) - -1
+mbedtls_mpi_sub_mpi:16:"":16:"-1":16:"1"
+
+Test mbedtls_mpi_sub_mpi: 0 (1 limb) - 0 (null)
+mbedtls_mpi_sub_mpi:16:"00":16:"":16:"0"
+
+Test mbedtls_mpi_sub_mpi: 1 - 0 (null)
+mbedtls_mpi_sub_mpi:16:"1":16:"":16:"1"
+
+Test mbedtls_mpi_sub_mpi: -1 - 0 (null)
+mbedtls_mpi_sub_mpi:16:"-1":16:"":16:"-1"
+
 Test mbedtls_mpi_sub_mpi #1
 mbedtls_mpi_sub_mpi:10:"531872289054204184185084734375133399408303613982130856645299464930952178606045848877129147820387996428175564228204785846141207532462936339834139412401975338705794646595487324365194792822189473092273993580587964571659678084484152603881094176995594813302284232006001752128168901293560051833646881436219":10:"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123":10:"327915410697802206779318867446098822128109620667782593550526818477669115883344571244192531757243908254863191345527661966602498132304629772495811133247475640339722739829047287290977675016498600299425844468565678239514801901107826091797519355347660820341034314686165532823894621049756947818646317646096"
 
@@ -574,12 +889,30 @@
 Test mbedtls_mpi_sub_int #2
 mbedtls_mpi_sub_int:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":9871232:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227002905097"
 
+Test mbedtls_mpi_sub_int: 0 (null) - 0
+mbedtls_mpi_sub_int:16:"":0:16:"0"
+
+Test mbedtls_mpi_sub_int: 0 (null) - 1
+mbedtls_mpi_sub_int:16:"":1:16:"-1"
+
+Test mbedtls_mpi_sub_int: 0 (null) - -1
+mbedtls_mpi_sub_int:16:"":-1:16:"1"
+
 Test mbedtls_mpi_shift_l #1
 mbedtls_mpi_shift_l:10:"64":1:10:"128"
 
 Test mbedtls_mpi_shift_l #2
 mbedtls_mpi_shift_l:10:"658385546911733550164516088405238961461880256029834598831972039469421755117818013653494814438931957316403111689187691446941406788869098983929874080332195117465344344350008880118042764943201875870917468833709791733282363323948005998269792207":37:10:"90487820548639020691922304619723076305400961610119884872723190678642804168382367856686134531865643066983017249846286450251272364365605022750900439437595355052945035915579216557330505438734955340526145476988250171181404966718289259743378883640981192704"
 
+Test mbedtls_mpi_shift_l: 0 (null) <<= 0
+mbedtls_mpi_shift_l:16:"":0:16:"0"
+
+Test mbedtls_mpi_shift_l: 0 (null) <<= 1
+mbedtls_mpi_shift_l:16:"":1:16:"0"
+
+Test mbedtls_mpi_shift_l: 0 (null) <<= 64
+mbedtls_mpi_shift_l:16:"":64:16:"0"
+
 Test mbedtls_mpi_shift_r #1
 mbedtls_mpi_shift_r:10:"128":1:10:"64"
 
@@ -598,6 +931,15 @@
 Test mbedtls_mpi_shift_r #7
 mbedtls_mpi_shift_r:16:"FFFFFFFFFFFFFFFF":128:16:"00"
 
+Test mbedtls_mpi_shift_r: 0 (null) >>= 0
+mbedtls_mpi_shift_r:16:"":0:16:"0"
+
+Test mbedtls_mpi_shift_r: 0 (null) >>= 1
+mbedtls_mpi_shift_r:16:"":1:16:"0"
+
+Test mbedtls_mpi_shift_r: 0 (null) >>= 64
+mbedtls_mpi_shift_r:16:"":64:16:"0"
+
 Base test mbedtls_mpi_mul_mpi #1
 mbedtls_mpi_mul_mpi:10:"5":10:"7":10:"35"
 
@@ -610,8 +952,131 @@
 Base test mbedtls_mpi_mul_mpi #4
 mbedtls_mpi_mul_mpi:10:"-5":10:"-7":10:"35"
 
+Test mbedtls_mpi_mul_mpi: 0 (null) * 0 (null)
+mbedtls_mpi_mul_mpi:16:"":16:"":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (null) * 0 (1 limb)
+mbedtls_mpi_mul_mpi:16:"":16:"00":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (null) * 1
+mbedtls_mpi_mul_mpi:16:"":16:"01":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (null) * -1
+mbedtls_mpi_mul_mpi:16:"":16:"-01":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (1 limb) * -1
+mbedtls_mpi_mul_mpi:16:"00":16:"-01":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (1 limb) * 0 (null)
+mbedtls_mpi_mul_mpi:16:"00":16:"":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 1 * 0 (null)
+mbedtls_mpi_mul_mpi:16:"01":16:"":16:"0"
+
+Test mbedtls_mpi_mul_mpi: -1 * 0 (null)
+mbedtls_mpi_mul_mpi:16:"-01":16:"":16:"0"
+
+Test mbedtls_mpi_mul_mpi: -1 * 0 (1 limb)
+mbedtls_mpi_mul_mpi:16:"-01":16:"00":16:"0"
+
 Test mbedtls_mpi_mul_mpi #1
-mbedtls_mpi_mul_mpi:10:"28911710017320205966167820725313234361535259163045867986277478145081076845846493521348693253530011243988160148063424837895971948244167867236923919506962312185829914482993478947657472351461336729641485069323635424692930278888923450060546465883490944265147851036817433970984747733020522259537":10:"16471581891701794764704009719057349996270239948993452268812975037240586099924712715366967486587417803753916334331355573776945238871512026832810626226164346328807407669366029926221415383560814338828449642265377822759768011406757061063524768140567867350208554439342320410551341675119078050953":10:"476221599179424887669515829231223263939342135681791605842540429321038144633323941248706405375723482912535192363845116154236465184147599697841273424891410002781967962186252583311115708128167171262206919514587899883547279647025952837516324649656913580411611297312678955801899536937577476819667861053063432906071315727948826276092545739432005962781562403795455162483159362585281248265005441715080197800335757871588045959754547836825977169125866324128449699877076762316768127816074587766799018626179199776188490087103869164122906791440101822594139648973454716256383294690817576188761"
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in B
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in B, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in B, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A
+mbedtls_mpi_mul_mpi:16:"000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A, A < 0
+mbedtls_mpi_mul_mpi:16:"-000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A, B < 0
+mbedtls_mpi_mul_mpi:16:"000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A and B
+mbedtls_mpi_mul_mpi:16:"000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A and B, A < 0
+mbedtls_mpi_mul_mpi:16:"-000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A and B, B < 0
+mbedtls_mpi_mul_mpi:16:"000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A and B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in B
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in B, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in B, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A and B
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A and B, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A and B, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A and B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in A
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf245100000000000000000000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in A, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf245100000000000000000000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in A, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf245100000000000000000000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in A, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf245100000000000000000000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in B
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c8900000000000000000000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in B, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c8900000000000000000000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in B, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c8900000000000000000000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c8900000000000000000000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
 
 Test mbedtls_mpi_mul_int #1
 mbedtls_mpi_mul_int:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":9871232:10:"20133056642518226042310730101376278483547239130123806338055387803943342738063359782107667328":"=="
@@ -625,15 +1090,45 @@
 Test mbedtls_mpi_mul_int #4 (Unsigned, thus failure)
 mbedtls_mpi_mul_int:10:"-2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":-9871232:10:"20133056642518226042310730101376278483547239130123806338055387803943342738063359782107667328":"!="
 
+Test mbedtls_mpi_mul_int: 0 (null) * 0
+mbedtls_mpi_mul_int:16:"":0:16:"":"=="
+
+Test mbedtls_mpi_mul_int: 0 (null) * 1
+mbedtls_mpi_mul_int:16:"":1:16:"":"=="
+
+Test mbedtls_mpi_mul_int: 0 (null) * 0x1234
+mbedtls_mpi_mul_int:16:"":0x1234:16:"":"=="
+
 Base test mbedtls_mpi_div_mpi #1
 mbedtls_mpi_div_mpi:10:"1000":10:"13":10:"76":10:"12":0
 
-Base test mbedtls_mpi_div_mpi #2 (Divide by zero)
+Base test mbedtls_mpi_div_mpi #2 (Divide by zero (1 limb))
 mbedtls_mpi_div_mpi:10:"1000":10:"0":10:"1":10:"1":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
 
+Base test mbedtls_mpi_div_mpi #2 (Divide by zero (null))
+mbedtls_mpi_div_mpi:10:"1000":10:"":10:"1":10:"1":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
 Base test mbedtls_mpi_div_mpi #3
 mbedtls_mpi_div_mpi:10:"1000":10:"-13":10:"-76":10:"12":0
 
+Test mbedtls_mpi_div_mpi: 0 (null) / 0 (null)
+mbedtls_mpi_div_mpi:16:"":16:"":16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_mpi: 0 (null) / 0 (1 limb)
+mbedtls_mpi_div_mpi:16:"":16:"0":16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_mpi: 0 (1 limb) / 0 (null)
+mbedtls_mpi_div_mpi:16:"0":16:"":16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_mpi: 0 (1 limb) / 0 (1 limb)
+mbedtls_mpi_div_mpi:16:"0":16:"0":16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_mpi: 0 (null) / 1
+mbedtls_mpi_div_mpi:16:"":16:"1":16:"":16:"":0
+
+Test mbedtls_mpi_div_mpi: 0 (null) / -1
+mbedtls_mpi_div_mpi:16:"":16:"-1":16:"":16:"":0
+
 Test mbedtls_mpi_div_mpi #1
 mbedtls_mpi_div_mpi:10:"20133056642518226042310730101376278483547239130123806338055387803943342738063359782107667328":10:"34":10:"592148724779947824773845002981655249516095268533053127589864347174804198178334111238460803":10:"26":0
 
@@ -661,10 +1156,22 @@
 Test mbedtls_mpi_div_int #2
 mbedtls_mpi_div_int:10:"20133056642518226042310730101376278483547239130123806338055387803943342738063359782107667328":-34:10:"-592148724779947824773845002981655249516095268533053127589864347174804198178334111238460803":10:"26":0
 
+Test mbedtls_mpi_div_int: 0 (null) / 0
+mbedtls_mpi_div_int:16:"":0:16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_int: 0 (1 limb) / 0
+mbedtls_mpi_div_int:16:"00":0:16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_int: 0 (null) / 1
+mbedtls_mpi_div_int:16:"":1:16:"":16:"":0
+
 Base test mbedtls_mpi_mod_mpi #1
 mbedtls_mpi_mod_mpi:10:"1000":10:"13":10:"12":0
 
-Base test mbedtls_mpi_mod_mpi #2 (Divide by zero)
+Base test mbedtls_mpi_mod_mpi #2 (Divide by zero (null))
+mbedtls_mpi_mod_mpi:10:"1000":10:"":10:"0":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Base test mbedtls_mpi_mod_mpi #2 (Divide by zero (1 limb))
 mbedtls_mpi_mod_mpi:10:"1000":10:"0":10:"0":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
 
 Base test mbedtls_mpi_mod_mpi #3
@@ -676,6 +1183,12 @@
 Base test mbedtls_mpi_mod_mpi #5 (Negative modulo)
 mbedtls_mpi_mod_mpi:10:"-1000":10:"-13":10:"-12":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
 
+Test mbedtls_mpi_mod_mpi: 0 (null) % 1
+mbedtls_mpi_mod_mpi:16:"":16:"1":16:"":0
+
+Test mbedtls_mpi_mod_mpi: 0 (null) % -1
+mbedtls_mpi_mod_mpi:16:"":16:"-1":16:"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
 Base test mbedtls_mpi_mod_int #1
 mbedtls_mpi_mod_int:10:"1000":13:12:0
 
@@ -700,23 +1213,74 @@
 Base test mbedtls_mpi_mod_int #8 (By 2)
 mbedtls_mpi_mod_int:10:"1000":2:0:0
 
+Test mbedtls_mpi_mod_int: 0 (null) % 1
+mbedtls_mpi_mod_int:16:"":1:0:0
+
+Test mbedtls_mpi_mod_int: 0 (null) % -1
+mbedtls_mpi_mod_int:16:"":-1:0:MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
 Base test mbedtls_mpi_exp_mod #1
-mbedtls_mpi_exp_mod:10:"23":10:"13":10:"29":10:"":10:"24":0
+mbedtls_mpi_exp_mod:10:"23":10:"13":10:"29":10:"24":0
 
 Base test mbedtls_mpi_exp_mod #2 (Even N)
-mbedtls_mpi_exp_mod:10:"23":10:"13":10:"30":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+mbedtls_mpi_exp_mod:10:"23":10:"13":10:"30":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Base test mbedtls_mpi_exp_mod #2 (N = 0 (null))
+mbedtls_mpi_exp_mod:10:"23":10:"13":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
 Base test mbedtls_mpi_exp_mod #3 (Negative N)
-mbedtls_mpi_exp_mod:10:"23":10:"13":10:"-29":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+mbedtls_mpi_exp_mod:10:"23":10:"13":10:"-29":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
 Base test mbedtls_mpi_exp_mod #4 (Negative base)
-mbedtls_mpi_exp_mod:10:"-23":10:"13":10:"29":10:"":10:"5":0
+mbedtls_mpi_exp_mod:10:"-23":10:"13":10:"29":10:"5":0
 
 Base test mbedtls_mpi_exp_mod #5 (Negative exponent)
-mbedtls_mpi_exp_mod:10:"23":10:"-13":10:"29":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+mbedtls_mpi_exp_mod:10:"23":10:"-13":10:"29":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
 Base test mbedtls_mpi_exp_mod #6 (Negative base + exponent)
-mbedtls_mpi_exp_mod:10:"-23":10:"-13":10:"29":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+mbedtls_mpi_exp_mod:10:"-23":10:"-13":10:"29":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_exp_mod: 0 (null) ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 0 (null) ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"":16:"00":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 0 (null) ^ 1 mod 9
+mbedtls_mpi_exp_mod:16:"":16:"01":16:"09":16:"":0
+
+Test mbedtls_mpi_exp_mod: 0 (null) ^ 2 mod 9
+mbedtls_mpi_exp_mod:16:"":16:"02":16:"09":16:"":0
+
+Test mbedtls_mpi_exp_mod: 0 (1 limb) ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"00":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 0 (1 limb) ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"00":16:"00":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 0 (1 limb) ^ 1 mod 9
+mbedtls_mpi_exp_mod:16:"00":16:"01":16:"09":16:"":0
+
+Test mbedtls_mpi_exp_mod: 0 (1 limb) ^ 2 mod 9
+mbedtls_mpi_exp_mod:16:"00":16:"02":16:"09":16:"":0
+
+Test mbedtls_mpi_exp_mod: 1 ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"01":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 4 ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"04":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 10 ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"0a":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 1 ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"01":16:"00":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 4 ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"04":16:"00":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 10 ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"0a":16:"00":16:"09":16:"1":0
 
 Test mbedtls_mpi_exp_mod: MAX_SIZE exponent
 mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE:10:10:"":0
@@ -738,14 +1302,14 @@
 
 Test mbedtls_mpi_exp_mod #1
 depends_on:MPI_MAX_BITS_LARGER_THAN_792
-mbedtls_mpi_exp_mod:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"583137007797276923956891216216022144052044091311388601652961409557516421612874571554415606746479105795833145583959622117418531166391184939066520869800857530421873250114773204354963864729386957427276448683092491947566992077136553066273207777134303397724679138833126700957":10:"":10:"114597449276684355144920670007147953232659436380163461553186940113929777196018164149703566472936578890991049344459204199888254907113495794730452699842273939581048142004834330369483813876618772578869083248061616444392091693787039636316845512292127097865026290173004860736":0
+mbedtls_mpi_exp_mod:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"583137007797276923956891216216022144052044091311388601652961409557516421612874571554415606746479105795833145583959622117418531166391184939066520869800857530421873250114773204354963864729386957427276448683092491947566992077136553066273207777134303397724679138833126700957":10:"114597449276684355144920670007147953232659436380163461553186940113929777196018164149703566472936578890991049344459204199888254907113495794730452699842273939581048142004834330369483813876618772578869083248061616444392091693787039636316845512292127097865026290173004860736":0
 
 Test mbedtls_mpi_exp_mod (Negative base) [#1]
-mbedtls_mpi_exp_mod:10:"-10000000000":10:"10000000000":10:"99999":10:"":10:"1":0
+mbedtls_mpi_exp_mod:10:"-10000000000":10:"10000000000":10:"99999":10:"1":0
 
 Test mbedtls_mpi_exp_mod (Negative base) [#2]
 depends_on:MPI_MAX_BITS_LARGER_THAN_792
-mbedtls_mpi_exp_mod:16:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":16:"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":16:"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":16:"":16:"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0
+mbedtls_mpi_exp_mod:16:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":16:"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":16:"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":16:"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0
 
 Base test GCD #1
 mbedtls_mpi_gcd:10:"693":10:"609":10:"21"
@@ -756,24 +1320,105 @@
 Base test GCD #3
 mbedtls_mpi_gcd:10:"768454923":10:"542167814":10:"1"
 
-Test GCD #1
+Test GCD: 0 (null), 0 (null)
+mbedtls_mpi_gcd:16:"":16:"":16:"0"
+
+Test GCD: 0 (null), 0 (1 limb)
+mbedtls_mpi_gcd:16:"":16:"00":16:"0"
+
+Test GCD: 0 (null), 3
+mbedtls_mpi_gcd:16:"":16:"03":16:"3"
+
+Test GCD: 0 (null), 6
+mbedtls_mpi_gcd:16:"":16:"06":16:"6"
+
+Test GCD: 0 (1 limb), 0 (null)
+mbedtls_mpi_gcd:16:"00":16:"":16:"0"
+
+Test GCD: 0 (1 limb), 3
+mbedtls_mpi_gcd:16:"00":16:"03":16:"3"
+
+Test GCD: 0 (1 limb), 6
+mbedtls_mpi_gcd:16:"00":16:"06":16:"6"
+
+Test GCD: 3, 0 (null)
+mbedtls_mpi_gcd:16:"03":16:"":16:"3"
+
+Test GCD: 3, 0 (1 limb)
+mbedtls_mpi_gcd:16:"03":16:"00":16:"3"
+
+Test GCD: 6, 0 (null)
+mbedtls_mpi_gcd:16:"06":16:"":16:"6"
+
+Test GCD: 6, 0 (1 limb)
+mbedtls_mpi_gcd:16:"06":16:"00":16:"6"
+
+Test GCD: gcd=1, 0 < A < B
 mbedtls_mpi_gcd:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"1"
 
+Test GCD: gcd=1, 0 < B < A
+mbedtls_mpi_gcd:10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"1"
+
+Test GCD: gcd=1, A > 0, B < 0
+mbedtls_mpi_gcd:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"-5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"1"
+
+Test GCD: gcd=1, A < 0 < B, |A| < |B|
+mbedtls_mpi_gcd:10:"-433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"1"
+
+Test GCD: gcd=1, B < A < 0
+mbedtls_mpi_gcd:10:"-433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"-5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"1"
+
+Test GCD: gcd=2, 0 < A < B
+mbedtls_mpi_gcd:10:"866038481820754956434747145919120219639297294032193121047538021762345738166676571147513149114791725930190032967735626087327963892955396933002903664815184654712662526249110275464787876484571564289857507839177265358101598397874265844290169694":10:"11563076655955657794301818333556815318500916759291646124084984923153517053514981820147256017227955101092765549551141776260059527143057399149435166457879071920468928461765147231860769958200758205831314967733510743119623437535521189838913942708368227442":10:"2"
+
+Test GCD: gcd=2, 0 < B < A
+mbedtls_mpi_gcd:10:"11563076655955657794301818333556815318500916759291646124084984923153517053514981820147256017227955101092765549551141776260059527143057399149435166457879071920468928461765147231860769958200758205831314967733510743119623437535521189838913942708368227442":10:"866038481820754956434747145919120219639297294032193121047538021762345738166676571147513149114791725930190032967735626087327963892955396933002903664815184654712662526249110275464787876484571564289857507839177265358101598397874265844290169694":10:"2"
+
+Test GCD: gcd=3, 0 < A < B
+mbedtls_mpi_gcd:10:"1299057722731132434652120718878680329458945941048289681571307032643518607250014856721269723672187588895285049451603439130991945839433095399504355497222776982068993789373665413197181814726857346434786261758765898037152397596811398766435254541":10:"17344614983933486691452727500335222977751375138937469186127477384730275580272472730220884025841932651639148324326712664390089290714586098724152749686818607880703392692647720847791154937301137308746972451600266114679435156303281784758370914062552341163":10:"3"
+
+Test GCD: gcd=3, 0 < B < A
+mbedtls_mpi_gcd:10:"17344614983933486691452727500335222977751375138937469186127477384730275580272472730220884025841932651639148324326712664390089290714586098724152749686818607880703392692647720847791154937301137308746972451600266114679435156303281784758370914062552341163":10:"1299057722731132434652120718878680329458945941048289681571307032643518607250014856721269723672187588895285049451603439130991945839433095399504355497222776982068993789373665413197181814726857346434786261758765898037152397596811398766435254541":10:"3"
+
+Test GCD: gcd=4, 0 < A < B
+mbedtls_mpi_gcd:10:"1732076963641509912869494291838240439278594588064386242095076043524691476333353142295026298229583451860380065935471252174655927785910793866005807329630369309425325052498220550929575752969143128579715015678354530716203196795748531688580339388":10:"23126153311911315588603636667113630637001833518583292248169969846307034107029963640294512034455910202185531099102283552520119054286114798298870332915758143840937856923530294463721539916401516411662629935467021486239246875071042379677827885416736454884":10:"4"
+
+Test GCD: gcd=4, 0 < B < A
+mbedtls_mpi_gcd:10:"23126153311911315588603636667113630637001833518583292248169969846307034107029963640294512034455910202185531099102283552520119054286114798298870332915758143840937856923530294463721539916401516411662629935467021486239246875071042379677827885416736454884":10:"1732076963641509912869494291838240439278594588064386242095076043524691476333353142295026298229583451860380065935471252174655927785910793866005807329630369309425325052498220550929575752969143128579715015678354530716203196795748531688580339388":10:"4"
+
+Test GCD: gcd=6, 0 < A < B
+mbedtls_mpi_gcd:10:"2598115445462264869304241437757360658917891882096579363142614065287037214500029713442539447344375177790570098903206878261983891678866190799008710994445553964137987578747330826394363629453714692869572523517531796074304795193622797532870509082":10:"34689229967866973382905455000670445955502750277874938372254954769460551160544945460441768051683865303278296648653425328780178581429172197448305499373637215761406785385295441695582309874602274617493944903200532229358870312606563569516741828125104682326":10:"6"
+
+Test GCD: gcd=6, 0 < B < A
+mbedtls_mpi_gcd:10:"34689229967866973382905455000670445955502750277874938372254954769460551160544945460441768051683865303278296648653425328780178581429172197448305499373637215761406785385295441695582309874602274617493944903200532229358870312606563569516741828125104682326":10:"2598115445462264869304241437757360658917891882096579363142614065287037214500029713442539447344375177790570098903206878261983891678866190799008710994445553964137987578747330826394363629453714692869572523517531796074304795193622797532870509082":10:"6"
+
+Test GCD: 0 < A = B
+mbedtls_mpi_gcd:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847"
+
 Base test mbedtls_mpi_inv_mod #1
 mbedtls_mpi_inv_mod:10:"3":10:"11":10:"4":0
 
-Base test mbedtls_mpi_inv_mod #2
+Test mbedtls_mpi_inv_mod: mod 0 (null)
+mbedtls_mpi_inv_mod:10:"3":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_inv_mod: mod 0 (1 limb)
 mbedtls_mpi_inv_mod:10:"3":10:"0":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
-Base test mbedtls_mpi_inv_mod #3
+Test mbedtls_mpi_inv_mod: mod negative
 mbedtls_mpi_inv_mod:10:"3":10:"-11":10:"4":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
-Base test mbedtls_mpi_inv_mod #4
+Test mbedtls_mpi_inv_mod: 2^-1 mod 4
 mbedtls_mpi_inv_mod:10:"2":10:"4":10:"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
 
-Base test mbedtls_mpi_inv_mod #5
+Test mbedtls_mpi_inv_mod: mod 1
 mbedtls_mpi_inv_mod:10:"3":10:"1":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+Test mbedtls_mpi_inv_mod: 0 (null) ^-1
+mbedtls_mpi_inv_mod:16:"":16:"11":16:"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+
+Test mbedtls_mpi_inv_mod: 0 (1 limb) ^-1
+mbedtls_mpi_inv_mod:16:"00":16:"11":16:"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+
 Test mbedtls_mpi_inv_mod #1
 mbedtls_mpi_inv_mod:16:"aa4df5cb14b4c31237f98bd1faf527c283c2d0f3eec89718664ba33f9762907c":16:"fffbbd660b94412ae61ead9c2906a344116e316a256fd387874c6c675b1d587d":16:"8d6a5c1d7adeae3e94b9bcd2c47e0d46e778bc8804a2cc25c02d775dc3d05b0c":0
 
@@ -958,6 +1603,9 @@
 Test bit getting (Larger and non-existing limb)
 mbedtls_mpi_get_bit:10:"49979687":500:0
 
+Test bit getting in 0 (null)
+mbedtls_mpi_get_bit:10:"":500:0
+
 Test bit getting (Value bit 24)
 mbedtls_mpi_get_bit:10:"49979687":24:0
 
@@ -976,6 +1624,12 @@
 Test bit set (Add above existing limbs with a 1)
 mbedtls_mpi_set_bit:10:"49979687":80:1:10:"1208925819614629224685863":0
 
+Test bit set (Add to 0 (null) with a 0)
+mbedtls_mpi_set_bit:16:"":65:0:16:"":0
+
+Test bit set (Add to 0 (null) with a 1)
+mbedtls_mpi_set_bit:16:"":65:1:16:"020000000000000000":0
+
 Test bit set (Bit index larger than 31 with a 0)
 mbedtls_mpi_set_bit:16:"FFFFFFFFFFFFFFFF":32:0:16:"FFFFFFFEFFFFFFFF":0
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index eb918b3..1372668 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -6,6 +6,18 @@
 #define MPI_MAX_BITS_LARGER_THAN_792
 #endif
 
+/* Check the validity of the sign bit in an MPI object. Reject representations
+ * that are not supported by the rest of the library and indicate a bug when
+ * constructing the value. */
+static int sign_is_valid( const mbedtls_mpi *X )
+{
+    if( X->s != 1 && X->s != -1 )
+        return( 0 ); // invalid sign bit, e.g. 0
+    if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
+        return( 0 ); // negative zero
+    return( 1 );
+}
+
 typedef struct mbedtls_test_mpi_random
 {
     data_t *data;
@@ -150,6 +162,7 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
     if( result_read == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &X ) );
         TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
         if( result_write == 0 )
         {
@@ -174,6 +187,7 @@
 
 
     TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
     TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
 
@@ -193,6 +207,7 @@
 
 
     TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
     TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
 
@@ -214,7 +229,7 @@
 
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     buflen = mbedtls_mpi_size( &X );
     if( buflen > (size_t) output_size )
@@ -246,7 +261,7 @@
 
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     buflen = mbedtls_mpi_size( &X );
     if( buflen > (size_t) output_size )
@@ -287,6 +302,7 @@
 
     if( result == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &X ) );
         buflen = mbedtls_mpi_size( &X );
         TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
 
@@ -310,7 +326,7 @@
 
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     file_out = fopen( output_file, "w" );
     TEST_ASSERT( file_out != NULL );
@@ -336,7 +352,7 @@
 {
     mbedtls_mpi X;
     mbedtls_mpi_init( &X );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
 
 exit:
@@ -351,12 +367,13 @@
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, output_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, output_Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
 
     if( result == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &X ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
     }
 
@@ -371,7 +388,7 @@
     mbedtls_mpi X;
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
 
 exit:
@@ -385,7 +402,7 @@
     mbedtls_mpi X;
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
 
 exit:
@@ -400,10 +417,11 @@
     mbedtls_mpi A, X, Y, Z;
     mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
 exit:
@@ -432,8 +450,8 @@
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
 
 exit:
@@ -451,8 +469,8 @@
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, input_Y ) == 0 );
 
     TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
@@ -473,8 +491,8 @@
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
 
 exit:
@@ -483,55 +501,125 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mbedtls_mpi_copy_sint( int input_X, int input_Y )
+void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
 {
-    mbedtls_mpi X, Y;
+    mbedtls_mpi src, dst, ref;
+    mbedtls_mpi_init( &src );
+    mbedtls_mpi_init( &dst );
+    mbedtls_mpi_init( &ref );
+
+    TEST_ASSERT( mbedtls_test_read_mpi( &src, 16, src_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &ref, 16, dst_hex ) == 0 );
+
+    /* mbedtls_mpi_copy() */
+    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
+    TEST_ASSERT( sign_is_valid( &dst ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
+
+    /* mbedtls_mpi_safe_cond_assign(), assignment done */
+    mbedtls_mpi_free( &dst );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &dst ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
+
+    /* mbedtls_mpi_safe_cond_assign(), assignment not done */
+    mbedtls_mpi_free( &dst );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &dst ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &src );
+    mbedtls_mpi_free( &dst );
+    mbedtls_mpi_free( &ref );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_copy_self( char *input_X )
+{
+    mbedtls_mpi X, A;
+    mbedtls_mpi_init( &A );
+    mbedtls_mpi_init( &X );
+
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
+
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, 16, input_X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &A );
+    mbedtls_mpi_free( &X );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
+{
+    mbedtls_mpi X, Y, X0, Y0;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
+    mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
 
-    TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X0, 16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y0, 16, Y_hex ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
+    /* mbedtls_mpi_swap() */
+    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
+    mbedtls_mpi_swap( &X, &Y );
+    TEST_ASSERT( sign_is_valid( &X ) );
+    TEST_ASSERT( sign_is_valid( &Y ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
+
+    /* mbedtls_mpi_safe_cond_swap(), swap done */
+    mbedtls_mpi_free( &X );
+    mbedtls_mpi_free( &Y );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
+    TEST_ASSERT( sign_is_valid( &Y ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
+
+    /* mbedtls_mpi_safe_cond_swap(), swap not done */
+    mbedtls_mpi_free( &X );
+    mbedtls_mpi_free( &Y );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
+    TEST_ASSERT( sign_is_valid( &Y ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
 
 exit:
     mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
+    mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mbedtls_mpi_copy_binary( data_t *input_X, data_t *input_Y )
+void mpi_swap_self( char *X_hex )
 {
-    mbedtls_mpi X, Y, X0;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &X0 );
+    mbedtls_mpi X, X0;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X0, 16, X_hex ) == 0 );
+
+    mbedtls_mpi_swap( &X, &X );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
-
 exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &X0 );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mpi_copy_self( int input_X )
-{
-    mbedtls_mpi X;
-    mbedtls_mpi_init( &X );
-
-    TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X );
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
 }
 /* END_CASE */
 
@@ -542,10 +630,14 @@
     mbedtls_mpi_init( &X );
 
     TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
-    TEST_ASSERT( used <= before );
-    memset( X.p, 0x2a, used * sizeof( mbedtls_mpi_uint ) );
+    if( used > 0 )
+    {
+        size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
+        TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
+    }
+    TEST_EQUAL( X.n, (size_t) before );
     TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
-    TEST_ASSERT( X.n == (size_t) after );
+    TEST_EQUAL( X.n, (size_t) after );
 
 exit:
     mbedtls_mpi_free( &X );
@@ -553,139 +645,28 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mbedtls_mpi_safe_cond_assign( int x_sign, char * x_str, int y_sign,
-                                   char * y_str )
-{
-    mbedtls_mpi X, Y, XX;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &XX );
-
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x_str ) == 0 );
-    X.s = x_sign;
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y_str ) == 0 );
-    Y.s = y_sign;
-    TEST_ASSERT( mbedtls_mpi_copy( &XX, &X ) == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &X, &Y, 0 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &XX ) == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &X, &Y, 1 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &XX );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mbedtls_mpi_safe_cond_swap( int x_sign, char * x_str, int y_sign,
-                                 char * y_str )
-{
-    mbedtls_mpi X, Y, XX, YY;
-
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
-    mbedtls_mpi_init( &XX ); mbedtls_mpi_init( &YY );
-
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x_str ) == 0 );
-    X.s = x_sign;
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y_str ) == 0 );
-    Y.s = y_sign;
-
-    TEST_ASSERT( mbedtls_mpi_copy( &XX, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_copy( &YY, &Y ) == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &XX ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &YY ) == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &XX ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &YY ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
-    mbedtls_mpi_free( &XX ); mbedtls_mpi_free( &YY );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mbedtls_mpi_swap_sint( int input_X, int input_Y )
-{
-    mbedtls_mpi X, Y;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
-
-    TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_Y ) == 0 );
-
-    mbedtls_mpi_swap( &X, &Y );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mbedtls_mpi_swap_binary( data_t *input_X, data_t *input_Y )
-{
-    mbedtls_mpi X, Y, X0, Y0;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
-    mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
-
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &Y0, input_Y->x, input_Y->len ) == 0 );
-
-    mbedtls_mpi_swap( &X, &Y );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
-    mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mpi_swap_self( data_t *input_X )
-{
-    mbedtls_mpi X, X0;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
-
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
-
-    mbedtls_mpi_swap( &X, &X );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
 void mbedtls_mpi_add_mpi( int radix_X, char * input_X, int radix_Y,
                           char * input_Y, int radix_A, char * input_A )
 {
     mbedtls_mpi X, Y, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
     /* result == first operand */
     TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Y ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
 exit:
@@ -700,18 +681,21 @@
     mbedtls_mpi X, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
 
 exit:
@@ -727,19 +711,22 @@
     mbedtls_mpi X, Y, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
     /* result == first operand */
     TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Y ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
 exit:
@@ -754,9 +741,10 @@
     mbedtls_mpi X, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
 exit:
@@ -771,19 +759,22 @@
     mbedtls_mpi X, Y, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
     /* result == first operand */
     TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Y ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
 exit:
@@ -800,23 +791,26 @@
     int res;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
 
     res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
     TEST_ASSERT( res == sub_result );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     if( res == 0 )
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
     /* result == first operand */
     TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
+    TEST_ASSERT( sign_is_valid( &X ) );
     if( sub_result == 0 )
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
+    TEST_ASSERT( sign_is_valid( &Y ) );
     if( sub_result == 0 )
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
@@ -832,9 +826,10 @@
     mbedtls_mpi X, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
 exit:
@@ -849,10 +844,11 @@
     mbedtls_mpi X, Y, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
 exit:
@@ -868,9 +864,10 @@
     mbedtls_mpi X, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     if( strcmp( result_comparison, "==" ) == 0 )
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
     else if( strcmp( result_comparison, "!=" ) == 0 )
@@ -893,14 +890,16 @@
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
     mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &B, radix_B, input_B ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
     res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &Q ) );
+        TEST_ASSERT( sign_is_valid( &R ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
     }
@@ -921,13 +920,15 @@
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
     mbedtls_mpi_init( &B );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &B, radix_B, input_B ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
     res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &Q ) );
+        TEST_ASSERT( sign_is_valid( &R ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
     }
@@ -947,13 +948,14 @@
     int res;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &X ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
     }
 
@@ -971,7 +973,7 @@
     mbedtls_mpi_uint r;
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     res = mbedtls_mpi_mod_int( &r, &X, input_Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
@@ -987,26 +989,41 @@
 /* BEGIN_CASE */
 void mbedtls_mpi_exp_mod( int radix_A, char * input_A, int radix_E,
                           char * input_E, int radix_N, char * input_N,
-                          int radix_RR, char * input_RR, int radix_X,
-                          char * input_X, int div_result )
+                          int radix_X, char * input_X, int exp_result )
 {
     mbedtls_mpi A, E, N, RR, Z, X;
     int res;
     mbedtls_mpi_init( &A  ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
     mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
-    if( strlen( input_RR ) )
-        TEST_ASSERT( mbedtls_mpi_read_string( &RR, radix_RR, input_RR ) == 0 );
-
-    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
-    TEST_ASSERT( res == div_result );
+    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
+    TEST_ASSERT( res == exp_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &Z ) );
+        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
+    }
+
+    /* Now test again with the speed-up parameter supplied as an output. */
+    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
+    TEST_ASSERT( res == exp_result );
+    if( res == 0 )
+    {
+        TEST_ASSERT( sign_is_valid( &Z ) );
+        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
+    }
+
+    /* Now test again with the speed-up parameter supplied in calculated form. */
+    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
+    TEST_ASSERT( res == exp_result );
+    if( res == 0 )
+    {
+        TEST_ASSERT( sign_is_valid( &Z ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
     }
 
@@ -1040,7 +1057,7 @@
     TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
 
     if( strlen( input_RR ) )
-        TEST_ASSERT( mbedtls_mpi_read_string( &RR, radix_RR, input_RR ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &RR, radix_RR, input_RR ) == 0 );
 
     TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
 
@@ -1059,13 +1076,14 @@
     int res;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &Z ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
     }
 
@@ -1081,7 +1099,7 @@
     int res;
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
     TEST_ASSERT( res == div_result );
 
@@ -1141,6 +1159,7 @@
 
         TEST_ASSERT( actual_bits >= (size_t) bits );
         TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
+        TEST_ASSERT( sign_is_valid( &X ) );
 
         TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
                                                mbedtls_test_rnd_std_rand,
@@ -1167,9 +1186,10 @@
     mbedtls_mpi X, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
 
 exit:
@@ -1184,9 +1204,10 @@
     mbedtls_mpi X, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
 
 exit:
@@ -1228,6 +1249,7 @@
         TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
                      (size_t) wanted_bytes );
         TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
+        TEST_ASSERT( sign_is_valid( &X ) );
     }
 
 exit:
@@ -1285,6 +1307,7 @@
         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 )
@@ -1366,6 +1389,7 @@
                                             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 );
 
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 5ccb072..56cc45b 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -226,7 +226,7 @@
     TEST_ASSERT( mbedtls_pk_sign_restartable( &pk,
                                               MBEDTLS_MD_NONE,
                                               NULL, 0,
-                                              buf, &len,
+                                              buf, sizeof( buf ), &len,
                                               mbedtls_test_rnd_std_rand, NULL,
                                               NULL ) ==
                  MBEDTLS_ERR_PK_BAD_INPUT_DATA );
@@ -234,7 +234,7 @@
     TEST_ASSERT( mbedtls_pk_sign_restartable( &pk,
                                               MBEDTLS_MD_NONE,
                                               NULL, 0,
-                                              buf, &len,
+                                              buf, sizeof( buf ), &len,
                                               mbedtls_test_rnd_std_rand, NULL,
                                               NULL ) ==
                  MBEDTLS_ERR_PK_BAD_INPUT_DATA );
@@ -242,7 +242,7 @@
     TEST_ASSERT( mbedtls_pk_sign( &pk,
                                   MBEDTLS_MD_NONE,
                                   NULL, 0,
-                                  buf, &len,
+                                  buf, sizeof( buf ), &len,
                                   mbedtls_test_rnd_std_rand, NULL ) ==
                  MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
@@ -403,8 +403,8 @@
     rsa = mbedtls_pk_rsa( pk );
 
     rsa->len = mod / 8;
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->E, radix_E, input_E ) == 0 );
 
 
     if( mbedtls_md_info_from_type( digest ) != NULL )
@@ -446,15 +446,16 @@
     rsa = mbedtls_pk_rsa( pk );
 
     rsa->len = mod / 8;
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->E, radix_E, input_E ) == 0 );
 
 
     if( digest != MBEDTLS_MD_NONE )
     {
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ),
-                     message_str->x, message_str->len, hash_result ) == 0 );
-        hash_len = 0;
+        const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
+        TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len,
+                                 hash_result ) == 0 );
+        hash_len = mbedtls_md_get_size( md_info );
     }
     else
     {
@@ -534,7 +535,7 @@
 
     TEST_ASSERT( mbedtls_pk_setup( &prv, mbedtls_pk_info_from_type( pk_type ) ) == 0 );
     TEST_ASSERT( mbedtls_ecp_group_load( &mbedtls_pk_ec( prv )->grp, grp_id ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &mbedtls_pk_ec( prv )->d, 16, d_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &mbedtls_pk_ec( prv )->d, 16, d_str ) == 0 );
 
     TEST_ASSERT( mbedtls_pk_setup( &pub, mbedtls_pk_info_from_type( pk_type ) ) == 0 );
     TEST_ASSERT( mbedtls_ecp_group_load( &mbedtls_pk_ec( pub )->grp, grp_id ) == 0 );
@@ -554,8 +555,9 @@
     cnt_restart = 0;
     do {
         ret = mbedtls_pk_sign_restartable( &prv, md_alg, hash, hlen,
-                                            sig, &slen, mbedtls_test_rnd_std_rand,
-                                            NULL, &rs_ctx );
+                                           sig, sizeof( sig ), &slen,
+                                           mbedtls_test_rnd_std_rand, NULL,
+                                           &rs_ctx );
     } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
 
     TEST_ASSERT( ret == 0 );
@@ -602,8 +604,9 @@
 
         slen = sizeof( sig );
         ret = mbedtls_pk_sign_restartable( &prv, md_alg, hash, hlen,
-                                            sig, &slen, mbedtls_test_rnd_std_rand,
-                                            NULL, &rs_ctx );
+                                           sig, sizeof sig, &slen,
+                                           mbedtls_test_rnd_std_rand, NULL,
+                                           &rs_ctx );
         TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
     }
 
@@ -619,7 +622,8 @@
 {
     mbedtls_pk_context pk;
     size_t sig_len;
-    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+    unsigned char hash[32]; // Hard-coded for SHA256
+    size_t hash_len = sizeof( hash );
     unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
     void *rs_ctx = NULL;
 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
@@ -643,31 +647,33 @@
     TEST_ASSERT( pk_genkey( &pk, parameter ) == 0 );
 
     TEST_ASSERT( mbedtls_pk_sign_restartable( &pk, MBEDTLS_MD_SHA256,
-                 hash, sizeof hash, sig, &sig_len,
-                 mbedtls_test_rnd_std_rand, NULL, rs_ctx ) == sign_ret );
+                                              hash, hash_len,
+                                              sig, sizeof sig, &sig_len,
+                                              mbedtls_test_rnd_std_rand, NULL,
+                                              rs_ctx ) == sign_ret );
     if( sign_ret == 0 )
         TEST_ASSERT( sig_len <= MBEDTLS_PK_SIGNATURE_MAX_SIZE );
     else
         sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE;
 
     TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_SHA256,
-                            hash, sizeof hash, sig, sig_len ) == verify_ret );
+                            hash, hash_len, sig, sig_len ) == verify_ret );
 
     if( verify_ret == 0 )
     {
         hash[0]++;
         TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_SHA256,
-                                hash, sizeof hash, sig, sig_len ) != 0 );
+                                hash, hash_len, sig, sig_len ) != 0 );
         hash[0]--;
 
         sig[0]++;
         TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_SHA256,
-                                hash, sizeof hash, sig, sig_len ) != 0 );
+                                hash, hash_len, sig, sig_len ) != 0 );
         sig[0]--;
     }
 
-    TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, sizeof hash,
-                                  sig, &sig_len,
+    TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, hash_len,
+                                  sig, sizeof sig, &sig_len,
                                   mbedtls_test_rnd_std_rand,
                                   NULL ) == sign_ret );
     if( sign_ret == 0 )
@@ -676,7 +682,7 @@
         sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE;
 
     TEST_ASSERT( mbedtls_pk_verify_restartable( &pk, MBEDTLS_MD_SHA256,
-                 hash, sizeof hash, sig, sig_len, rs_ctx ) == verify_ret );
+                 hash, hash_len, sig, sig_len, rs_ctx ) == verify_ret );
 
     if( verify_ret == 0 )
     {
@@ -720,8 +726,8 @@
     rsa = mbedtls_pk_rsa( pk );
 
     rsa->len = mod / 8;
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_pk_encrypt( &pk, message->x, message->len,
                             output, &olen, sizeof( output ),
@@ -759,12 +765,12 @@
     rsa = mbedtls_pk_rsa( pk );
 
     /* load public key */
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     /* load private key */
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( rsa, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( rsa ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_complete( rsa ) == 0 );
@@ -846,8 +852,9 @@
     TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_NONE, hash, hash_len,
                     sig, sig_len ) == MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
-    TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_NONE, hash, hash_len, sig,
-                                  &sig_len, mbedtls_test_rnd_std_rand, NULL )
+    TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_NONE, hash, hash_len,
+                                  sig, sizeof sig, &sig_len,
+                                  mbedtls_test_rnd_std_rand, NULL )
                  == MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
 exit:
@@ -901,12 +908,14 @@
 
     /* Test signature */
 #if SIZE_MAX > UINT_MAX
-    TEST_ASSERT( mbedtls_pk_sign( &alt, MBEDTLS_MD_NONE, hash, SIZE_MAX, sig,
-                                  &sig_len, mbedtls_test_rnd_std_rand, NULL )
+    TEST_ASSERT( mbedtls_pk_sign( &alt, MBEDTLS_MD_NONE, hash, SIZE_MAX,
+                                  sig, sizeof sig, &sig_len,
+                                  mbedtls_test_rnd_std_rand, NULL )
                  == MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 #endif /* SIZE_MAX > UINT_MAX */
-    TEST_ASSERT( mbedtls_pk_sign( &alt, MBEDTLS_MD_NONE, hash, sizeof hash, sig,
-                                  &sig_len, mbedtls_test_rnd_std_rand, NULL )
+    TEST_ASSERT( mbedtls_pk_sign( &alt, MBEDTLS_MD_NONE, hash, sizeof hash,
+                                  sig, sizeof sig, &sig_len,
+                                  mbedtls_test_rnd_std_rand, NULL )
                  == 0 );
     TEST_ASSERT( sig_len == RSA_KEY_LEN );
     TEST_ASSERT( mbedtls_pk_verify( &rsa, MBEDTLS_MD_NONE,
@@ -994,7 +1003,7 @@
     memset( sig, 0, sizeof sig );
 
     TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256,
-                 hash, sizeof hash, sig, &sig_len,
+                 hash, sizeof hash, sig, sizeof sig, &sig_len,
                  NULL, NULL ) == 0 );
 
     /* Export underlying public key for re-importing in a psa context. */
diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function
index d78ee88..6f859d5 100644
--- a/tests/suites/test_suite_pkcs1_v15.function
+++ b/tests/suites/test_suite_pkcs1_v15.function
@@ -30,8 +30,8 @@
                                           MBEDTLS_RSA_PKCS_V15, hash ) == 0 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
@@ -80,10 +80,10 @@
     memset( output, 0x00, sizeof( output ) );
     memset( &rnd_info, 0, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
@@ -269,6 +269,7 @@
                             data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
     unsigned char output[128];
     mbedtls_rsa_context ctx;
     mbedtls_mpi N, P, Q, E;
@@ -288,23 +289,23 @@
     memset( hash_result, 0x00, sizeof( hash_result ) );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
+    if( md_info != NULL )
+        TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len, hash_result ) == 0 );
 
-    if( mbedtls_md_info_from_type( digest ) != NULL )
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str->x, message_str->len, hash_result ) == 0 );
-
-    TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &mbedtls_test_rnd_buffer_rand,
-                                         &info, digest, 0, hash_result,
-                                         output ) == result );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_sign(
+                     &ctx, &mbedtls_test_rnd_buffer_rand, &info,
+                     digest, mbedtls_md_get_size( md_info ), hash_result,
+                     output ) == result );
     if( result == 0 )
     {
 
@@ -326,6 +327,7 @@
                               data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
     mbedtls_rsa_context ctx;
     mbedtls_mpi N, E;
     ((void) salt);
@@ -336,17 +338,17 @@
                                           MBEDTLS_RSA_PKCS_V15, hash ) == 0 );
     memset( hash_result, 0x00, sizeof( hash_result ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
 
-    if( mbedtls_md_info_from_type( digest ) != NULL )
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str->x, message_str->len, hash_result ) == 0 );
+    if( md_info != NULL )
+        TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len, hash_result ) == 0 );
 
-    TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, digest, 0, hash_result, result_str->x ) == result );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, digest, mbedtls_md_get_size( md_info ), hash_result, result_str->x ) == result );
 
 exit:
     mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
diff --git a/tests/suites/test_suite_pkcs1_v21.function b/tests/suites/test_suite_pkcs1_v21.function
index ec5591f..27b0990 100644
--- a/tests/suites/test_suite_pkcs1_v21.function
+++ b/tests/suites/test_suite_pkcs1_v21.function
@@ -123,6 +123,7 @@
                             int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
     unsigned char output[512];
     mbedtls_rsa_context ctx;
     mbedtls_test_rnd_buf_info info;
@@ -152,14 +153,15 @@
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
-    if( mbedtls_md_info_from_type( digest ) != NULL )
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str->x, message_str->len, hash_result ) == 0 );
+    if( md_info != NULL )
+        TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len, hash_result ) == 0 );
 
     if (fixed_salt_length == MBEDTLS_RSA_SALT_LEN_ANY)
     {
-        TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &mbedtls_test_rnd_buffer_rand,
-                                             &info, digest, 0,hash_result,
-                                             output ) == result );
+        TEST_ASSERT( mbedtls_rsa_pkcs1_sign(
+                         &ctx, &mbedtls_test_rnd_buffer_rand, &info,
+                         digest, mbedtls_md_get_size( md_info ), hash_result,
+                         output ) == result );
         if( result == 0 )
         {
             ASSERT_COMPARE( output, ctx.len, result_str->x, result_str->len );
@@ -169,9 +171,10 @@
         info.length = rnd_buf->len;
     }
 
-    TEST_ASSERT( mbedtls_rsa_rsassa_pss_sign_ext( &ctx, &mbedtls_test_rnd_buffer_rand,
-                                                  &info, digest, 0, hash_result,
-                                                  fixed_salt_length, output ) == result );
+    TEST_ASSERT( mbedtls_rsa_rsassa_pss_sign_ext(
+                     &ctx, &mbedtls_test_rnd_buffer_rand, &info,
+                     digest, mbedtls_md_get_size( md_info ), hash_result,
+                     fixed_salt_length, output ) == result );
     if( result == 0 )
     {
         ASSERT_COMPARE( output, ctx.len, result_str->x, result_str->len );
@@ -190,6 +193,7 @@
                               char * salt, data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
     mbedtls_rsa_context ctx;
     mbedtls_mpi N, E;
     ((void) salt);
@@ -208,10 +212,10 @@
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
 
-    if( mbedtls_md_info_from_type( digest ) != NULL )
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str->x, message_str->len, hash_result ) == 0 );
+    if( md_info != NULL )
+        TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len, hash_result ) == 0 );
 
-    TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, digest, 0, hash_result, result_str->x ) == result );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, digest, mbedtls_md_get_size( md_info ), hash_result, result_str->x ) == result );
 
 exit:
     mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
@@ -248,9 +252,12 @@
 
     if( msg_digest_id != MBEDTLS_MD_NONE )
     {
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( msg_digest_id ),
-                     message_str->x, message_str->len, hash_result ) == 0 );
-        hash_len = 0;
+        const mbedtls_md_info_t *md_info =
+            mbedtls_md_info_from_type( msg_digest_id );
+        TEST_ASSERT( mbedtls_md( md_info,
+                                 message_str->x, message_str->len,
+                                 hash_result ) == 0 );
+        hash_len = mbedtls_md_get_size( md_info );
     }
     else
     {
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 5ed485e..8671e37 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -365,116 +365,144 @@
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 check_key_policy:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_NO_PADDING
 
-PSA key policy: ECC SECP256R1, sign
+PSA key policy: ECC SECP256R1, SIGN_HASH -> SIGN_HASH+MESSAGE
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 check_key_policy:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):256:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_ECDSA_ANY
 
-PSA key policy: ECC SECP256R1, sign+verify
+PSA key policy: ECC SECP256R1, VERIFY_HASH -> VERIFY_HASH+MESSAGE
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+check_key_policy:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):256:PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY
+
+PSA key policy: ECC SECP256R1, SIGN+VERIFY_HASH -> {SIGN,VERIFY}_{HASH,MESSAGE}
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 check_key_policy:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY
 
-PSA key policy: ECC SECP256R1, sign message
+PSA key policy: ECC SECP256R1, {SIGN,VERIFY}_{HASH,MESSAGE}
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+check_key_policy:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDSA_ANY
+
+PSA key policy: ECC SECP256R1, SIGN_MESSAGE
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 check_key_policy:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):256:PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_ECDSA(PSA_ALG_SHA_256)
 
-PSA key policy: ECC SECP256R1, sign+verify message
+PSA key policy: ECC SECP256R1, VERIFY_MESSAGE
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+check_key_policy:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):256:PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDSA(PSA_ALG_SHA_256)
+
+PSA key policy: ECC SECP256R1, SIGN+VERIFY_MESSAGE
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 check_key_policy:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):256:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDSA(PSA_ALG_SHA_256)
 
 Key attributes initializers zero properly
 key_attributes_init:
 
-PSA key policy: MAC, sign | verify
-depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
-
-PSA key policy: MAC, wrong algorithm
-depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224):PSA_ERROR_NOT_PERMITTED
-
-PSA key policy: MAC, alg=0 in policy
-depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
-
-PSA key policy: MAC, ANY_HASH in policy is not meaningful
-depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
-
-PSA key policy: MAC, sign but not verify
+PSA key policy: MAC, SIGN_HASH -> SIGN_HASH+MESSAGE
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
 mac_key_policy:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
 
-PSA key policy: MAC, verify but not sign
+PSA key policy: MAC, VERIFY_HASH -> VERIFY_HASH+MESSAGE
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
 mac_key_policy:PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
 
+PSA key policy: MAC, SIGN+VERIFY_HASH -> {SIGN,VERIFY}_{HASH,MESSAGE}
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+
+PSA key policy: MAC, {SIGN,VERIFY}_{HASH,MESSAGE}
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+
+PSA key policy: MAC, SIGN_MESSAGE
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+mac_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+
+PSA key policy: MAC, VERIFY_MESSAGE
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+mac_key_policy:PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+
+PSA key policy: MAC, SIGN+VERIFY_MESSAGE
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+mac_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+
 PSA key policy: MAC, neither sign nor verify
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
 mac_key_policy:0:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
 
+PSA key policy: MAC, wrong algorithm
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224):PSA_ERROR_NOT_PERMITTED
+
+PSA key policy: MAC, alg=0 in policy
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
+
+PSA key policy: MAC, ANY_HASH in policy is not meaningful
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_HMAC(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
+
 PSA key policy: HMAC, sign-verify, tag length > min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 30):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 30):PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, tag length = min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, tag length < min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: CMAC, sign-verify, tag length > min-length policy
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 16):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 16):PSA_SUCCESS
 
 PSA key policy: CMAC, sign-verify, tag length = min-length policy
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 10):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 10):PSA_SUCCESS
 
 PSA key policy: CMAC, sign-verify, tag length < min-length policy
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 8):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_CMAC, 10):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 8):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, default tag length > min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 31):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 31):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, default tag length = min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 32):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 32):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, default tag length < min-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 33):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 33):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, min-length policy, unmatched base alg
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 20):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 20):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, min-length policy, unmatched base alg (different hash base)
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 20):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 20):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, min-length policy, unmatched base alg (different algorithm)
 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CMAC:PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CMAC:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, min-length policy used as algorithm
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_INVALID_ARGUMENT
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_INVALID_ARGUMENT
 
 PSA key policy: HMAC, sign-verify, tag length > exact-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: HMAC, sign-verify, tag length = exact-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS
 
 PSA key policy: HMAC, sign-verify, tag length < exact-length policy
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED
+mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: cipher, encrypt | decrypt
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
@@ -612,85 +640,105 @@
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
 asymmetric_encryption_key_policy:0:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT
 
-PSA key policy: asymmetric signature, sign | verify
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1
+PSA key policy: asymmetric signature, sign | verify hash, PKCS#1v1.5 SHA-256
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
+
+PSA key policy: asymmetric signature, sign | verify hash, PKCS#1v1.5 raw
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
+
+PSA key policy: asymmetric signature, sign | verify hash, ECDSA SHA-256
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDSA(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
+
+PSA key policy: asymmetric signature, sign, key usage extension
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE
+
+PSA key policy: asymmetric signature, verify, key usage extension
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE
+
+PSA key policy: asymmetric signature, sign | verify, key usage extension
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, wrong algorithm family
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, wildcard in policy, wrong algorithm family
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, wildcard in policy, ECDSA SHA-256
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDSA(PSA_ALG_SHA_256):32
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDSA(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, wildcard in policy, PKCS#1v1.5 SHA-256
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, wildcard in policy, PKCS#1v1.5 raw
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, wrong hash algorithm
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:0
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_384):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, alg=0 in policy
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:0
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, sign but not verify
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE
 
 PSA key policy: asymmetric signature, verify but not sign
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
-asymmetric_signature_key_policy:PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature, neither sign nor verify
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
-asymmetric_signature_key_policy:0:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_MD_C
+asymmetric_signature_key_policy:0:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:0
 
 PSA key policy: asymmetric signature for message, sign | verify
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature for message, wrong algorithm family
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature for message, wildcard in policy, wrong algorithm family
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature for message, wildcard in policy, ECDSA SHA-256
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDSA(PSA_ALG_SHA_256):32
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDSA(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature for message, wildcard in policy, PKCS#1v1.5 SHA-256
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):32:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature for message, wrong hash algorithm
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_384):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature for message, alg=0 in policy
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: asymmetric signature for message, sign but not verify
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1
+asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1:PSA_KEY_USAGE_SIGN_MESSAGE
 
 PSA key policy: asymmetric signature for message, verify but not sign
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR
-asymmetric_signature_key_policy:PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1
+asymmetric_signature_key_policy:PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):1:PSA_KEY_USAGE_VERIFY_MESSAGE
 
 PSA key policy: derive via HKDF, permitted
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
@@ -760,11 +808,15 @@
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
 key_policy_alg2:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING
 
-PSA key policy algorithm2: ECDH, ECDSA
-depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
-key_policy_alg2:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDH:PSA_ALG_ECDSA_ANY
+PSA key policy algorithm2: ECDH, ECDSA, HASH usage
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
+key_policy_alg2:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_SHA_256)
 
-PSA key policy algorithm2 with message signature: ECDH, ECDSA
+PSA key policy algorithm2: ECDH, ECDSA, HASH+MESSAGE usage
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
+key_policy_alg2:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_SHA_256)
+
+PSA key policy algorithm2: ECDH, ECDSA, MESSAGE usage
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 key_policy_alg2:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_SHA_256)
 
@@ -805,55 +857,63 @@
 
 Copy key: RSA key pair, same usage flags
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+
+Copy key: RSA key pair, extended usage flags
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
 
 Copy key: RSA key pair, fewer usage flags
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
 
 Copy key: RSA key pair, more usage flags
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
 
 Copy key: RSA key pair, intersect usage flags #0
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:0:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:0:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
 
 Copy key: RSA key pair, intersect usage flags #1
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
 
 Copy key: RSA key pair, wildcard algorithm in source
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
 
 Copy key: RSA key pair, wildcard algorithm in target
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):0
 
 Copy key: RSA key pair, wildcard algorithm in source and target
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_MD_C
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH):0
 
 Copy key: source=ECDSA+ECDH, target=ECDSA+ECDH
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:PSA_WANT_ECC_SECP_R1_256
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH
+
+Copy key: source=ECDSA+ECDH, target=ECDSA+ECDH, extended usage flags
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:PSA_WANT_ECC_SECP_R1_256
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH
 
 Copy key: source=ECDSA+ECDH, target=ECDSA+0
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:PSA_WANT_ECC_SECP_R1_256
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):0
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):0
 
 Copy key: source=ECDSA+ECDH, target=0+ECDH
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:PSA_WANT_ECC_SECP_R1_256
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:0:PSA_ALG_ECDH:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:0:PSA_ALG_ECDH
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:0:PSA_ALG_ECDH:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:0:PSA_ALG_ECDH
 
 Copy key: source=ECDSA(any)+ECDH, target=ECDSA(SHA256)+ECDH
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:PSA_WANT_ECC_SECP_R1_256
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_ALG_ECDH
 
 Copy key: source=ECDH+ECDSA(any), target=ECDH+ECDSA(SHA256)
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:PSA_WANT_ECC_SECP_R1_256
-copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_SHA_256)
+copy_success:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":0:PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_SHA_256):PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_ALG_ECDSA(PSA_ALG_SHA_256)
 
 Copy fail: raw data, no COPY flag
 copy_fail:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_TYPE_RAW_DATA:"404142434445464748494a4b4c4d4e4f":0:0:PSA_KEY_USAGE_EXPORT:0:0:0:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_NOT_PERMITTED
@@ -866,41 +926,45 @@
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
 copy_fail:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:0:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":0:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:0:0:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_INVALID_ARGUMENT
 
+Copy key: source=MAC, target=MAC extended usage flags
+depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
+copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_HMAC(PSA_ALG_SHA_256):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_HMAC(PSA_ALG_SHA_256):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_HMAC(PSA_ALG_SHA_256):0
+
 Copy key: source=MAC min-length, target=MAC length > min-length
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0
+copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0
 
 Copy key: source=MAC min-length, target=MAC length = min-length
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0
+copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0
 
 Copy fail: source=MAC min-length, target=MAC length < min-length
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_fail:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_HMAC:256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 16):0:0:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_INVALID_ARGUMENT
+copy_fail:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_HMAC:256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 16):0:0:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_INVALID_ARGUMENT
 
 Copy key: source=MAC min-length, target=MAC min-length, src > tgt
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0
+copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0
 
 Copy key: source=MAC min-length, target=MAC min-length, src = tgt
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0
+copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0
 
 Copy key: source=MAC min-length, target=MAC min-length, src < tgt
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0
+copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0
 
 Copy fail: source=MAC, target=MAC min-length > length
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_fail:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_HMAC:256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0:0:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_INVALID_ARGUMENT
+copy_fail:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_HMAC:256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 24):0:0:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_INVALID_ARGUMENT
 
 Copy key: source=MAC, target=MAC min-length = length
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0
+copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0
 
 Copy key: source=MAC, target=MAC min-length < length
 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_HMAC
-copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 16):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0
+copy_success:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 16):0:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):0
 
 Copy key: source=AEAD min-length, target=AEAD length > min-length
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
@@ -1395,132 +1459,292 @@
 cipher_setup:PSA_KEY_TYPE_RAW_DATA:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CTR:PSA_ERROR_NOT_SUPPORTED
 
 PSA cipher setup: incompatible key ChaCha20 for CTR
-depends_on:MBEDTLS_ARC4_C:MBEDTLS_CIPHER_MODE_CTR
+depends_on:PSA_WANT_KEY_TYPE_CHACHA20:MBEDTLS_CIPHER_MODE_CTR
 # Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
 cipher_setup:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f10111213141516171819202122232425":PSA_ALG_CTR:PSA_ERROR_NOT_SUPPORTED
 
 PSA cipher: bad order function calls
 cipher_bad_order:
 
-PSA symmetric encrypt: AES-ECB, 0 bytes, good
+PSA cipher encrypt: without initialization
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":"":PSA_SUCCESS
+cipher_encrypt_fail:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"":"":PSA_ERROR_BAD_STATE
 
-PSA symmetric encrypt: AES-ECB, 16 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a":"3ad77bb40d7a3660a89ecaf32466ef97":PSA_SUCCESS
+PSA cipher encrypt: invalid key type
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING
+cipher_encrypt_fail:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_RAW_DATA:"2b7e151628aed2a6abf7158809cf4f3c":"":PSA_ERROR_NOT_SUPPORTED
 
-PSA symmetric encrypt: AES-ECB, 32 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97":"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1":PSA_SUCCESS
+PSA cipher encrypt: incompatible key ChaCha20 for CTR
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_CHACHA20
+# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
+cipher_encrypt_fail:PSA_ALG_CTR:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f10111213141516171819202122232425":"":PSA_ERROR_NOT_SUPPORTED
 
-PSA symmetric encrypt: AES-CBC-nopad, 16 bytes, good
-depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS
+PSA cipher encrypt: bad algorithm (unknown cipher algorithm)
+depends_on:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_fail:PSA_ALG_CATEGORY_CIPHER:PSA_KEY_TYPE_RAW_DATA:"2b7e151628aed2a6abf7158809cf4f3c":"":PSA_ERROR_NOT_SUPPORTED
 
-PSA symmetric encrypt: AES-CBC-PKCS#7, 16 bytes, good
-depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":PSA_SUCCESS
-
-PSA symmetric encrypt: AES-CBC-PKCS#7, 15 bytes, good
-depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"6279b49d7f7a8dd87b685175d4276e24":PSA_SUCCESS
+PSA cipher encrypt: bad algorithm (not a cipher algorithm)
+depends_on:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_MD5
+cipher_encrypt_fail:PSA_ALG_MD5:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric encrypt: AES-ECB, input too short (15 bytes)
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e11739317":"":PSA_ERROR_INVALID_ARGUMENT
+cipher_encrypt_fail:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric encrypt: AES-CBC-nopad, input too short
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
+cipher_encrypt_fail:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
 
-PSA symmetric encrypt: AES-CTR, 16 bytes, good
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":""
 
-PSA symmetric encrypt: AES-CTR, 15 bytes, good
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"8f9408fe80a81d3e813da3c7b0b2bd":PSA_SUCCESS
+PSA symmetric encrypt: AES-ECB, 16 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":"3ad77bb40d7a3660a89ecaf32466ef97"
 
-PSA symmetric encrypt: DES-CBC-nopad, 8 bytes, good
-depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_encrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0e":"2a2a2a2a2a2a2a2a":"eda4011239bc3ac9":"64f917b0152f8f05":PSA_SUCCESS
-
-PSA symmetric encrypt: 2-key 3DES-CBC-nopad, 8 bytes, good
-depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_encrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"2a2a2a2a2a2a2a2a":"eda4011239bc3ac9":"5d0652429c5b0ac7":PSA_SUCCESS
-
-PSA symmetric encrypt: 3-key 3DES-CBC-nopad, 8 bytes, good
-depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_encrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"2a2a2a2a2a2a2a2a":"eda4011239bc3ac9":"817ca7d69b80d86a":PSA_SUCCESS
+PSA symmetric encrypt: AES-ECB, 32 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97":"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1"
 
 PSA symmetric encrypt: 2-key 3DES-ECB, 8 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_encrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"":"c78e2b38139610e3":"5d0652429c5b0ac7":PSA_SUCCESS
+cipher_encrypt_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"c78e2b38139610e3":"5d0652429c5b0ac7"
 
 PSA symmetric encrypt: 3-key 3DES-ECB, 8 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_encrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"":"c78e2b38139610e3":"817ca7d69b80d86a":PSA_SUCCESS
+cipher_encrypt_alg_without_iv:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"c78e2b38139610e3":"817ca7d69b80d86a"
 
-PSA symmetric decrypt: AES-ECB, 0 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":"":PSA_SUCCESS
-
-PSA symmetric decrypt: AES-ECB, 16 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654aa":"63cecc46a382414d5fa7d2b79387437f":PSA_SUCCESS
-
-PSA symmetric decrypt: AES-ECB, 32 bytes, good
-depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1":"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97":PSA_SUCCESS
-
-PSA symmetric decrypt: AES-CBC-nopad, 16 bytes, good
+PSA symmetric encrypt validation: AES-CBC-nopad, 16 bytes, good
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"49e4e66c89a86b67758df89db9ad6955":PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
 
-PSA symmetric decrypt: AES-CBC-PKCS#7, 16 bytes, good
+PSA symmetric encrypt validation: AES-CBC-PKCS#7, 16 bytes, good
 depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":"6bc1bee22e409f96e93d7e117393172a":PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
 
-PSA symmetric decrypt: AES-CBC-PKCS#7, 15 bytes, good
+PSA symmetric encrypt validation: AES-CBC-PKCS#7, 15 bytes, good
 depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6279b49d7f7a8dd87b685175d4276e24":"6bc1bee22e409f96e93d7e11739317":PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317"
+
+PSA symmetric encrypt validation: AES-CTR, 16 bytes, good
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_validation:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
+
+PSA symmetric encrypt validation: AES-CTR, 15 bytes, good
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_validation:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317"
+
+PSA symmetric encrypt validation: DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_encrypt_validation:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0e":"eda4011239bc3ac9"
+
+PSA symmetric encrypt validation: 2-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_encrypt_validation:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"eda4011239bc3ac9"
+
+PSA symmetric encrypt validation: 3-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_encrypt_validation:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"eda4011239bc3ac9"
+
+PSA symmetric encrypt multipart: AES-ECB, 0 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":0:0:0:"":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-ECB, 16 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"3ad77bb40d7a3660a89ecaf32466ef97":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-ECB, 32 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97":32:32:0:"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-CBC-nopad, 16 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-CBC-PKCS#7, 16 bytes, good
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-CBC-PKCS#7, 15 bytes, good
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:0:0:"6279b49d7f7a8dd87b685175d4276e24":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-ECB, input too short (15 bytes)
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e11739317":0:0:0:"":PSA_ERROR_INVALID_ARGUMENT
+
+PSA symmetric encrypt multipart: AES-CBC-nopad, input too short
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":0:0:0:"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
+
+PSA symmetric encrypt multipart: AES-CTR, 16 bytes, good
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-CTR, 15 bytes, good
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0e":"2a2a2a2a2a2a2a2a":"eda4011239bc3ac9":8:8:0:"64f917b0152f8f05":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: 2-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"2a2a2a2a2a2a2a2a":"eda4011239bc3ac9":8:8:0:"5d0652429c5b0ac7":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: 3-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"2a2a2a2a2a2a2a2a":"eda4011239bc3ac9":8:8:0:"817ca7d69b80d86a":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: 2-key 3DES-ECB, 8 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"":"c78e2b38139610e3":8:8:0:"5d0652429c5b0ac7":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: 3-key 3DES-ECB, 8 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"":"c78e2b38139610e3":8:8:0:"817ca7d69b80d86a":PSA_SUCCESS
+
+PSA cipher decrypt: without initialization
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_fail:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"":"":"":PSA_ERROR_BAD_STATE
+
+PSA cipher decrypt: invalid key type
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING
+cipher_decrypt_fail:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_RAW_DATA:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"":PSA_ERROR_NOT_SUPPORTED
+
+PSA cipher decrypt: incompatible key ChaCha20 for CTR
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_CHACHA20
+# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
+cipher_decrypt_fail:PSA_ALG_CTR:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f10111213141516171819202122232425":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"":PSA_ERROR_NOT_SUPPORTED
+
+PSA cipher decrypt: bad algorithm (unknown cipher algorithm)
+cipher_decrypt_fail:PSA_ALG_CATEGORY_CIPHER:PSA_KEY_TYPE_RAW_DATA:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"":PSA_ERROR_NOT_SUPPORTED
+
+PSA cipher decrypt: bad algorithm (not a cipher algorithm)
+depends_on:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_MD5
+cipher_decrypt_fail:PSA_ALG_MD5:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric decrypt: AES-CBC-PKCS#7, input too short (15 bytes)
 depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"49e4e66c89a86b67758df89db9ad6955":PSA_ERROR_INVALID_ARGUMENT
-
-PSA symmetric decrypt: AES-CTR, 16 bytes, good
-depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"dd3b5e5319b7591daab1e1a92687feb2":PSA_SUCCESS
+cipher_decrypt_fail:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric decrypt: AES-ECB, input too short (15 bytes)
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654":"63cecc46a382414d5fa7d2b7938743":PSA_ERROR_INVALID_ARGUMENT
+cipher_decrypt_fail:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric decrypt: AES-CBC-nopad, input too short (5 bytes)
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
+cipher_decrypt_fail:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
+
+PSA symmetric decrypt: AES-ECB, 0 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":""
+
+PSA symmetric decrypt: AES-ECB, 16 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654aa":"63cecc46a382414d5fa7d2b79387437f"
+
+PSA symmetric decrypt: AES-ECB, 32 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1":"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97"
+
+PSA symmetric decrypt: AES-CBC-nopad, 16 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"49e4e66c89a86b67758df89db9ad6955"
+
+PSA symmetric decrypt: AES-CBC-PKCS#7, 16 bytes, good
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":"6bc1bee22e409f96e93d7e117393172a"
+
+PSA symmetric decrypt: AES-CBC-PKCS#7, 15 bytes, good
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6279b49d7f7a8dd87b685175d4276e24":"6bc1bee22e409f96e93d7e11739317"
+
+PSA symmetric decrypt: AES-CTR, 16 bytes, good
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"dd3b5e5319b7591daab1e1a92687feb2"
 
 PSA symmetric decrypt: DES-CBC-nopad, 8 bytes, good
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0e":"2a2a2a2a2a2a2a2a":"64f917b0152f8f05":"eda4011239bc3ac9":PSA_SUCCESS
+cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0e":"2a2a2a2a2a2a2a2a":"64f917b0152f8f05":"eda4011239bc3ac9"
 
 PSA symmetric decrypt: 2-key 3DES-CBC-nopad, 8 bytes, good
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"2a2a2a2a2a2a2a2a":"5d0652429c5b0ac7":"eda4011239bc3ac9":PSA_SUCCESS
+cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"2a2a2a2a2a2a2a2a":"5d0652429c5b0ac7":"eda4011239bc3ac9"
 
 PSA symmetric decrypt: 3-key 3DES-CBC-nopad, 8 bytes, good
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"2a2a2a2a2a2a2a2a":"817ca7d69b80d86a":"eda4011239bc3ac9":PSA_SUCCESS
+cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"2a2a2a2a2a2a2a2a":"817ca7d69b80d86a":"eda4011239bc3ac9"
 
 PSA symmetric decrypt: 2-key 3DES-ECB, 8 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"":"5d0652429c5b0ac7":"c78e2b38139610e3":PSA_SUCCESS
+cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"":"5d0652429c5b0ac7":"c78e2b38139610e3"
 
 PSA symmetric decrypt: 3-key 3DES-ECB, 8 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
-cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"":"817ca7d69b80d86a":"c78e2b38139610e3":PSA_SUCCESS
+cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"":"817ca7d69b80d86a":"c78e2b38139610e3"
+
+PSA symmetric decrypt multipart: AES-ECB, 0 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":0:0:0:"":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-ECB, 16 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654aa":16:16:0:"63cecc46a382414d5fa7d2b79387437f":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-ECB, 32 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef972249a2638c6f1c755a84f9681a9f08c1":32:32:0:"6bc1bee22e409f96e93d7e117393172a3ad77bb40d7a3660a89ecaf32466ef97":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-CBC-nopad, 16 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":16:16:0:"49e4e66c89a86b67758df89db9ad6955":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-CBC-PKCS#7, 16 bytes, good
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":16:0:16:"6bc1bee22e409f96e93d7e117393172a":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-CBC-PKCS#7, 15 bytes, good
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6279b49d7f7a8dd87b685175d4276e24":16:0:0:"6bc1bee22e409f96e93d7e11739317":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-CBC-PKCS#7, input too short (15 bytes)
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:0:"49e4e66c89a86b67758df89db9ad6955":PSA_ERROR_INVALID_ARGUMENT
+
+PSA symmetric decrypt multipart: AES-CTR, 16 bytes, good
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":16:16:0:"dd3b5e5319b7591daab1e1a92687feb2":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-ECB, input too short (15 bytes)
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"396ee84fb75fdbb5c2b13c7fe5a654":0:0:0:"63cecc46a382414d5fa7d2b7938743":PSA_ERROR_INVALID_ARGUMENT
+
+PSA symmetric decrypt multipart: AES-CBC-nopad, input too short (5 bytes)
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":0:0:0:"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
+
+PSA symmetric decrypt multipart: DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0e":"2a2a2a2a2a2a2a2a":"64f917b0152f8f05":8:8:0:"eda4011239bc3ac9":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: 2-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"2a2a2a2a2a2a2a2a":"5d0652429c5b0ac7":8:8:0:"eda4011239bc3ac9":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: 3-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"2a2a2a2a2a2a2a2a":"817ca7d69b80d86a":8:8:0:"eda4011239bc3ac9":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: 2-key 3DES-ECB, 8 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"":"5d0652429c5b0ac7":8:8:0:"c78e2b38139610e3":PSA_SUCCESS
+
+PSA symmetric decrypt multipart: 3-key 3DES-ECB, 8 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"":"817ca7d69b80d86a":8:8:0:"c78e2b38139610e3":PSA_SUCCESS
 
 PSA symmetric encrypt/decrypt: AES-ECB, 16 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
@@ -1544,151 +1768,171 @@
 
 PSA symmetric encryption multipart: AES-ECB, 16+16 bytes
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c"
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-ECB, 13+19 bytes
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":13:0:32:"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c"
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":13:0:32:"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-ECB, 24+12 bytes
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":24:16:16:"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c"
+cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":24:16:16:"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CBC-nopad, 7+9 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":7:0:16:"a076ec9dfbe47d52afc357336f20743b"
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":7:0:16:"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CBC-nopad, 3+13 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":3:0:16:"a076ec9dfbe47d52afc357336f20743b"
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":3:0:16:"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CBC-nopad, 4+12 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":4:0:16:"a076ec9dfbe47d52afc357336f20743b"
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":4:0:16:"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CBC-nopad, 11+5 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:0:16:"a076ec9dfbe47d52afc357336f20743b"
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:0:16:"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CBC-nopad, 16+16 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f"
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CBC-nopad, 12+20 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:0:32:"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f"
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:0:32:"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CBC-nopad, 20+12 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:16:16:"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f"
+cipher_encrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:16:16:"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 11+5 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 16+16 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 12+20 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 20+12 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 12+10 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 0+15 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 15+0 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 0+16 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 16+0 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-ECB, 16+16 bytes
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":16:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef"
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":16:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-ECB, 11+21 bytes
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":11:0:32:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef"
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":11:0:32:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-ECB, 28+4 bytes
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":28:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef"
+cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":28:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CBC-nopad, 7+9 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b":7:0:16:"6bc1bee22e409f96e93d7e117393172a"
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b":7:0:16:"6bc1bee22e409f96e93d7e117393172a":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CBC-nopad, 3+13 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b":3:0:16:"6bc1bee22e409f96e93d7e117393172a"
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b":3:0:16:"6bc1bee22e409f96e93d7e117393172a":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CBC-nopad, 11+5 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b":11:0:16:"6bc1bee22e409f96e93d7e117393172a"
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b":11:0:16:"6bc1bee22e409f96e93d7e117393172a":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CBC-nopad, 16+16 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":16:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef"
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":16:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CBC-nopad, 12+20 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":12:0:32:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef"
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":12:0:32:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CBC-nopad, 20+12 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":20:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef"
+cipher_decrypt_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743b89906f2f9207ac02aa658cb4ef19c61f":20:16:16:"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 11+5 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 16+16 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 12+20 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 20+12 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 12+10 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 0+15 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 15+0 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 0+16 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 16+0 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":PSA_SUCCESS
+
+PSA symmetric encrypt/decrypt multipart: AES-ECB, 16 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_verify_output_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":16
+
+PSA symmetric encrypt/decrypt multipart: AES-CBC-nopad, 16 bytes, good
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
+cipher_verify_output_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":16
+
+PSA symmetric encrypt/decrypt multipart: AES-CBC-PKCS#7, 16 bytes
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_verify_output_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":16
+
+PSA symmetric encrypt/decrypt multipart: AES-CBC-PKCS#7, 15 bytes
+depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
+cipher_verify_output_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317":15
+
+PSA symmetric encrypt/decrypt multipart: AES-CTR
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_verify_output_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":16
 
 PSA symmetric encrypt/decrypt multipart: AES-CBC-nopad, 11+5 bytes
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
@@ -1698,25 +1942,33 @@
 depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES
 cipher_verify_output_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"a076ec9dfbe47d52afc357336f20743b":4
 
-PSA symmetric encrypt: ChaCha20, K=0 N=0
+PSA symmetric encrypt validation: ChaCha20, K=0 N=0
 depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
-cipher_encrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"0000000000000000000000000000000000000000000000000000000000000000":"000000000000000000000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586":PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
 
-PSA symmetric encrypt: ChaCha20, K=rand N=rand
+PSA symmetric encrypt validation: ChaCha20, K=rand N=rand
 depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
-cipher_encrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+
+PSA symmetric encrypt multipart: ChaCha20, K=0 N=0
+depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
+cipher_encrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"0000000000000000000000000000000000000000000000000000000000000000":"000000000000000000000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":64:64:0:"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586":PSA_SUCCESS
+
+PSA symmetric encrypt multipart: ChaCha20, K=rand N=rand
+depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
+cipher_encrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":64:64:0:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
 
 PSA symmetric encryption multipart: ChaCha20, 14+50 bytes
 depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
-cipher_encrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":14:14:50:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4"
+cipher_encrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":14:14:50:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
 
-PSA symmetric decrypt: ChaCha20, K=rand N=rand
+PSA symmetric decrypt multipart: ChaCha20, K=rand N=rand
 depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
-cipher_decrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
+cipher_decrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":64:64:0:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
 
 PSA symmetric decryption multipart: ChaCha20, 14+50 bytes
 depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20
-cipher_decrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":14:14:50:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4"
+cipher_decrypt_multipart:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":"a170d9349d24955aa4501891":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":14:14:50:"9ba7d8de0c6b579fc436e368619e09228070d23246c836d6c6b4c476af6f5eb2b78fbe809d03f7881e6af28cfe3746e8dcf1eb7f762fe7d003141f1539a6cec4":PSA_SUCCESS
 
 PSA AEAD encrypt/decrypt: AES-CCM, 19 bytes #1
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
@@ -2190,6 +2442,14 @@
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 sign_hash_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":127:PSA_ERROR_BUFFER_TOO_SMALL
 
+PSA sign hash: RSA PSS SHA-256, wrong hash length (0 bytes)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+sign_hash_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":127:PSA_ERROR_INVALID_ARGUMENT
+
+PSA sign hash: RSA PSS SHA-256, wrong hash length (129 bytes)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+sign_hash_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":127:PSA_ERROR_INVALID_ARGUMENT
+
 PSA sign hash: deterministic ECDSA SECP256R1 SHA-256, output buffer too small
 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 sign_hash_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":63:PSA_ERROR_BUFFER_TOO_SMALL
@@ -2230,18 +2490,10 @@
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 sign_verify_hash:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
 
-PSA sign/verify hash: RSA PSS SHA-256, 0 bytes
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
-sign_verify_hash:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):""
-
 PSA sign/verify hash: RSA PSS SHA-256, 32 bytes (hash size)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 sign_verify_hash:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
 
-PSA sign/verify hash: RSA PSS SHA-256, 129 bytes
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
-sign_verify_hash:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-
 PSA sign/verify hash: randomized ECDSA SECP256R1 SHA-256
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 sign_verify_hash:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b"
@@ -2298,17 +2550,17 @@
 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"21a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311":PSA_ERROR_INVALID_SIGNATURE
 
-PSA verify hash: RSA PSS SHA-256, good signature, 0 bytes
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
-verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"34c011b625c32d992f4ab8fcfa52b616ea66270b5b75a4fc71af712f9b8806bcdd374ce50eafcbb489562b93347885f93c2de1d404c45cacccefceb112ff6ffdfe4264f91d66320bbbe09304b851b8ad6280bbccc571eebcd49c7db5dfa399a6289e1978407904598751613d9870770cdd8507e3dc7b46851dbf05ae1df2988d"
-
 PSA verify hash: RSA PSS SHA-256, good signature, 32 bytes (hash size)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
 verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"1967ae568cc071dfebeeca76b11d40bd1ec5af241c50b3dcceff21f4536c0693a7179a8d5d163a7625fefd37c161127800edeebc24fa73ca772096827bd3f75e8ccf2c64f07b7171b5c99022a4d73b760f34a385ccff0bd5ed7997d2a29d2847acb0767f93a2a404bc046c97de66d95dc9f7646fdb216b627b2ea0de8afcefb7"
 
-PSA verify hash: RSA PSS SHA-256, good signature, 129 bytes
+PSA verify hash: RSA PSS SHA-256, wrong hash length (0 bytes)
 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
-verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"1491cead330b4ad5b092f8351518141ac11d0888591572669c1e79d6e932c488acd62d44479b0e14cd91a048778bc02398a772ad6bdb4f7764780cf0afe70293d0cac86f2695a1dcb54568bb37d7086f9e86f95a6802d2ee5a4facaa762beff5261bb2816b62cb5af86404974c3f6b67985ac1fbfdf46d6de54f6e29d9274308"
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"34c011b625c32d992f4ab8fcfa52b616ea66270b5b75a4fc71af712f9b8806bcdd374ce50eafcbb489562b93347885f93c2de1d404c45cacccefceb112ff6ffdfe4264f91d66320bbbe09304b851b8ad6280bbccc571eebcd49c7db5dfa399a6289e1978407904598751613d9870770cdd8507e3dc7b46851dbf05ae1df2988d":PSA_ERROR_INVALID_ARGUMENT
+
+PSA verify hash: RSA PSS SHA-256, wrong hash length (129 bytes)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_MD_C
+verify_hash_fail:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"1491cead330b4ad5b092f8351518141ac11d0888591572669c1e79d6e932c488acd62d44479b0e14cd91a048778bc02398a772ad6bdb4f7764780cf0afe70293d0cac86f2695a1dcb54568bb37d7086f9e86f95a6802d2ee5a4facaa762beff5261bb2816b62cb5af86404974c3f6b67985ac1fbfdf46d6de54f6e29d9274308":PSA_ERROR_INVALID_ARGUMENT
 
 PSA verify hash: ECDSA SECP256R1, good
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 33e7c95..9136cb9 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -19,6 +19,11 @@
 /* If this comes up, it's a bug in the test code or in the test data. */
 #define UNUSED 0xdeadbeef
 
+/* Assert that an operation is (not) active.
+ * This serves as a proxy for checking if the operation is aborted. */
+#define ASSERT_OPERATION_IS_ACTIVE(   operation ) TEST_ASSERT( operation.id != 0 )
+#define ASSERT_OPERATION_IS_INACTIVE( operation ) TEST_ASSERT( operation.id == 0 )
+
 /** An invalid export length that will never be set by psa_export_key(). */
 static const size_t INVALID_EXPORT_LENGTH = ~0U;
 
@@ -317,7 +322,8 @@
 
     PSA_ASSERT( psa_get_key_attributes( key, &got_attributes ) );
     TEST_EQUAL( psa_get_key_type( &got_attributes ), type );
-    TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
+    TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ),
+                mbedtls_test_update_key_usage_flags( usage ) );
     TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
     ASSERT_NO_SLOT_NUMBER( &got_attributes );
 
@@ -738,7 +744,9 @@
                        int usage_arg, int alg_arg )
 {
     test_effective_key_attributes( type_arg, type_arg, bits_arg, bits_arg,
-                                   usage_arg, usage_arg, alg_arg, alg_arg );
+                                   usage_arg,
+                                   mbedtls_test_update_key_usage_flags( usage_arg ),
+                                   alg_arg, alg_arg );
     goto exit;
 }
 /* END_CASE */
@@ -779,16 +787,20 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mac_key_policy( int policy_usage,
-                     int policy_alg,
-                     int key_type,
+void mac_key_policy( int policy_usage_arg,
+                     int policy_alg_arg,
+                     int key_type_arg,
                      data_t *key_data,
-                     int exercise_alg,
+                     int exercise_alg_arg,
                      int expected_status_arg )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t policy_alg = policy_alg_arg;
+    psa_algorithm_t exercise_alg = exercise_alg_arg;
+    psa_key_usage_t policy_usage = policy_usage_arg;
     psa_status_t status;
     psa_status_t expected_status = expected_status_arg;
     unsigned char mac[PSA_MAC_MAX_SIZE];
@@ -802,6 +814,9 @@
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
 
+    TEST_EQUAL( psa_get_key_usage_flags( &attributes ),
+                mbedtls_test_update_key_usage_flags( policy_usage ) );
+
     status = psa_mac_sign_setup( &operation, key, exercise_alg );
     if( ( policy_usage & PSA_KEY_USAGE_SIGN_HASH ) == 0 )
         TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
@@ -825,7 +840,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void cipher_key_policy( int policy_usage,
+void cipher_key_policy( int policy_usage_arg,
                         int policy_alg,
                         int key_type,
                         data_t *key_data,
@@ -834,6 +849,7 @@
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_key_usage_t policy_usage = policy_usage_arg;
     psa_status_t status;
 
     PSA_ASSERT( psa_crypto_init( ) );
@@ -845,6 +861,10 @@
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
 
+    /* Check if no key usage flag implication is done */
+    TEST_EQUAL( policy_usage,
+                mbedtls_test_update_key_usage_flags( policy_usage ) );
+
     status = psa_cipher_encrypt_setup( &operation, key, exercise_alg );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
@@ -868,7 +888,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void aead_key_policy( int policy_usage,
+void aead_key_policy( int policy_usage_arg,
                       int policy_alg,
                       int key_type,
                       data_t *key_data,
@@ -879,6 +899,7 @@
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_usage_t policy_usage = policy_usage_arg;
     psa_status_t status;
     psa_status_t expected_status = expected_status_arg;
     unsigned char nonce[16] = {0};
@@ -899,6 +920,10 @@
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
 
+    /* Check if no key usage implication is done */
+    TEST_EQUAL( policy_usage,
+                mbedtls_test_update_key_usage_flags( policy_usage ) );
+
     status = psa_aead_encrypt( key, exercise_alg,
                                nonce, nonce_length,
                                NULL, 0,
@@ -931,7 +956,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void asymmetric_encryption_key_policy( int policy_usage,
+void asymmetric_encryption_key_policy( int policy_usage_arg,
                                        int policy_alg,
                                        int key_type,
                                        data_t *key_data,
@@ -939,6 +964,7 @@
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_usage_t policy_usage = policy_usage_arg;
     psa_status_t status;
     size_t key_bits;
     size_t buffer_length;
@@ -954,6 +980,10 @@
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
 
+    /* Check if no key usage implication is done */
+    TEST_EQUAL( policy_usage,
+                mbedtls_test_update_key_usage_flags( policy_usage ) );
+
     PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
     key_bits = psa_get_key_bits( &attributes );
     buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
@@ -998,15 +1028,18 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void asymmetric_signature_key_policy( int policy_usage,
+void asymmetric_signature_key_policy( int policy_usage_arg,
                                       int policy_alg,
                                       int key_type,
                                       data_t *key_data,
                                       int exercise_alg,
-                                      int payload_length_arg )
+                                      int payload_length_arg,
+                                      int expected_usage_arg )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_usage_t policy_usage = policy_usage_arg;
+    psa_key_usage_t expected_usage = expected_usage_arg;
     psa_status_t status;
     unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
     /* If `payload_length_arg > 0`, `exercise_alg` is supposed to be
@@ -1018,6 +1051,11 @@
     unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = {0};
     size_t signature_length;
 
+    /* Check if all implicit usage flags are deployed
+       in the expected usage flags. */
+    TEST_EQUAL( expected_usage,
+                mbedtls_test_update_key_usage_flags( policy_usage ) );
+
     PSA_ASSERT( psa_crypto_init( ) );
 
     psa_set_key_usage_flags( &attributes, policy_usage );
@@ -1027,11 +1065,13 @@
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
 
+    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), expected_usage );
+
     status = psa_sign_hash( key, exercise_alg,
                             payload, payload_length,
                             signature, sizeof( signature ),
                             &signature_length );
-    if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_SIGN_HASH ) != 0 )
+    if( compatible_alg && ( expected_usage & PSA_KEY_USAGE_SIGN_HASH ) != 0 )
         PSA_ASSERT( status );
     else
         TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
@@ -1040,11 +1080,33 @@
     status = psa_verify_hash( key, exercise_alg,
                               payload, payload_length,
                               signature, sizeof( signature ) );
-    if( compatible_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY_HASH ) != 0 )
+    if( compatible_alg && ( expected_usage & PSA_KEY_USAGE_VERIFY_HASH ) != 0 )
         TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
     else
         TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
+    if( PSA_ALG_IS_HASH_AND_SIGN( exercise_alg ) &&
+        PSA_ALG_IS_HASH( PSA_ALG_SIGN_GET_HASH( exercise_alg ) ) )
+    {
+        status = psa_sign_message( key, exercise_alg,
+                                   payload, payload_length,
+                                   signature, sizeof( signature ),
+                                   &signature_length );
+        if( compatible_alg && ( expected_usage & PSA_KEY_USAGE_SIGN_MESSAGE ) != 0 )
+            PSA_ASSERT( status );
+        else
+            TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
+
+        memset( signature, 0, sizeof( signature ) );
+        status = psa_verify_message( key, exercise_alg,
+                                     payload, payload_length,
+                                     signature, sizeof( signature ) );
+        if( compatible_alg && ( expected_usage & PSA_KEY_USAGE_VERIFY_MESSAGE ) != 0 )
+            TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
+        else
+            TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
+    }
+
 exit:
     psa_destroy_key( key );
     PSA_DONE( );
@@ -1157,6 +1219,8 @@
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
 
+    /* Update the usage flags to obtain implicit usage flags */
+    usage = mbedtls_test_update_key_usage_flags( usage );
     PSA_ASSERT( psa_get_key_attributes( key, &got_attributes ) );
     TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
     TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
@@ -1540,15 +1604,28 @@
 
     /* Call setup twice in a row. */
     PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_hash_setup( &operation, alg ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_hash_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Call update without calling setup beforehand. */
     TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
                 PSA_ERROR_BAD_STATE );
     PSA_ASSERT( psa_hash_abort( &operation ) );
 
+    /* Check that update calls abort on error. */
+    PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    operation.id = UINT_MAX;
+    ASSERT_OPERATION_IS_ACTIVE( operation );
+    TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
+                PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
+    PSA_ASSERT( psa_hash_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
+
     /* Call update after finish. */
     PSA_ASSERT( psa_hash_setup( &operation, alg ) );
     PSA_ASSERT( psa_hash_finish( &operation,
@@ -1574,11 +1651,14 @@
 
     /* Call verify twice in a row. */
     PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     PSA_ASSERT( psa_hash_verify( &operation,
                                  valid_hash, sizeof( valid_hash ) ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     TEST_EQUAL( psa_hash_verify( &operation,
                                  valid_hash, sizeof( valid_hash ) ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_hash_abort( &operation ) );
 
     /* Call finish without calling setup beforehand. */
@@ -1627,8 +1707,12 @@
 
     /* psa_hash_verify with a smaller hash than expected */
     PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
                 PSA_ERROR_INVALID_SIGNATURE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
+    PSA_ASSERT( psa_hash_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* psa_hash_verify with a non-matching hash */
     PSA_ASSERT( psa_hash_setup( &operation, alg ) );
@@ -1871,9 +1955,12 @@
 
     /* Call setup twice in a row. */
     PSA_ASSERT( psa_mac_sign_setup( &operation, key, alg ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_mac_sign_setup( &operation, key, alg ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_mac_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Call update after sign finish. */
     PSA_ASSERT( psa_mac_sign_setup( &operation, key, alg ) );
@@ -1919,19 +2006,25 @@
     /* Setup sign but try verify. */
     PSA_ASSERT( psa_mac_sign_setup( &operation, key, alg ) );
     PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_mac_verify_finish( &operation,
                                        verify_mac, sizeof( verify_mac ) ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_mac_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Setup verify but try sign. */
     PSA_ASSERT( psa_mac_verify_setup( &operation, key, alg ) );
     PSA_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_mac_sign_finish( &operation,
                                      sign_mac, sizeof( sign_mac ),
                                      &sign_mac_length ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_mac_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     PSA_ASSERT( psa_destroy_key( key ) );
 
@@ -2233,15 +2326,21 @@
 
     /* Call encrypt setup twice in a row. */
     PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_cipher_encrypt_setup( &operation, key, alg ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_cipher_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Call decrypt setup twice in a row. */
     PSA_ASSERT( psa_cipher_decrypt_setup( &operation, key, alg ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_cipher_decrypt_setup( &operation, key, alg ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_cipher_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Generate an IV without calling setup beforehand. */
     TEST_EQUAL( psa_cipher_generate_iv( &operation,
@@ -2255,11 +2354,14 @@
     PSA_ASSERT( psa_cipher_generate_iv( &operation,
                                         buffer, sizeof( buffer ),
                                         &length ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_cipher_generate_iv( &operation,
                                         buffer, sizeof( buffer ),
                                         &length ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_cipher_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Generate an IV after it's already set. */
     PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
@@ -2281,10 +2383,13 @@
     PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
     PSA_ASSERT( psa_cipher_set_iv( &operation,
                                    iv, sizeof( iv ) ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_cipher_set_iv( &operation,
                                    iv, sizeof( iv ) ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_cipher_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Set an IV after it's already generated. */
     PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
@@ -2305,12 +2410,16 @@
     PSA_ASSERT( psa_cipher_abort( &operation ) );
 
     /* Call update without an IV where an IV is required. */
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_cipher_update( &operation,
                                    text, sizeof( text ),
                                    buffer, sizeof( buffer ),
                                    &length ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_cipher_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Call update after finish. */
     PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
@@ -2335,10 +2444,13 @@
     PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
     /* Not calling update means we are encrypting an empty buffer, which is OK
      * for cipher modes with padding. */
+    ASSERT_OPERATION_IS_ACTIVE( operation );
     TEST_EQUAL( psa_cipher_finish( &operation,
                                    buffer, sizeof( buffer ), &length ),
                 PSA_ERROR_BAD_STATE );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
     PSA_ASSERT( psa_cipher_abort( &operation ) );
+    ASSERT_OPERATION_IS_INACTIVE( operation );
 
     /* Call finish twice in a row. */
     PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
@@ -2360,10 +2472,11 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void cipher_encrypt( int alg_arg, int key_type_arg,
-                     data_t *key_data, data_t *iv,
-                     data_t *input, data_t *expected_output,
-                     int expected_status_arg )
+void cipher_encrypt_fail( int alg_arg,
+                          int key_type_arg,
+                          data_t *key_data,
+                          data_t *input,
+                          int expected_status_arg )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_status_t status;
@@ -2372,8 +2485,97 @@
     psa_status_t expected_status = expected_status_arg;
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
+    size_t output_length = 0;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    if ( PSA_ERROR_BAD_STATE != expected_status )
+    {
+        PSA_ASSERT( psa_crypto_init( ) );
+
+        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
+        psa_set_key_algorithm( &attributes, alg );
+        psa_set_key_type( &attributes, key_type );
+
+        output_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg,
+                                                             input->len );
+        ASSERT_ALLOC( output, output_buffer_size );
+
+        PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                    &key ) );
+    }
+
+    status = psa_cipher_encrypt( key, alg, input->x, input->len, output,
+                                 output_buffer_size, &output_length );
+
+    TEST_EQUAL( status, expected_status );
+
+exit:
+    mbedtls_free( output );
+    psa_destroy_key( key );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_encrypt_alg_without_iv( int alg_arg,
+                                    int key_type_arg,
+                                    data_t *key_data,
+                                    data_t *input,
+                                    data_t *expected_output )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char *output = NULL;
+    size_t output_buffer_size = 0;
+    size_t output_length = 0;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    output_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len );
+    ASSERT_ALLOC( output, output_buffer_size );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_cipher_encrypt( key, alg, input->x, input->len, output,
+                                    output_buffer_size, &output_length ) );
+    TEST_ASSERT( output_length <=
+                 PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ) );
+    TEST_ASSERT( output_length <=
+                 PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
+
+    ASSERT_COMPARE( expected_output->x, expected_output->len,
+                    output, output_length );
+exit:
+    mbedtls_free( output );
+    psa_destroy_key( key );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_encrypt_validation( int alg_arg,
+                                int key_type_arg,
+                                data_t *key_data,
+                                data_t *input )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    size_t iv_size = PSA_CIPHER_IV_LENGTH ( key_type, alg );
+    unsigned char *output1 = NULL;
+    size_t output1_buffer_size = 0;
+    size_t output1_length = 0;
+    unsigned char *output2 = NULL;
+    size_t output2_buffer_size = 0;
+    size_t output2_length = 0;
     size_t function_output_length = 0;
-    size_t total_output_length = 0;
     psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
@@ -2383,53 +2585,55 @@
     psa_set_key_algorithm( &attributes, alg );
     psa_set_key_type( &attributes, key_type );
 
+    output1_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len );
+    output2_buffer_size = PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) +
+                          PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg );
+    ASSERT_ALLOC( output1, output1_buffer_size );
+    ASSERT_ALLOC( output2, output2_buffer_size );
+
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
 
-    PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
-
-    if( iv->len > 0 )
-    {
-        PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
-    }
-
-    output_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len );
-    TEST_ASSERT( output_buffer_size <=
+    /* The one-shot cipher encryption uses generated iv so validating
+       the output is not possible. Validating with multipart encryption. */
+    PSA_ASSERT( psa_cipher_encrypt( key, alg, input->x, input->len, output1,
+                                    output1_buffer_size, &output1_length ) );
+    TEST_ASSERT( output1_length <=
+                 PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ) );
+    TEST_ASSERT( output1_length <=
                  PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
-    ASSERT_ALLOC( output, output_buffer_size );
+
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
+    PSA_ASSERT( psa_cipher_set_iv( &operation, output1, iv_size ) );
 
     PSA_ASSERT( psa_cipher_update( &operation,
                                    input->x, input->len,
-                                   output, output_buffer_size,
+                                   output2, output2_buffer_size,
                                    &function_output_length ) );
     TEST_ASSERT( function_output_length <=
                  PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) );
     TEST_ASSERT( function_output_length <=
                  PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
-    total_output_length += function_output_length;
+    output2_length += function_output_length;
 
-    status = psa_cipher_finish( &operation,
-                                ( output_buffer_size == 0 ? NULL :
-                                  output + total_output_length ),
-                                output_buffer_size - total_output_length,
-                                &function_output_length );
+    PSA_ASSERT( psa_cipher_finish( &operation,
+                                   output2 + output2_length,
+                                   output2_buffer_size - output2_length,
+                                   &function_output_length ) );
     TEST_ASSERT( function_output_length <=
                  PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
     TEST_ASSERT( function_output_length <=
                  PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
-    total_output_length += function_output_length;
+    output2_length += function_output_length;
 
-    TEST_EQUAL( status, expected_status );
-    if( expected_status == PSA_SUCCESS )
-    {
-        PSA_ASSERT( psa_cipher_abort( &operation ) );
-        ASSERT_COMPARE( expected_output->x, expected_output->len,
-                        output, total_output_length );
-    }
+    PSA_ASSERT( psa_cipher_abort( &operation ) );
+    ASSERT_COMPARE( output1 + iv_size, output1_length - iv_size,
+                    output2, output2_length );
 
 exit:
     psa_cipher_abort( &operation );
-    mbedtls_free( output );
+    mbedtls_free( output1 );
+    mbedtls_free( output2 );
     psa_destroy_key( key );
     PSA_DONE( );
 }
@@ -2441,11 +2645,14 @@
                                data_t *input,
                                int first_part_size_arg,
                                int output1_length_arg, int output2_length_arg,
-                               data_t *expected_output )
+                               data_t *expected_output,
+                               int expected_status_arg )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
+    psa_status_t status;
+    psa_status_t expected_status = expected_status_arg;
     size_t first_part_size = first_part_size_arg;
     size_t output1_length = output1_length_arg;
     size_t output2_length = output2_length_arg;
@@ -2472,9 +2679,8 @@
         PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
     }
 
-    output_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len );
-    TEST_ASSERT( output_buffer_size <=
-                 PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
+    output_buffer_size = PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) +
+                         PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg );
     ASSERT_ALLOC( output, output_buffer_size );
 
     TEST_ASSERT( first_part_size <= input->len );
@@ -2488,36 +2694,44 @@
                  PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size) );
     total_output_length += function_output_length;
 
-    PSA_ASSERT( psa_cipher_update( &operation,
-                                   input->x + first_part_size,
-                                   input->len - first_part_size,
-                                   ( output_buffer_size == 0 ? NULL :
-                                     output + total_output_length ),
-                                   output_buffer_size - total_output_length,
-                                   &function_output_length ) );
-    TEST_ASSERT( function_output_length == output2_length );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
-                                                alg,
-                                                input->len - first_part_size ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
-    total_output_length += function_output_length;
+    if( first_part_size < input->len )
+    {
+        PSA_ASSERT( psa_cipher_update( &operation,
+                                       input->x + first_part_size,
+                                       input->len - first_part_size,
+                                       ( output_buffer_size == 0 ? NULL :
+                                         output + total_output_length ),
+                                       output_buffer_size - total_output_length,
+                                       &function_output_length ) );
+        TEST_ASSERT( function_output_length == output2_length );
+        TEST_ASSERT( function_output_length <=
+                     PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
+                                                    alg,
+                                                    input->len - first_part_size ) );
+        TEST_ASSERT( function_output_length <=
+                     PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
+        total_output_length += function_output_length;
+    }
 
-    PSA_ASSERT( psa_cipher_finish( &operation,
-                                   ( output_buffer_size == 0 ? NULL :
-                                     output + total_output_length ),
-                                   output_buffer_size - total_output_length,
-                                   &function_output_length ) );
+    status = psa_cipher_finish( &operation,
+                                ( output_buffer_size == 0 ? NULL :
+                                  output + total_output_length ),
+                                output_buffer_size - total_output_length,
+                                &function_output_length );
     TEST_ASSERT( function_output_length <=
                  PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
     TEST_ASSERT( function_output_length <=
                  PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
     total_output_length += function_output_length;
-    PSA_ASSERT( psa_cipher_abort( &operation ) );
+    TEST_EQUAL( status, expected_status );
 
-    ASSERT_COMPARE( expected_output->x, expected_output->len,
-                    output, total_output_length );
+    if( expected_status == PSA_SUCCESS )
+    {
+        PSA_ASSERT( psa_cipher_abort( &operation ) );
+
+        ASSERT_COMPARE( expected_output->x, expected_output->len,
+                        output, total_output_length );
+    }
 
 exit:
     psa_cipher_abort( &operation );
@@ -2533,11 +2747,14 @@
                                data_t *input,
                                int first_part_size_arg,
                                int output1_length_arg, int output2_length_arg,
-                               data_t *expected_output )
+                               data_t *expected_output,
+                               int expected_status_arg )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
+    psa_status_t status;
+    psa_status_t expected_status = expected_status_arg;
     size_t first_part_size = first_part_size_arg;
     size_t output1_length = output1_length_arg;
     size_t output2_length = output2_length_arg;
@@ -2564,9 +2781,8 @@
         PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
     }
 
-    output_buffer_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input->len );
-    TEST_ASSERT( output_buffer_size <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( input->len ) );
+    output_buffer_size = PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) +
+                         PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg );
     ASSERT_ALLOC( output, output_buffer_size );
 
     TEST_ASSERT( first_part_size <= input->len );
@@ -2581,94 +2797,25 @@
                  PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) );
     total_output_length += function_output_length;
 
-    PSA_ASSERT( psa_cipher_update( &operation,
-                                   input->x + first_part_size,
-                                   input->len - first_part_size,
-                                   ( output_buffer_size == 0 ? NULL :
-                                     output + total_output_length ),
-                                   output_buffer_size - total_output_length,
-                                   &function_output_length ) );
-    TEST_ASSERT( function_output_length == output2_length );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
-                                                alg,
-                                                input->len - first_part_size ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
-    total_output_length += function_output_length;
-
-    PSA_ASSERT( psa_cipher_finish( &operation,
-                                   ( output_buffer_size == 0 ? NULL :
-                                     output + total_output_length ),
-                                   output_buffer_size - total_output_length,
-                                   &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
-    total_output_length += function_output_length;
-    PSA_ASSERT( psa_cipher_abort( &operation ) );
-
-    ASSERT_COMPARE( expected_output->x, expected_output->len,
-                    output, total_output_length );
-
-exit:
-    psa_cipher_abort( &operation );
-    mbedtls_free( output );
-    psa_destroy_key( key );
-    PSA_DONE( );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void cipher_decrypt( int alg_arg, int key_type_arg,
-                     data_t *key_data, data_t *iv,
-                     data_t *input, data_t *expected_output,
-                     int expected_status_arg )
-{
-    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
-    psa_status_t status;
-    psa_key_type_t key_type = key_type_arg;
-    psa_algorithm_t alg = alg_arg;
-    psa_status_t expected_status = expected_status_arg;
-    unsigned char *output = NULL;
-    size_t output_buffer_size = 0;
-    size_t function_output_length = 0;
-    size_t total_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
-    PSA_ASSERT( psa_crypto_init( ) );
-
-    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
-    psa_set_key_algorithm( &attributes, alg );
-    psa_set_key_type( &attributes, key_type );
-
-    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
-                                &key ) );
-
-    PSA_ASSERT( psa_cipher_decrypt_setup( &operation, key, alg ) );
-
-    if( iv->len > 0 )
+    if( first_part_size < input->len )
     {
-        PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
+        PSA_ASSERT( psa_cipher_update( &operation,
+                                       input->x + first_part_size,
+                                       input->len - first_part_size,
+                                       ( output_buffer_size == 0 ? NULL :
+                                         output + total_output_length ),
+                                       output_buffer_size - total_output_length,
+                                       &function_output_length ) );
+        TEST_ASSERT( function_output_length == output2_length );
+        TEST_ASSERT( function_output_length <=
+                     PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type,
+                                                    alg,
+                                                    input->len - first_part_size ) );
+        TEST_ASSERT( function_output_length <=
+                     PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
+        total_output_length += function_output_length;
     }
 
-    output_buffer_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input->len );
-    TEST_ASSERT( output_buffer_size <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( input->len ) );
-    ASSERT_ALLOC( output, output_buffer_size );
-
-    PSA_ASSERT( psa_cipher_update( &operation,
-                                   input->x, input->len,
-                                   output, output_buffer_size,
-                                   &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
-    total_output_length += function_output_length;
-
     status = psa_cipher_finish( &operation,
                                 ( output_buffer_size == 0 ? NULL :
                                   output + total_output_length ),
@@ -2684,6 +2831,7 @@
     if( expected_status == PSA_SUCCESS )
     {
         PSA_ASSERT( psa_cipher_abort( &operation ) );
+
         ASSERT_COMPARE( expected_output->x, expected_output->len,
                         output, total_output_length );
     }
@@ -2697,25 +2845,132 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void cipher_verify_output( int alg_arg, int key_type_arg,
+void cipher_decrypt_fail( int alg_arg,
+                          int key_type_arg,
+                          data_t *key_data,
+                          data_t *iv,
+                          data_t *input_arg,
+                          int expected_status_arg )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_status_t status;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    unsigned char *input = NULL;
+    size_t input_buffer_size = 0;
+    unsigned char *output = NULL;
+    size_t output_buffer_size = 0;
+    size_t output_length = 0;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    if ( PSA_ERROR_BAD_STATE != expected_status )
+    {
+        PSA_ASSERT( psa_crypto_init( ) );
+
+        psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
+        psa_set_key_algorithm( &attributes, alg );
+        psa_set_key_type( &attributes, key_type );
+
+        PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                    &key ) );
+    }
+
+    /* Allocate input buffer and copy the iv and the plaintext */
+    input_buffer_size = ( (size_t) input_arg->len + (size_t) iv->len );
+    if ( input_buffer_size > 0 )
+    {
+        ASSERT_ALLOC( input, input_buffer_size );
+        memcpy( input, iv->x, iv->len );
+        memcpy( input + iv->len, input_arg->x, input_arg->len );
+    }
+
+    output_buffer_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input_buffer_size );
+    ASSERT_ALLOC( output, output_buffer_size );
+
+    status = psa_cipher_decrypt( key, alg, input, input_buffer_size, output,
+                                 output_buffer_size, &output_length );
+    TEST_EQUAL( status, expected_status );
+
+exit:
+    mbedtls_free( input );
+    mbedtls_free( output );
+    psa_destroy_key( key );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_decrypt( int alg_arg,
+                     int key_type_arg,
+                     data_t *key_data,
+                     data_t *iv,
+                     data_t *input_arg,
+                     data_t *expected_output )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    unsigned char *input = NULL;
+    size_t input_buffer_size = 0;
+    unsigned char *output = NULL;
+    size_t output_buffer_size = 0;
+    size_t output_length = 0;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    /* Allocate input buffer and copy the iv and the plaintext */
+    input_buffer_size = ( (size_t) input_arg->len + (size_t) iv->len );
+    if ( input_buffer_size > 0 )
+    {
+        ASSERT_ALLOC( input, input_buffer_size );
+        memcpy( input, iv->x, iv->len );
+        memcpy( input + iv->len, input_arg->x, input_arg->len );
+    }
+
+    output_buffer_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input_buffer_size );
+    ASSERT_ALLOC( output, output_buffer_size );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_cipher_decrypt( key, alg, input, input_buffer_size, output,
+                                    output_buffer_size, &output_length ) );
+    TEST_ASSERT( output_length <=
+                 PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input_buffer_size ) );
+    TEST_ASSERT( output_length <=
+                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( input_buffer_size ) );
+
+    ASSERT_COMPARE( expected_output->x, expected_output->len,
+                    output, output_length );
+exit:
+    mbedtls_free( input );
+    mbedtls_free( output );
+    psa_destroy_key( key );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_verify_output( int alg_arg,
+                           int key_type_arg,
                            data_t *key_data,
                            data_t *input )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
-    unsigned char iv[16] = {0};
-    size_t iv_size = 16;
-    size_t iv_length = 0;
     unsigned char *output1 = NULL;
     size_t output1_size = 0;
     size_t output1_length = 0;
     unsigned char *output2 = NULL;
     size_t output2_size = 0;
     size_t output2_length = 0;
-    size_t function_output_length = 0;
-    psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT;
-    psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
     PSA_ASSERT( psa_crypto_init( ) );
@@ -2726,82 +2981,31 @@
 
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
-
-    PSA_ASSERT( psa_cipher_encrypt_setup( &operation1, key, alg ) );
-    PSA_ASSERT( psa_cipher_decrypt_setup( &operation2, key, alg ) );
-
-    if( alg != PSA_ALG_ECB_NO_PADDING )
-    {
-        PSA_ASSERT( psa_cipher_generate_iv( &operation1,
-                                            iv, iv_size,
-                                            &iv_length ) );
-    }
     output1_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len );
-    TEST_ASSERT( output1_size <=
-                 PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
     ASSERT_ALLOC( output1, output1_size );
 
-    PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
-                                   output1, output1_size,
-                                   &output1_length ) );
+    PSA_ASSERT( psa_cipher_encrypt( key, alg, input->x, input->len,
+                                    output1, output1_size,
+                                    &output1_length ) );
     TEST_ASSERT( output1_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) );
+                 PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ) );
     TEST_ASSERT( output1_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) );
-
-    PSA_ASSERT( psa_cipher_finish( &operation1,
-                                   output1 + output1_length,
-                                   output1_size - output1_length,
-                                   &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
-
-    output1_length += function_output_length;
-
-    PSA_ASSERT( psa_cipher_abort( &operation1 ) );
+                 PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) );
 
     output2_size = output1_length;
-    TEST_ASSERT( output2_size <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, output1_length ) );
-    TEST_ASSERT( output2_size <=
-                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( output1_length ) );
     ASSERT_ALLOC( output2, output2_size );
 
-    if( iv_length > 0 )
-    {
-        PSA_ASSERT( psa_cipher_set_iv( &operation2,
-                                       iv, iv_length ) );
-    }
-
-    PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
-                                   output2, output2_size,
-                                   &output2_length ) );
+    PSA_ASSERT( psa_cipher_decrypt( key, alg, output1, output1_length,
+                                    output2, output2_size,
+                                    &output2_length ) );
     TEST_ASSERT( output2_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, output1_length ) );
+                 PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, output1_length ) );
     TEST_ASSERT( output2_length <=
-                 PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( output1_length ) );
-
-    function_output_length = 0;
-    PSA_ASSERT( psa_cipher_finish( &operation2,
-                                   output2 + output2_length,
-                                   output2_size - output2_length,
-                                   &function_output_length ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) );
-    TEST_ASSERT( function_output_length <=
-                 PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE );
-
-    output2_length += function_output_length;
-
-    PSA_ASSERT( psa_cipher_abort( &operation2 ) );
+                 PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( output1_length ) );
 
     ASSERT_COMPARE( input->x, input->len, output2, output2_length );
 
 exit:
-    psa_cipher_abort( &operation1 );
-    psa_cipher_abort( &operation2 );
     mbedtls_free( output1 );
     mbedtls_free( output2 );
     psa_destroy_key( key );
@@ -5133,7 +5337,8 @@
                 PSA_KEY_LIFETIME_PERSISTENT );
     TEST_EQUAL( psa_get_key_type( &attributes ), type );
     TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
-    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
+    TEST_EQUAL( psa_get_key_usage_flags( &attributes ),
+                mbedtls_test_update_key_usage_flags( usage_flags ) );
     TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
 
     /* Export the key again if permitted by the key policy. */
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
index dbc5b1f..ead7a69 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
@@ -117,29 +117,45 @@
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:PSA_WANT_ECC_SECP_R1_256
 export_key:PSA_ERROR_GENERIC_ERROR:"":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"":PSA_ERROR_GENERIC_ERROR
 
-PSA symmetric encrypt: AES-CTR, 16 bytes, good
+PSA symmetric encrypt validation: AES-CTR, 16 bytes, good
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
 
-PSA symmetric encrypt: AES-CTR, 15 bytes, good
+PSA symmetric encrypt validation: AES-CTR, 15 bytes, good
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_SUCCESS:PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317"
 
-PSA symmetric encrypt: AES-CTR, 16 bytes, fallback
+PSA symmetric encrypt validation: AES-CTR, 16 bytes, fallback
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_CIPHER
-cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
 
-PSA symmetric encrypt: AES-CTR, 15 bytes, fallback
+PSA symmetric encrypt validation: AES-CTR, 15 bytes, fallback
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_CIPHER
-cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS
+cipher_encrypt_validation:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317"
 
-PSA symmetric encrypt: AES-CTR, 16 bytes, fake
+PSA symmetric encrypt multipart: AES-CTR, 16 bytes, good
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
 
-PSA symmetric encrypt: AES-CTR, 15 bytes, fake
+PSA symmetric encrypt multipart: AES-CTR, 15 bytes, good
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_SUCCESS:PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-CTR, 16 bytes, fallback
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_CIPHER
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-CTR, 15 bytes, fallback
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_CIPHER
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-CTR, 16 bytes, fake
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:8:0:"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
+
+PSA symmetric encrypt multipart: AES-CTR, 15 bytes, fake
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:8:0:"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decrypt: AES-CTR, 16 bytes, good
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
@@ -153,77 +169,89 @@
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
 cipher_decrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
 
+PSA symmetric decrypt multipart: AES-CTR, 16 bytes, good
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":16:16:0:"dd3b5e5319b7591daab1e1a92687feb2":0:PSA_SUCCESS:PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-CTR, 16 bytes, fallback
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_CIPHER
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":16:16:0:"dd3b5e5319b7591daab1e1a92687feb2":0:PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS
+
+PSA symmetric decrypt multipart: AES-CTR, 16 bytes, fake
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":16:8:0:"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
+
 PSA symmetric encryption multipart: AES-CTR, 11+5 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 16+16 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 12+20 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 20+12 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 12+10 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 0+15 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 15+0 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 0+16 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric encryption multipart: AES-CTR, 16+0 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 11+5 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 16+16 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 12+20 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 20+12 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 12+10 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 0+15 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 15+0 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 0+16 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
 
 PSA symmetric decryption multipart: AES-CTR, 16+0 bytes
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
-cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32"
+cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
 
 Cipher driver: negative testing on all entry points
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index 3a9eff9..6d78ad5 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -422,19 +422,111 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void cipher_encrypt( int alg_arg, int key_type_arg,
-                     data_t *key_data, data_t *iv,
-                     data_t *input, data_t *expected_output,
-                     int mock_output_arg,
-                     int force_status_arg,
-                     int expected_status_arg )
+void cipher_encrypt_validation( int alg_arg,
+                                int key_type_arg,
+                                data_t *key_data,
+                                data_t *input )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
-    psa_status_t status;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
+    size_t iv_size = PSA_CIPHER_IV_LENGTH ( key_type, alg );
+    unsigned char *output1 = NULL;
+    size_t output1_buffer_size = 0;
+    size_t output1_length = 0;
+    unsigned char *output2 = NULL;
+    size_t output2_buffer_size = 0;
+    size_t output2_length = 0;
+    size_t function_output_length = 0;
+    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    output1_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len );
+    output2_buffer_size = PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) +
+                          PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg );
+    ASSERT_ALLOC( output1, output1_buffer_size );
+    ASSERT_ALLOC( output2, output2_buffer_size );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+
+    PSA_ASSERT( psa_cipher_encrypt( key, alg, input->x, input->len, output1,
+                                    output1_buffer_size, &output1_length ) );
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
+    mbedtls_test_driver_cipher_hooks.hits = 0;
+
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
+    mbedtls_test_driver_cipher_hooks.hits = 0;
+
+    PSA_ASSERT( psa_cipher_set_iv( &operation, output1, iv_size ) );
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
+    mbedtls_test_driver_cipher_hooks.hits = 0;
+
+    PSA_ASSERT( psa_cipher_update( &operation,
+                                   input->x, input->len,
+                                   output2, output2_buffer_size,
+                                   &function_output_length ) );
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
+    mbedtls_test_driver_cipher_hooks.hits = 0;
+
+    output2_length += function_output_length;
+    PSA_ASSERT( psa_cipher_finish( &operation,
+                                   output2 + output2_length,
+                                   output2_buffer_size - output2_length,
+                                   &function_output_length ) );
+    /* Finish will have called abort as well, so expecting two hits here */
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 2 );
+    mbedtls_test_driver_cipher_hooks.hits = 0;
+
+    output2_length += function_output_length;
+
+    PSA_ASSERT( psa_cipher_abort( &operation ) );
+    // driver function should've been called as part of the finish() core routine
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 0 );
+    ASSERT_COMPARE( output1 + iv_size, output1_length - iv_size,
+                    output2, output2_length );
+
+exit:
+    psa_cipher_abort( &operation );
+    mbedtls_free( output1 );
+    mbedtls_free( output2 );
+    psa_destroy_key( key );
+    PSA_DONE( );
+    mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void cipher_encrypt_multipart( int alg_arg,
+                               int key_type_arg,
+                               data_t *key_data,
+                               data_t *iv,
+                               data_t *input,
+                               int first_part_size_arg,
+                               int output1_length_arg,
+                               int output2_length_arg,
+                               data_t *expected_output,
+                               int mock_output_arg,
+                               int force_status_arg,
+                               int expected_status_arg )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t status;
     psa_status_t expected_status = expected_status_arg;
     psa_status_t force_status = force_status_arg;
+    size_t first_part_size = first_part_size_arg;
+    size_t output1_length = output1_length_arg;
+    size_t output2_length = output2_length_arg;
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
@@ -444,6 +536,20 @@
     mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
     mbedtls_test_driver_cipher_hooks.forced_status = force_status;
 
+    /* Test operation initialization */
+    mbedtls_psa_cipher_operation_t mbedtls_operation =
+            MBEDTLS_PSA_CIPHER_OPERATION_INIT;
+
+    mbedtls_transparent_test_driver_cipher_operation_t tranparent_operation =
+            MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT;
+
+    mbedtls_opaque_test_driver_cipher_operation_t opaque_operation =
+            MBEDTLS_OPAQUE_TEST_DRIVER_CIPHER_OPERATION_INIT;
+
+    operation.ctx.mbedtls_ctx = mbedtls_operation;
+    operation.ctx.transparent_test_driver_ctx = tranparent_operation;
+    operation.ctx.opaque_test_driver_ctx = opaque_operation;
+
     PSA_ASSERT( psa_crypto_init( ) );
 
     psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
@@ -471,36 +577,52 @@
         mbedtls_test_driver_cipher_hooks.forced_output_length = expected_output->len;
     }
 
-    PSA_ASSERT( psa_cipher_update( &operation,
-                                   input->x, input->len,
+    TEST_ASSERT( first_part_size <= input->len );
+    PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
                                    output, output_buffer_size,
                                    &function_output_length ) );
     TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
     mbedtls_test_driver_cipher_hooks.hits = 0;
 
+    TEST_ASSERT( function_output_length == output1_length );
+    total_output_length += function_output_length;
+
+    if( first_part_size < input->len )
+    {
+        PSA_ASSERT( psa_cipher_update( &operation,
+                                       input->x + first_part_size,
+                                       input->len - first_part_size,
+                                       output + total_output_length,
+                                       output_buffer_size - total_output_length,
+                                       &function_output_length ) );
+        TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
+        mbedtls_test_driver_cipher_hooks.hits = 0;
+
+        TEST_ASSERT( function_output_length == output2_length );
+        total_output_length += function_output_length;
+    }
+
     if( mock_output_arg )
     {
         mbedtls_test_driver_cipher_hooks.forced_output = NULL;
         mbedtls_test_driver_cipher_hooks.forced_output_length = 0;
     }
 
-    total_output_length += function_output_length;
-    status = psa_cipher_finish( &operation,
-                                output + total_output_length,
-                                output_buffer_size - total_output_length,
-                                &function_output_length );
+    status =  psa_cipher_finish( &operation,
+                                 output + total_output_length,
+                                 output_buffer_size - total_output_length,
+                                 &function_output_length );
     /* Finish will have called abort as well, so expecting two hits here */
     TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 2 : 0 ) );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
-
+    mbedtls_test_driver_cipher_hooks.hits = 0 ;
     total_output_length += function_output_length;
-
     TEST_EQUAL( status, expected_status );
+
     if( expected_status == PSA_SUCCESS )
     {
         PSA_ASSERT( psa_cipher_abort( &operation ) );
-        // driver function should've been called as part of the finish() core routine
         TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 0 );
+
         ASSERT_COMPARE( expected_output->x, expected_output->len,
                         output, total_output_length );
     }
@@ -515,16 +637,25 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
-                               data_t *key_data, data_t *iv,
+void cipher_decrypt_multipart( int alg_arg,
+                               int key_type_arg,
+                               data_t *key_data,
+                               data_t *iv,
                                data_t *input,
                                int first_part_size_arg,
-                               int output1_length_arg, int output2_length_arg,
-                               data_t *expected_output )
+                               int output1_length_arg,
+                               int output2_length_arg,
+                               data_t *expected_output,
+                               int mock_output_arg,
+                               int force_status_arg,
+                               int expected_status_arg )
 {
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
+    psa_status_t status;
+    psa_status_t expected_status = expected_status_arg;
+    psa_status_t force_status = force_status_arg;
     size_t first_part_size = first_part_size_arg;
     size_t output1_length = output1_length_arg;
     size_t output2_length = output2_length_arg;
@@ -535,91 +666,21 @@
     psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
+    mbedtls_test_driver_cipher_hooks.forced_status = force_status;
 
-    PSA_ASSERT( psa_crypto_init( ) );
+    /* Test operation initialization */
+    mbedtls_psa_cipher_operation_t mbedtls_operation =
+            MBEDTLS_PSA_CIPHER_OPERATION_INIT;
 
-    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
-    psa_set_key_algorithm( &attributes, alg );
-    psa_set_key_type( &attributes, key_type );
+    mbedtls_transparent_test_driver_cipher_operation_t tranparent_operation =
+            MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT;
 
-    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
-                                &key ) );
+    mbedtls_opaque_test_driver_cipher_operation_t opaque_operation =
+            MBEDTLS_OPAQUE_TEST_DRIVER_CIPHER_OPERATION_INIT;
 
-    PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
-
-    PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
-
-    output_buffer_size = ( (size_t) input->len +
-                           PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
-    ASSERT_ALLOC( output, output_buffer_size );
-
-    TEST_ASSERT( first_part_size <= input->len );
-    PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
-                                   output, output_buffer_size,
-                                   &function_output_length ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
-
-    TEST_ASSERT( function_output_length == output1_length );
-    total_output_length += function_output_length;
-    PSA_ASSERT( psa_cipher_update( &operation,
-                                   input->x + first_part_size,
-                                   input->len - first_part_size,
-                                   output + total_output_length,
-                                   output_buffer_size - total_output_length,
-                                   &function_output_length ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
-    TEST_ASSERT( function_output_length == output2_length );
-    total_output_length += function_output_length;
-    PSA_ASSERT( psa_cipher_finish( &operation,
-                                   output + total_output_length,
-                                   output_buffer_size - total_output_length,
-                                   &function_output_length ) );
-    /* Finish will have called abort as well, so expecting two hits here */
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 2 );
-    mbedtls_test_driver_cipher_hooks.hits = 0 ;
-    total_output_length += function_output_length;
-    PSA_ASSERT( psa_cipher_abort( &operation ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 0 );
-
-    ASSERT_COMPARE( expected_output->x, expected_output->len,
-                    output, total_output_length );
-
-exit:
-    psa_cipher_abort( &operation );
-    mbedtls_free( output );
-    psa_destroy_key( key );
-    PSA_DONE( );
-    mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
-                               data_t *key_data, data_t *iv,
-                               data_t *input,
-                               int first_part_size_arg,
-                               int output1_length_arg, int output2_length_arg,
-                               data_t *expected_output )
-{
-    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
-    psa_key_type_t key_type = key_type_arg;
-    psa_algorithm_t alg = alg_arg;
-    size_t first_part_size = first_part_size_arg;
-    size_t output1_length = output1_length_arg;
-    size_t output2_length = output2_length_arg;
-    unsigned char *output = NULL;
-    size_t output_buffer_size = 0;
-    size_t function_output_length = 0;
-    size_t total_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
+    operation.ctx.mbedtls_ctx = mbedtls_operation;
+    operation.ctx.transparent_test_driver_ctx = tranparent_operation;
+    operation.ctx.opaque_test_driver_ctx = opaque_operation;
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -635,47 +696,69 @@
     mbedtls_test_driver_cipher_hooks.hits = 0;
 
     PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
     mbedtls_test_driver_cipher_hooks.hits = 0;
 
     output_buffer_size = ( (size_t) input->len +
                            PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
     ASSERT_ALLOC( output, output_buffer_size );
 
+    if( mock_output_arg )
+    {
+        mbedtls_test_driver_cipher_hooks.forced_output = expected_output->x;
+        mbedtls_test_driver_cipher_hooks.forced_output_length = expected_output->len;
+    }
+
     TEST_ASSERT( first_part_size <= input->len );
     PSA_ASSERT( psa_cipher_update( &operation,
                                    input->x, first_part_size,
                                    output, output_buffer_size,
                                    &function_output_length ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
     mbedtls_test_driver_cipher_hooks.hits = 0;
 
     TEST_ASSERT( function_output_length == output1_length );
     total_output_length += function_output_length;
-    PSA_ASSERT( psa_cipher_update( &operation,
-                                   input->x + first_part_size,
-                                   input->len - first_part_size,
-                                   output + total_output_length,
-                                   output_buffer_size - total_output_length,
-                                   &function_output_length ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
 
-    TEST_ASSERT( function_output_length == output2_length );
-    total_output_length += function_output_length;
-    PSA_ASSERT( psa_cipher_finish( &operation,
-                                   output + total_output_length,
-                                   output_buffer_size - total_output_length,
-                                   &function_output_length ) );
+    if( first_part_size < input->len )
+    {
+        PSA_ASSERT( psa_cipher_update( &operation,
+                                       input->x + first_part_size,
+                                       input->len - first_part_size,
+                                       output + total_output_length,
+                                       output_buffer_size - total_output_length,
+                                       &function_output_length ) );
+        TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
+        mbedtls_test_driver_cipher_hooks.hits = 0;
+
+        TEST_ASSERT( function_output_length == output2_length );
+        total_output_length += function_output_length;
+    }
+
+    if( mock_output_arg )
+    {
+        mbedtls_test_driver_cipher_hooks.forced_output = NULL;
+        mbedtls_test_driver_cipher_hooks.forced_output_length = 0;
+    }
+
+    status = psa_cipher_finish( &operation,
+                                output + total_output_length,
+                                output_buffer_size - total_output_length,
+                                &function_output_length );
     /* Finish will have called abort as well, so expecting two hits here */
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 2 );
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 2 : 0 ) );
     mbedtls_test_driver_cipher_hooks.hits = 0;
     total_output_length += function_output_length;
-    PSA_ASSERT( psa_cipher_abort( &operation ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 0 );
+    TEST_EQUAL( status, expected_status );
 
-    ASSERT_COMPARE( expected_output->x, expected_output->len,
-                    output, total_output_length );
+    if( expected_status == PSA_SUCCESS )
+    {
+        PSA_ASSERT( psa_cipher_abort( &operation ) );
+        TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 0 );
+
+        ASSERT_COMPARE( expected_output->x, expected_output->len,
+                        output, total_output_length );
+    }
 
 exit:
     psa_cipher_abort( &operation );
@@ -687,9 +770,12 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void cipher_decrypt( int alg_arg, int key_type_arg,
-                     data_t *key_data, data_t *iv,
-                     data_t *input, data_t *expected_output,
+void cipher_decrypt( int alg_arg,
+                     int key_type_arg,
+                     data_t *key_data,
+                     data_t *iv,
+                     data_t *input_arg,
+                     data_t *expected_output,
                      int mock_output_arg,
                      int force_status_arg,
                      int expected_status_arg )
@@ -700,11 +786,11 @@
     psa_algorithm_t alg = alg_arg;
     psa_status_t expected_status = expected_status_arg;
     psa_status_t force_status = force_status_arg;
+    unsigned char *input = NULL;
+    size_t input_buffer_size = 0;
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
-    size_t function_output_length = 0;
-    size_t total_output_length = 0;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    size_t output_length = 0;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     mbedtls_test_driver_cipher_hooks = mbedtls_test_driver_cipher_hooks_init();
     mbedtls_test_driver_cipher_hooks.forced_status = force_status;
@@ -715,62 +801,42 @@
     psa_set_key_algorithm( &attributes, alg );
     psa_set_key_type( &attributes, key_type );
 
+    /* Allocate input buffer and copy the iv and the plaintext */
+    input_buffer_size = ( (size_t) input_arg->len + (size_t) iv->len );
+    if ( input_buffer_size > 0 )
+    {
+        ASSERT_ALLOC( input, input_buffer_size );
+        memcpy( input, iv->x, iv->len );
+        memcpy( input + iv->len, input_arg->x, input_arg->len );
+    }
+
+    output_buffer_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input_buffer_size );
+    ASSERT_ALLOC( output, output_buffer_size );
+
     PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                 &key ) );
 
-    PSA_ASSERT( psa_cipher_decrypt_setup( &operation, key, alg ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
-
-    PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
-
-    output_buffer_size = ( (size_t) input->len +
-                           PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
-    ASSERT_ALLOC( output, output_buffer_size );
-
     if( mock_output_arg )
     {
         mbedtls_test_driver_cipher_hooks.forced_output = expected_output->x;
         mbedtls_test_driver_cipher_hooks.forced_output_length = expected_output->len;
     }
 
-    PSA_ASSERT( psa_cipher_update( &operation,
-                                   input->x, input->len,
-                                   output, output_buffer_size,
-                                   &function_output_length ) );
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
+    status = psa_cipher_decrypt( key, alg, input, input_buffer_size, output,
+                                 output_buffer_size, &output_length );
+    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 1 );
     mbedtls_test_driver_cipher_hooks.hits = 0;
 
-    if( mock_output_arg )
-    {
-        mbedtls_test_driver_cipher_hooks.forced_output = NULL;
-        mbedtls_test_driver_cipher_hooks.forced_output_length = 0;
-    }
-
-    total_output_length += function_output_length;
-    status = psa_cipher_finish( &operation,
-                                output + total_output_length,
-                                output_buffer_size - total_output_length,
-                                &function_output_length );
-    /* Finish will have called abort as well, so expecting two hits here */
-    TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 2 : 0 ) );
-    mbedtls_test_driver_cipher_hooks.hits = 0;
-
-    total_output_length += function_output_length;
     TEST_EQUAL( status, expected_status );
 
     if( expected_status == PSA_SUCCESS )
     {
-        PSA_ASSERT( psa_cipher_abort( &operation ) );
-        TEST_EQUAL( mbedtls_test_driver_cipher_hooks.hits, 0 );
         ASSERT_COMPARE( expected_output->x, expected_output->len,
-                        output, total_output_length );
+                        output, output_length );
     }
 
 exit:
-    psa_cipher_abort( &operation );
+    mbedtls_free( input );
     mbedtls_free( output );
     psa_destroy_key( key );
     PSA_DONE( );
diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data
index 9bf91b5..a3668fc 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.data
+++ b/tests/suites/test_suite_psa_crypto_metadata.data
@@ -344,3 +344,39 @@
 
 DH group family: RFC 7919
 dh_key_family:PSA_DH_FAMILY_RFC7919
+
+Lifetime: VOLATILE
+lifetime:PSA_KEY_LIFETIME_VOLATILE:KEY_LIFETIME_IS_VOLATILE:PSA_KEY_PERSISTENCE_VOLATILE:PSA_KEY_LOCATION_LOCAL_STORAGE
+
+Lifetime: PERSISTENT
+lifetime:PSA_KEY_LIFETIME_PERSISTENT:0:PSA_KEY_PERSISTENCE_DEFAULT:PSA_KEY_LOCATION_LOCAL_STORAGE
+
+Lifetime: volatile, local storage
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_VOLATILE, PSA_KEY_LOCATION_LOCAL_STORAGE):KEY_LIFETIME_IS_VOLATILE:PSA_KEY_PERSISTENCE_VOLATILE:PSA_KEY_LOCATION_LOCAL_STORAGE
+
+Lifetime: default, local storage
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, PSA_KEY_LOCATION_LOCAL_STORAGE):0:PSA_KEY_PERSISTENCE_DEFAULT:PSA_KEY_LOCATION_LOCAL_STORAGE
+
+Lifetime: 2, local storage
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, PSA_KEY_LOCATION_LOCAL_STORAGE):0:2:PSA_KEY_LOCATION_LOCAL_STORAGE
+
+Lifetime: 254, local storage
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(254, PSA_KEY_LOCATION_LOCAL_STORAGE):0:254:PSA_KEY_LOCATION_LOCAL_STORAGE
+
+Lifetime: read-only, local storage
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_READ_ONLY, PSA_KEY_LOCATION_LOCAL_STORAGE):KEY_LIFETIME_IS_READ_ONLY:PSA_KEY_PERSISTENCE_READ_ONLY:PSA_KEY_LOCATION_LOCAL_STORAGE
+
+Lifetime: volatile, 0x123456
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_VOLATILE, 0x123456):KEY_LIFETIME_IS_VOLATILE:PSA_KEY_PERSISTENCE_VOLATILE:0x123456
+
+Lifetime: default, 0x123456
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, 0x123456):0:PSA_KEY_PERSISTENCE_DEFAULT:0x123456
+
+Lifetime: 2, 0x123456
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, 0x123456):0:2:0x123456
+
+Lifetime: 254, 0x123456
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(254, 0x123456):0:254:0x123456
+
+Lifetime: read-only, 0x123456
+lifetime:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_READ_ONLY, 0x123456):KEY_LIFETIME_IS_READ_ONLY:PSA_KEY_PERSISTENCE_READ_ONLY:0x123456
diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function
index 3ed08a6..4790be6 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.function
+++ b/tests/suites/test_suite_psa_crypto_metadata.function
@@ -55,8 +55,21 @@
 #define KEY_TYPE_IS_ECC                 ( 1u << 6 )
 #define KEY_TYPE_IS_DH                  ( 1u << 7 )
 
-#define TEST_CLASSIFICATION_MACRO( flag, alg, flags )           \
-    TEST_ASSERT( PSA_##flag( alg ) == !! ( ( flags ) & flag ) )
+/* Flags for lifetime classification macros. There is a flag for every
+ * lifetime classification macro PSA_KEY_LIFETIME_IS_xxx. The name of the
+ * flag is the name of the classification macro without the PSA_ prefix. */
+#define KEY_LIFETIME_IS_VOLATILE        ( 1u << 0 )
+#define KEY_LIFETIME_IS_READ_ONLY       ( 1u << 1 )
+
+#define TEST_CLASSIFICATION_MACRO( flag, alg, flags ) \
+    do                                                \
+    {                                                 \
+        if( ( flags ) & ( flag ) )                    \
+            TEST_ASSERT( PSA_##flag( alg ) );         \
+        else                                          \
+            TEST_ASSERT( ! PSA_##flag( alg ) );       \
+    }                                                 \
+    while( 0 )
 
 /* Check the parity of value.
  *
@@ -665,3 +678,20 @@
     TEST_EQUAL( PSA_KEY_TYPE_DH_GET_FAMILY( pair_type ), group );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void lifetime( int lifetime_arg, int classification_flags,
+               int persistence_arg, int location_arg )
+{
+    psa_key_lifetime_t lifetime = lifetime_arg;
+    psa_key_persistence_t persistence = persistence_arg;
+    psa_key_location_t location = location_arg;
+    unsigned flags = classification_flags;
+
+    TEST_CLASSIFICATION_MACRO( KEY_LIFETIME_IS_VOLATILE, lifetime, flags );
+    TEST_CLASSIFICATION_MACRO( KEY_LIFETIME_IS_READ_ONLY, lifetime, flags );
+
+    TEST_EQUAL( PSA_KEY_LIFETIME_GET_PERSISTENCE( lifetime ), persistence );
+    TEST_EQUAL( PSA_KEY_LIFETIME_GET_LOCATION( lifetime ), location );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data
index dad1205..b250634 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.data
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.data
@@ -119,3 +119,12 @@
 import/export-persistent symmetric key with restart: 16 bytes
 depends_on:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C
 import_export_persistent_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:1:0
+
+Destroy invalid id: 0
+destroy_nonexistent:0:PSA_SUCCESS
+
+Destroy non-existent key
+destroy_nonexistent:1:PSA_ERROR_INVALID_HANDLE
+
+Destroy invalid id: 0xffffffff
+destroy_nonexistent:0xffffffff:PSA_ERROR_INVALID_HANDLE
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index 9759077..bd9b9c9 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -323,3 +323,18 @@
     psa_destroy_persistent_key( key_id );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void destroy_nonexistent( int id_arg, int expected_status_arg )
+{
+    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make( 1, id_arg );
+    psa_status_t expected_status = expected_status_arg;
+
+    PSA_INIT( );
+
+    TEST_EQUAL( expected_status, psa_destroy_key( id ) );
+
+exit:
+    PSA_DONE( );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data
index 0fedd14..68b196d 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.data
+++ b/tests/suites/test_suite_psa_crypto_slot_management.data
@@ -78,6 +78,27 @@
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
 persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:137:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":INVALIDATE_BY_SHUTDOWN
 
+Persistent slot, check after closing, persistence=2
+persistent_slot_lifecycle:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, PSA_KEY_LOCATION_LOCAL_STORAGE):124:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":INVALIDATE_BY_CLOSING
+
+Persistent slot, check after closing and restarting, persistence=2
+persistent_slot_lifecycle:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, PSA_KEY_LOCATION_LOCAL_STORAGE):125:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":INVALIDATE_BY_CLOSING_WITH_SHUTDOWN
+
+Persistent slot, check after destroying, persistence=2
+persistent_slot_lifecycle:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, PSA_KEY_LOCATION_LOCAL_STORAGE):126:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":INVALIDATE_BY_DESTROYING
+
+Persistent slot, check after destroying and restarting, persistence=2
+persistent_slot_lifecycle:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, PSA_KEY_LOCATION_LOCAL_STORAGE):127:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":INVALIDATE_BY_DESTROYING_WITH_SHUTDOWN
+
+Persistent slot, check after purging, persistence=2
+persistent_slot_lifecycle:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, PSA_KEY_LOCATION_LOCAL_STORAGE):200:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":INVALIDATE_BY_PURGING
+
+Persistent slot, check after purging and restarting, persistence=2
+persistent_slot_lifecycle:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, PSA_KEY_LOCATION_LOCAL_STORAGE):201:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":INVALIDATE_BY_PURGING_WITH_SHUTDOWN
+
+Persistent slot, check after restart with live handle, persistence=2
+persistent_slot_lifecycle:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(2, PSA_KEY_LOCATION_LOCAL_STORAGE):128:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":INVALIDATE_BY_SHUTDOWN
+
 Attempt to overwrite: close before
 create_existent:PSA_KEY_LIFETIME_PERSISTENT:0x1736:1:CLOSE_BEFORE
 
@@ -107,13 +128,17 @@
 depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
 open_fail:1:PSA_ERROR_DOES_NOT_EXIST
 
-Create failure: invalid lifetime for a persistent key
+Create failure: read-only key
 depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
-create_fail:0x7fffffff:1:PSA_ERROR_INVALID_ARGUMENT
+create_fail:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_READ_ONLY, PSA_KEY_LOCATION_LOCAL_STORAGE):1:PSA_ERROR_INVALID_ARGUMENT
 
-Create failure: invalid lifetime for a volatile key
+Create failure: invalid location for a persistent key
 depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
-create_fail:0x7fffff00:0:PSA_ERROR_INVALID_ARGUMENT
+create_fail:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, 0xbad10cU):1:PSA_ERROR_INVALID_ARGUMENT
+
+Create failure: invalid location for a volatile key
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+create_fail:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_VOLATILE, 0xbad10cU):0:PSA_ERROR_INVALID_ARGUMENT
 
 Create failure: invalid key id (0) for a persistent key
 depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index dac52ab..aa3ce28 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -242,7 +242,8 @@
     TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
     TEST_ASSERT( mbedtls_svc_key_id_equal(
                      psa_get_key_id( &attributes ), id ) );
-    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
+    TEST_EQUAL( psa_get_key_usage_flags( &attributes ),
+                mbedtls_test_update_key_usage_flags( usage_flags ) );
     TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
     TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ), alg2 );
     TEST_EQUAL( psa_get_key_type( &attributes ), type );
@@ -261,7 +262,8 @@
     TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
     TEST_ASSERT( mbedtls_svc_key_id_equal(
                      psa_get_key_id( &attributes ), id ) );
-    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
+    TEST_EQUAL( psa_get_key_usage_flags( &attributes ),
+                mbedtls_test_update_key_usage_flags( usage_flags ) );
     TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
     TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ), alg2 );
     TEST_EQUAL( psa_get_key_type( &attributes ), type );
@@ -293,7 +295,8 @@
             TEST_ASSERT( mbedtls_svc_key_id_equal(
                              psa_get_key_id( &attributes ),
                              psa_get_key_id( &read_attributes ) ) );
-            TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
+            TEST_EQUAL( psa_get_key_usage_flags( &attributes ),
+                        mbedtls_test_update_key_usage_flags( usage_flags ) );
             TEST_EQUAL( psa_get_key_algorithm( &attributes ),
                         psa_get_key_algorithm( &read_attributes ) );
             TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ),
diff --git a/tests/suites/test_suite_psa_crypto_storage_format.function b/tests/suites/test_suite_psa_crypto_storage_format.function
index 34d63a7..b90ef6e 100644
--- a/tests/suites/test_suite_psa_crypto_storage_format.function
+++ b/tests/suites/test_suite_psa_crypto_storage_format.function
@@ -8,6 +8,7 @@
 #include <psa_crypto_its.h>
 
 #define TEST_FLAG_EXERCISE      0x00000001
+#define TEST_FLAG_READ_ONLY     0x00000002
 
 /** Write a key with the given attributes and key material to storage.
  * Test that it has the expected representation.
@@ -115,10 +116,20 @@
                          psa_get_key_algorithm( expected_attributes ) ) );
     }
 
-    /* Destroy the key. Confirm through direct access to the storage. */
-    PSA_ASSERT( psa_destroy_key( key_id ) );
-    TEST_EQUAL( PSA_ERROR_DOES_NOT_EXIST,
-                psa_its_get_info( uid, &storage_info ) );
+
+    if( flags & TEST_FLAG_READ_ONLY )
+    {
+        /* Read-only keys cannot be removed through the API.
+         * The key will be removed through ITS in the cleanup code below. */
+        TEST_EQUAL( PSA_ERROR_NOT_PERMITTED, psa_destroy_key( key_id ) );
+    }
+    else
+    {
+        /* Destroy the key. Confirm through direct access to the storage. */
+        PSA_ASSERT( psa_destroy_key( key_id ) );
+        TEST_EQUAL( PSA_ERROR_DOES_NOT_EXIST,
+                    psa_its_get_info( uid, &storage_info ) );
+    }
 
     ok = 1;
 
@@ -219,7 +230,6 @@
 
 exit:
     psa_reset_key_attributes( &attributes );
-    psa_destroy_key( key_id );
     PSA_DONE( );
 }
 /* END_CASE */
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index e81f208..49301aa 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -373,12 +373,18 @@
 RSA Private (Data larger than N)
 mbedtls_rsa_private:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"605baf947c0de49e4f6a0dfb94a43ae318d5df8ed20ba4ba5a37a73fb009c5c9e5cce8b70a25b1c7580f389f0d7092485cdfa02208b70d33482edf07a7eafebdc54862ca0e0396a5a7d09991b9753eb1ffb6091971bb5789c6b121abbcd0a3cbaa39969fa7c28146fce96c6d03272e3793e5be8f5abfa9afcbebb986d7b3050604a2af4d3a40fa6c003781a539a60259d1e84f13322da9e538a49c369b83e7286bf7d30b64bbb773506705da5d5d5483a563a1ffacc902fb75c9a751b1e83cdc7a6db0470056883f48b5a5446b43b1d180ea12ba11a6a8d93b3b32a30156b6084b7fb142998a2a0d28014b84098ece7d9d5e4d55cc342ca26f5a0167a679dec8":MBEDTLS_ERR_RSA_PRIVATE_FAILED + MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+RSA Private (Data = 0 )
+mbedtls_rsa_private:"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":0
+
 RSA Public (Correct)
 mbedtls_rsa_public:"59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f8700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"1f5e927c13ff231090b0f18c8c3526428ed0f4a7561457ee5afe4d22d5d9220c34ef5b9a34d0c07f7248a1f3d57f95d10f7936b3063e40660b3a7ca3e73608b013f85a6e778ac7c60d576e9d9c0c5a79ad84ceea74e4722eb3553bdb0c2d7783dac050520cb27ca73478b509873cb0dcbd1d51dd8fccb96c29ad314f36d67cc57835d92d94defa0399feb095fd41b9f0b2be10f6041079ed4290040449f8a79aba50b0a1f8cf83c9fb8772b0686ec1b29cb1814bb06f9c024857db54d395a8da9a2c6f9f53b94bec612a0cb306a3eaa9fc80992e85d9d232e37a50cabe48c9343f039601ff7d95d60025e582aec475d031888310e8ec3833b394a5cf0599101e":0
 
 RSA Public (Data larger than N)
 mbedtls_rsa_public:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"605baf947c0de49e4f6a0dfb94a43ae318d5df8ed20ba4ba5a37a73fb009c5c9e5cce8b70a25b1c7580f389f0d7092485cdfa02208b70d33482edf07a7eafebdc54862ca0e0396a5a7d09991b9753eb1ffb6091971bb5789c6b121abbcd0a3cbaa39969fa7c28146fce96c6d03272e3793e5be8f5abfa9afcbebb986d7b3050604a2af4d3a40fa6c003781a539a60259d1e84f13322da9e538a49c369b83e7286bf7d30b64bbb773506705da5d5d5483a563a1ffacc902fb75c9a751b1e83cdc7a6db0470056883f48b5a5446b43b1d180ea12ba11a6a8d93b3b32a30156b6084b7fb142998a2a0d28014b84098ece7d9d5e4d55cc342ca26f5a0167a679dec8":MBEDTLS_ERR_RSA_PUBLIC_FAILED + MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+RSA Public (Data = 0)
+mbedtls_rsa_public:"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":0
+
 RSA Generate Key - 128bit key
 mbedtls_rsa_gen_key:128:3:0
 
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index eb96e30..f5f5159 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -84,6 +84,7 @@
                              data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
     unsigned char output[256];
     mbedtls_rsa_context ctx;
     mbedtls_mpi N, P, Q, E;
@@ -99,23 +100,23 @@
     memset( output, 0x00, sizeof( output ) );
     memset( &rnd_info, 0, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
+    if( md_info != NULL )
+        TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len, hash_result ) == 0 );
 
-    if( mbedtls_md_info_from_type( digest ) != NULL )
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str->x, message_str->len, hash_result ) == 0 );
-
-    TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &mbedtls_test_rnd_pseudo_rand,
-                                         &rnd_info, digest, 0, hash_result,
-                                         output ) == result );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_sign(
+                     &ctx, &mbedtls_test_rnd_pseudo_rand, &rnd_info,
+                     digest, mbedtls_md_get_size( md_info ), hash_result,
+                     output ) == result );
     if( result == 0 )
     {
 
@@ -137,8 +138,8 @@
                                data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( digest );
     mbedtls_rsa_context ctx;
-
     mbedtls_mpi N, E;
 
     mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
@@ -147,17 +148,16 @@
                                           MBEDTLS_MD_NONE ) == 0 );
     memset( hash_result, 0x00, sizeof( hash_result ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
+    if( md_info != NULL )
+        TEST_ASSERT( mbedtls_md( md_info, message_str->x, message_str->len, hash_result ) == 0 );
 
-    if( mbedtls_md_info_from_type( digest ) != NULL )
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str->x, message_str->len, hash_result ) == 0 );
-
-    TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, digest, 0, hash_result, result_str->x ) == result );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_verify( &ctx, digest, mbedtls_md_get_size( md_info ), hash_result, result_str->x ) == result );
 
 exit:
     mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
@@ -179,18 +179,19 @@
     mbedtls_test_rnd_pseudo_info rnd_info;
 
     mbedtls_rsa_init( &ctx );
-    TEST_ASSERT( mbedtls_rsa_set_padding( &ctx, padding_mode,
-                                          MBEDTLS_MD_NONE ) == 0 );
     mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P );
     mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &E );
 
+    TEST_ASSERT( mbedtls_rsa_set_padding( &ctx, padding_mode,
+                                          MBEDTLS_MD_NONE ) == 0 );
+
     memset( output, 0x00, sizeof( output ) );
     memset( &rnd_info, 0, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -232,8 +233,8 @@
                                           MBEDTLS_MD_NONE ) == 0 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -268,8 +269,8 @@
                                           MBEDTLS_MD_NONE ) == 0 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -311,8 +312,8 @@
                                           MBEDTLS_MD_NONE ) == 0 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -361,10 +362,10 @@
     memset( &rnd_info, 0, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -407,14 +408,16 @@
     mbedtls_rsa_init( &ctx2 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
+
+    /* Check test data consistency */
+    TEST_ASSERT( message_str->len == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
-
     TEST_ASSERT( mbedtls_rsa_public( &ctx, message_str->x, output ) == result );
     if( result == 0 )
     {
@@ -466,17 +469,19 @@
 
     memset( &rnd_info, 0, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
+
+    /* Check test data consistency */
+    TEST_ASSERT( message_str->len == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
-
     /* repeat three times to test updating of blinding values */
     for( i = 0; i < 3; i++ )
     {
@@ -542,11 +547,11 @@
 
     if( strlen( input_N ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
     }
     if( strlen( input_E ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     }
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
@@ -574,36 +579,36 @@
     ctx.len = mod / 8;
     if( strlen( input_P ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.P, radix_P, input_P ) == 0 );
     }
     if( strlen( input_Q ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.Q, radix_Q, input_Q ) == 0 );
     }
     if( strlen( input_N ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.N, radix_N, input_N ) == 0 );
     }
     if( strlen( input_E ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.E, radix_E, input_E ) == 0 );
     }
     if( strlen( input_D ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.D, radix_D, input_D ) == 0 );
     }
 #if !defined(MBEDTLS_RSA_NO_CRT)
     if( strlen( input_DP ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.DP, radix_DP, input_DP ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.DP, radix_DP, input_DP ) == 0 );
     }
     if( strlen( input_DQ ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.DQ, radix_DQ, input_DQ ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.DQ, radix_DQ, input_DQ ) == 0 );
     }
     if( strlen( input_QP ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.QP, radix_QP, input_QP ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.QP, radix_QP, input_QP ) == 0 );
     }
 #else
     ((void) radix_DP); ((void) input_DP);
@@ -638,45 +643,45 @@
 
     if( strlen( input_Npub ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &pub.N, radix_Npub, input_Npub ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &pub.N, radix_Npub, input_Npub ) == 0 );
     }
     if( strlen( input_Epub ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &pub.E, radix_Epub, input_Epub ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &pub.E, radix_Epub, input_Epub ) == 0 );
     }
 
     if( strlen( input_P ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.P, radix_P, input_P ) == 0 );
     }
     if( strlen( input_Q ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.Q, radix_Q, input_Q ) == 0 );
     }
     if( strlen( input_N ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.N, radix_N, input_N ) == 0 );
     }
     if( strlen( input_E ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.E, radix_E, input_E ) == 0 );
     }
     if( strlen( input_D ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.D, radix_D, input_D ) == 0 );
     }
 #if !defined(MBEDTLS_RSA_NO_CRT)
     if( strlen( input_DP ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.DP, radix_DP, input_DP ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.DP, radix_DP, input_DP ) == 0 );
     }
     if( strlen( input_DQ ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.DQ, radix_DQ, input_DQ ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.DQ, radix_DQ, input_DQ ) == 0 );
     }
     if( strlen( input_QP ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.QP, radix_QP, input_QP ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.QP, radix_QP, input_QP ) == 0 );
     }
 #else
     ((void) radix_DP); ((void) input_DP);
@@ -737,11 +742,11 @@
     mbedtls_mpi_init( &Pp ); mbedtls_mpi_init( &Qp );
     mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Qp, radix_P, output_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Pp, radix_Q, output_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &D, radix_D, input_D ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Qp, radix_P, output_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Pp, radix_Q, output_Q ) == 0 );
 
     if( corrupt )
         TEST_ASSERT( mbedtls_mpi_add_int( &D, &D, 2 ) == 0 );
@@ -778,10 +783,10 @@
     mbedtls_mpi_init( &E );
     mbedtls_mpi_init( &R ); mbedtls_mpi_init( &Rp );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Dp, radix_D, output_D ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Dp, radix_D, output_D ) == 0 );
 
     if( corrupt )
     {
@@ -864,19 +869,19 @@
                                 (const unsigned char *) pers, strlen( pers ) ) == 0 );
 
     if( have_N )
-        TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
 
     if( have_P )
-        TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
 
     if( have_Q )
-        TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
 
     if( have_D )
-        TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &D, radix_D, input_D ) == 0 );
 
     if( have_E )
-        TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     if( !successive )
     {
@@ -1008,19 +1013,19 @@
     /* Setup RSA context */
 
     if( have_N )
-        TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
 
     if( have_P )
-        TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
 
     if( have_Q )
-        TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
 
     if( have_D )
-        TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &D, radix_D, input_D ) == 0 );
 
     if( have_E )
-        TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx,
                                      strlen( input_N ) ? &N : NULL,
@@ -1128,19 +1133,19 @@
                                         strlen( pers ) ) == 0 );
 
     if( have_N )
-        TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
 
     if( have_P )
-        TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
 
     if( have_Q )
-        TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
 
     if( have_D )
-        TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &D, radix_D, input_D ) == 0 );
 
     if( have_E )
-        TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_validate_params( have_N ? &N : NULL,
                                         have_P ? &P : NULL,
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index d5123fa..98ed11f 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -1842,7 +1842,7 @@
 
     if( options->expected_negotiated_version == TEST_SSL_MINOR_VERSION_NONE )
     {
-        expected_handshake_result = MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION;
+        expected_handshake_result = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
     }
 
     TEST_ASSERT( mbedtls_move_handshake_to_state( &(client.ssl),
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index c9b7cf9..261794c 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -248,7 +248,7 @@
     (void) rsa_alt;
 #endif
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &serial, 10, serial_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &serial, 10, serial_str ) == 0 );
 
     if( ver != -1 )
         mbedtls_x509write_crt_set_version( &crt, ver );