Merge pull request #3826 from frestr/test/chachapoly_vector

PSA Crypto: Add zero-length input test vectors for ChaChaPoly
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5af4c81..ac24bf4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,9 +14,13 @@
 #     CMake files. It is related to ZLIB support which is planned to be removed.
 #     When the support is removed, the associated include_directories command
 #     will be removed as well as this note.
+# - MBEDTLS_TARGET_PREFIX: CMake targets are designed to be alterable by calling
+#   CMake in order to avoid target name clashes, via the use of
+#   MBEDTLS_TARGET_PREFIX. The value of this variable is prefixed to the
+#   mbedtls, mbedx509, mbedcrypto and apidoc targets.
 #
 
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 2.8.12)
 if(TEST_CPP)
     project("mbed TLS" C CXX)
 else()
@@ -112,9 +116,12 @@
     endif()
 endif()
 
-set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
-    CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
-    FORCE)
+# If this is the root project add longer list of available CMAKE_BUILD_TYPE values
+if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+    set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
+        CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
+        FORCE)
+endif()
 
 # Create a symbolic link from ${base_name} in the binary directory
 # to the corresponding path in the source directory.
@@ -273,7 +280,7 @@
     add_subdirectory(programs)
 endif()
 
-ADD_CUSTOM_TARGET(apidoc
+ADD_CUSTOM_TARGET(${MBEDTLS_TARGET_PREFIX}apidoc
     COMMAND doxygen mbedtls.doxyfile
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doxygen)
 
diff --git a/ChangeLog.d/00README.md b/ChangeLog.d/00README.md
index b559e23..d2ea73d 100644
--- a/ChangeLog.d/00README.md
+++ b/ChangeLog.d/00README.md
@@ -3,6 +3,29 @@
 This directory contains changelog entries that have not yet been merged
 to the changelog file ([`../ChangeLog`](../ChangeLog)).
 
+## What requires a changelog entry?
+
+Write a changelog entry if there is a user-visible change. This includes:
+
+* Bug fixes in the library or in sample programs: fixing a security hole,
+  fixing broken behavior, fixing the build in some configuration or on some
+  platform, etc.
+* New features in the library, new sample programs, or new platform support.
+* Changes in existing behavior. These should be rare. Changes in features
+  that are documented as experimental may or may not be announced, depending
+  on the extent of the change and how widely we expect the feature to be used.
+
+We generally don't include changelog entries for:
+
+* Documentation improvements.
+* Performance improvements, unless they are particularly significant.
+* Changes to parts of the code base that users don't interact with directly,
+  such as test code and test data.
+
+Until Mbed TLS 2.24.0, we required changelog entries in more cases.
+Looking at older changelog entries is good practice for how to write a
+changelog entry, but not for deciding whether to write one.
+
 ## Changelog entry file format
 
 A changelog entry file must have the extension `*.txt` and must have the
@@ -33,8 +56,7 @@
     Bugfix
     Changes
 
-Use “Changes” for anything that doesn't fit in the other categories, such as
-performance, documentation and test improvements.
+Use “Changes” for anything that doesn't fit in the other categories.
 
 ## How to write a changelog entry
 
@@ -49,8 +71,7 @@
 Mbed TLS issue. Add other external references such as CVE numbers where
 applicable.
 
-Credit the author of the contribution if the contribution is not a member of
-the Mbed TLS development team. Also credit bug reporters where applicable.
+Credit bug reporters where applicable.
 
 **Explain why, not how**. Remember that the audience is the users of the
 library, not its developers. In particular, for a bug fix, explain the
diff --git a/ChangeLog.d/_GNU_SOURCE-redefined.txt b/ChangeLog.d/_GNU_SOURCE-redefined.txt
new file mode 100644
index 0000000..59c8a15
--- /dev/null
+++ b/ChangeLog.d/_GNU_SOURCE-redefined.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix the build when the macro _GNU_SOURCE is defined to a non-empty value.
+     Fix #3432.
diff --git a/ChangeLog.d/add_MBEDTLS_TARGET_PREFIX_to_cmake.txt b/ChangeLog.d/add_MBEDTLS_TARGET_PREFIX_to_cmake.txt
new file mode 100644
index 0000000..533f309
--- /dev/null
+++ b/ChangeLog.d/add_MBEDTLS_TARGET_PREFIX_to_cmake.txt
@@ -0,0 +1,6 @@
+Features
+   * Add MBEDTLS_TARGET_PREFIX CMake variable, which is prefixed to the mbedtls,
+     mbedcrypto, mbedx509 and apidoc CMake target names. This can be used by
+     external CMake projects that include this one to avoid CMake target name
+     clashes.  The default value of this variable is "", so default target names
+     are unchanged.
diff --git a/ChangeLog.d/android-socklen_t.txt b/ChangeLog.d/android-socklen_t.txt
new file mode 100644
index 0000000..d795a52
--- /dev/null
+++ b/ChangeLog.d/android-socklen_t.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Use socklen_t on Android and other POSIX-compliant system
+
diff --git a/ChangeLog.d/bugfix_3794.txt b/ChangeLog.d/bugfix_3794.txt
new file mode 100644
index 0000000..a483ea7
--- /dev/null
+++ b/ChangeLog.d/bugfix_3794.txt
@@ -0,0 +1,4 @@
+Bugfix
+  * Fix handling of EOF against 0xff bytes and on platforms with
+    unsigned chars.  Fixes a build failure on platforms where char is
+    unsigned.  Fixes #3794.
diff --git a/ChangeLog.d/comment_typo_in_mbedtls_ssl_set_bio.txt b/ChangeLog.d/comment_typo_in_mbedtls_ssl_set_bio.txt
deleted file mode 100644
index 2f94c16..0000000
--- a/ChangeLog.d/comment_typo_in_mbedtls_ssl_set_bio.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Changes
-   * Fix comment typo in documentation of mbedtls_ssl_set_bio.
diff --git a/ChangeLog.d/ecp_curve_list.txt b/ChangeLog.d/ecp_curve_list.txt
new file mode 100644
index 0000000..55745d3
--- /dev/null
+++ b/ChangeLog.d/ecp_curve_list.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * mbedtls_ecp_curve_list() now lists Curve25519 and Curve448 under the names
+     "x25519" and "x448". These curves support ECDH but not ECDSA. If you need
+     only the curves that support ECDSA, filter the list with
+     mbedtls_ecdsa_can_do().
diff --git a/ChangeLog.d/feature-dtls-srtp.txt b/ChangeLog.d/feature-dtls-srtp.txt
new file mode 100644
index 0000000..8b9186b
--- /dev/null
+++ b/ChangeLog.d/feature-dtls-srtp.txt
@@ -0,0 +1,2 @@
+Features
+* Add support for DTLS-SRTP as defined in RFC 5764. Contributed by Johan Pascal, improved by Ron Eldor.
diff --git a/ChangeLog.d/fix-rsa-blinding.txt b/ChangeLog.d/fix-rsa-blinding.txt
new file mode 100644
index 0000000..a13572c
--- /dev/null
+++ b/ChangeLog.d/fix-rsa-blinding.txt
@@ -0,0 +1,6 @@
+Bugfix
+   * Fix rsa_prepare_blinding() to retry when the blinding value is not
+     invertible (mod N), instead of returning MBEDTLS_ERR_RSA_RNG_FAILED. This
+     addresses a regression but is rare in practice (approx. 1 in 2/sqrt(N)).
+     Found by Synopsys Coverity, fix contributed by Peter Kolbus (Garmin).
+     Fixes #3647.
diff --git a/ChangeLog.d/fix-typo.txt b/ChangeLog.d/fix-typo.txt
deleted file mode 100644
index 8e961d2..0000000
--- a/ChangeLog.d/fix-typo.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Changes
-   * Fixes a typo in the example code located in
-     program/pkey/ecdh_curve25519.c
diff --git a/ChangeLog.d/fix_ccm_add_length_check.txt b/ChangeLog.d/fix_ccm_add_length_check.txt
new file mode 100644
index 0000000..259399f
--- /dev/null
+++ b/ChangeLog.d/fix_ccm_add_length_check.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix an off-by-one error in the additional data length check for
+     CCM, which allowed encryption with a non-standard length field.
+     Fixes #3719.
+
diff --git a/ChangeLog.d/minimum_cmake_version_PR3802.txt b/ChangeLog.d/minimum_cmake_version_PR3802.txt
new file mode 100644
index 0000000..549f9b1
--- /dev/null
+++ b/ChangeLog.d/minimum_cmake_version_PR3802.txt
@@ -0,0 +1,3 @@
+Requirement changes
+* Update the minimum required CMake version to 2.8.12.
+* This silences a warning on CMake 3.19.0. #3801
diff --git a/ChangeLog.d/psa_error_invalid_argument_for_invalid_cipher_input_sizes.txt b/ChangeLog.d/psa_error_invalid_argument_for_invalid_cipher_input_sizes.txt
new file mode 100644
index 0000000..85c363b
--- /dev/null
+++ b/ChangeLog.d/psa_error_invalid_argument_for_invalid_cipher_input_sizes.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Consistently return PSA_ERROR_INVALID_ARGUMENT on invalid cipher input
+     sizes (instead of PSA_ERROR_BAD_STATE in some cases) to make the
+     psa_cipher_* functions compliant with the PSA Crypto API specification.
diff --git a/ChangeLog.d/psa_generate_key-curve25519.txt b/ChangeLog.d/psa_generate_key-curve25519.txt
new file mode 100644
index 0000000..24b6fcf
--- /dev/null
+++ b/ChangeLog.d/psa_generate_key-curve25519.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix psa_generate_key() returning an error when asked to generate
+     an ECC key pair on Curve25519 or secp244k1.
diff --git a/ChangeLog.d/support-ecdh-kdf-with-ecdh-key.txt b/ChangeLog.d/support-ecdh-kdf-with-ecdh-key.txt
new file mode 100644
index 0000000..6660dc3
--- /dev/null
+++ b/ChangeLog.d/support-ecdh-kdf-with-ecdh-key.txt
@@ -0,0 +1,6 @@
+Features
+   * In PSA, allow using a key declared with a base key agreement algorithm
+     in combined key agreement and derivation operations, as long as the key
+     agreement algorithm in use matches the algorithm the key was declared with.
+     This is currently non-standard behaviour, but expected to make it into a
+     future revision of the PSA Crypto standard.
diff --git a/ChangeLog.d/support-key-agreement-and-derivation-output-as-key.txt b/ChangeLog.d/support-key-agreement-and-derivation-output-as-key.txt
new file mode 100644
index 0000000..3f61481
--- /dev/null
+++ b/ChangeLog.d/support-key-agreement-and-derivation-output-as-key.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix psa_key_derivation_output_key() to allow the output of a combined key
+     agreement and subsequent key derivation operation to be used as a key
+     inside of the PSA Crypto core.
diff --git a/ChangeLog.d/systematically_store_bit_size_3740.txt b/ChangeLog.d/systematically_store_bit_size_3740.txt
new file mode 100644
index 0000000..9e63bbc
--- /dev/null
+++ b/ChangeLog.d/systematically_store_bit_size_3740.txt
@@ -0,0 +1,5 @@
+Changes
+   * The PSA persistent storage format is updated to always store the key bits
+     attribute. No automatic upgrade path is provided. Previously stored keys
+     must be erased, or manually upgraded based on the key storage format
+     specification (docs/architecture/mbed-crypto-storage-specification.md). #3740
diff --git a/docs/architecture/mbed-crypto-storage-specification.md b/docs/architecture/mbed-crypto-storage-specification.md
index afeb29f..914bca3 100644
--- a/docs/architecture/mbed-crypto-storage-specification.md
+++ b/docs/architecture/mbed-crypto-storage-specification.md
@@ -251,6 +251,7 @@
 * key material length (4 bytes).
 * key material:
     * For a transparent key: output of `psa_export_key`.
+    * For an opaque key (unified driver interface): driver-specific opaque key blob.
     * For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
 * Any trailing data is rejected on load.
 
@@ -280,3 +281,36 @@
     * The slot in the secure element designated by the slot number.
     * The file containing the key metadata designated by the key identifier.
     * The driver persistent data.
+
+Mbed Crypto TBD
+---------------
+
+Tags: TBD
+
+Released in TBD 2020. <br>
+Integrated in Mbed OS TBD.
+
+### Changes introduced in TBD
+
+* The type field has been split into a type and a bits field of 2 bytes each.
+
+### Key file format for TBD
+
+All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
+
+The layout of a key file is:
+
+* magic (8 bytes): `"PSA\0KEY\0"`.
+* version (4 bytes): 0.
+* lifetime (4 bytes): `psa_key_lifetime_t` value.
+* type (2 bytes): `psa_key_type_t` value.
+* bits (2 bytes): `psa_key_bits_t` value.
+* policy usage flags (4 bytes): `psa_key_usage_t` value.
+* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
+* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
+* key material length (4 bytes).
+* key material:
+    * For a transparent key: output of `psa_export_key`.
+    * For an opaque key (unified driver interface): driver-specific opaque key blob.
+    * For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
+* Any trailing data is rejected on load.
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 120c1d3..fd979db 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -871,6 +871,10 @@
 #endif /* MBEDTLS_DEPRECATED_REMOVED */
 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) )
+#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites"
+#endif
+
 /*
  * Avoid warning from -pedantic. This is a convenient place for this
  * workaround since this is included by every single file before the
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index b77b34b..2ac2cc6 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -864,7 +864,7 @@
  * may result in a compromise of the long-term signing key. This is avoided by
  * the deterministic variant.
  *
- * Requires: MBEDTLS_HMAC_DRBG_C
+ * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C
  *
  * Comment this macro to disable deterministic ECDSA.
  */
@@ -1330,7 +1330,7 @@
  *
  * Enable support for the experimental PSA crypto driver interface.
  *
- * Requires: MBEDTLS_PSA_CRYPTO_C.
+ * Requires: MBEDTLS_PSA_CRYPTO_C
  *
  * \warning This interface is experimental and may change or be removed
  * without notice.
@@ -1813,6 +1813,37 @@
 #define MBEDTLS_SSL_DTLS_HELLO_VERIFY
 
 /**
+ * \def MBEDTLS_SSL_DTLS_SRTP
+ *
+ * Enable support for negotation of DTLS-SRTP (RFC 5764)
+ * through the use_srtp extension.
+ *
+ * \note This feature provides the minimum functionality required
+ * to negotiate the use of DTLS-SRTP and to allow the derivation of
+ * the associated SRTP packet protection key material.
+ * In particular, the SRTP packet protection itself, as well as the
+ * demultiplexing of RTP and DTLS packets at the datagram layer
+ * (see Section 5 of RFC 5764), are not handled by this feature.
+ * Instead, after successful completion of a handshake negotiating
+ * the use of DTLS-SRTP, the extended key exporter API
+ * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement
+ * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705
+ * (this is implemented in the SSL example programs).
+ * The resulting key should then be passed to an SRTP stack.
+ *
+ * Setting this option enables the runtime API
+ * mbedtls_ssl_conf_dtls_srtp_protection_profiles()
+ * through which the supported DTLS-SRTP protection
+ * profiles can be configured. You must call this API at
+ * runtime if you wish to negotiate the use of DTLS-SRTP.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Uncomment this to enable support for use_srtp extension.
+ */
+//#define MBEDTLS_SSL_DTLS_SRTP
+
+/**
  * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
  *
  * Enable server-side support for clients that reconnect from the same port.
@@ -2020,6 +2051,20 @@
 //#define MBEDTLS_USE_PSA_CRYPTO
 
 /**
+ * \def MBEDTLS_PSA_CRYPTO_CONFIG
+ *
+ * This setting allows support for cryptographic mechanisms through the PSA
+ * API to be configured separately from support through the mbedtls API.
+ *
+ * Uncomment this to enable use of PSA Crypto configuration settings which
+ * can be found in include/psa/crypto_config.h
+ *
+ * This feature is still experimental and is not ready for production since
+ * it is not completed.
+ */
+//#define MBEDTLS_PSA_CRYPTO_CONFIG
+
+/**
  * \def MBEDTLS_VERSION_FEATURES
  *
  * Allow run-time checking of compile-time enabled features. Thus allowing users
@@ -3811,6 +3856,8 @@
 #include MBEDTLS_USER_CONFIG_FILE
 #endif
 
+#include "mbedtls/config_psa.h"
+
 #include "mbedtls/check_config.h"
 
 #endif /* MBEDTLS_CONFIG_H */
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
new file mode 100644
index 0000000..6af4d19
--- /dev/null
+++ b/include/mbedtls/config_psa.h
@@ -0,0 +1,82 @@
+/**
+ * \file mbedtls/config_psa.h
+ * \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
+ *  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/psa/crypto_config.h for PSA_WANT_XXX settings.
+ */
+/*
+ *  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_CONFIG_PSA_H
+#define MBEDTLS_CONFIG_PSA_H
+
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#include "psa/crypto_config.h"
+#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+
+#if defined(PSA_WANT_ALG_ECDSA)
+#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)
+#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA                   1
+#define MBEDTLS_ECDSA_C
+#endif /* !MBEDTLS_PSA_ACCEL_ALG_ECDSA */
+#endif /* PSA_WANT_ALG_ECDSA */
+
+#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
+#if !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)
+#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA     1
+#define MBEDTLS_ECDSA_DETERMINISTIC
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_HMAC_DRBG_C
+#define MBEDTLS_MD_C
+#endif /* MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA */
+#endif /* PSA_WANT_ALG_DETERMINISTIC_ECDSA */
+
+#else /* MBEDTLS_PSA_CRYPTO_CONFIG */
+
+/*
+ * Ensure PSA_WANT_* defines are setup properly if MBEDTLS_PSA_CRYPTO_CONFIG
+ * is not defined
+ */
+#if defined(MBEDTLS_ECDSA_C)
+#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA
+
+// Only add in DETERMINISTIC support if ECDSA is also enabled
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+
+#endif /* MBEDTLS_ECDSA_C */
+
+#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CONFIG_PSA_H */
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index a091261..1b4e163 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -214,6 +214,9 @@
 #define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED       1
 #define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED      0
 
+#define MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED    0
+#define MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED      1
+
 /*
  * Default range for DTLS retransmission timer value, in milliseconds.
  * RFC 6347 4.2.4.1 says from 1 second to 60 seconds.
@@ -393,6 +396,8 @@
 
 #define MBEDTLS_TLS_EXT_SIG_ALG                     13
 
+#define MBEDTLS_TLS_EXT_USE_SRTP                    14
+
 #define MBEDTLS_TLS_EXT_ALPN                        16
 
 #define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC            22 /* 0x16 */
@@ -851,6 +856,41 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED &&
           !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+
+#define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH             255
+#define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH    4
+/*
+ * For code readability use a typedef for DTLS-SRTP profiles
+ *
+ * Use_srtp extension protection profiles values as defined in
+ * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+ *
+ * Reminder: if this list is expanded mbedtls_ssl_check_srtp_profile_value
+ * must be updated too.
+ */
+#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80     ( (uint16_t) 0x0001)
+#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32     ( (uint16_t) 0x0002)
+#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80          ( (uint16_t) 0x0005)
+#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32          ( (uint16_t) 0x0006)
+/* This one is not iana defined, but for code readability. */
+#define MBEDTLS_TLS_SRTP_UNSET                      ( (uint16_t) 0x0000)
+
+typedef uint16_t mbedtls_ssl_srtp_profile;
+
+typedef struct mbedtls_dtls_srtp_info_t
+{
+    /*! The SRTP profile that was negotiated. */
+    mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile;
+    /*! The length of mki_value. */
+    uint16_t mki_len;
+    /*! The mki_value used, with max size of 256 bytes. */
+    unsigned char mki_value[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH];
+}
+mbedtls_dtls_srtp_info;
+
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 /*
  * This structure is used for storing current session data.
  *
@@ -1057,6 +1097,13 @@
     const char **alpn_list;         /*!< ordered list of protocols          */
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    /*! ordered list of supported srtp profile */
+    const mbedtls_ssl_srtp_profile *dtls_srtp_profile_list;
+    /*! number of supported profiles */
+    size_t dtls_srtp_profile_list_len;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
     /*
      * Numerical settings (int then char)
      */
@@ -1137,9 +1184,12 @@
                                              *   record with unexpected CID
                                              *   should lead to failure.    */
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    unsigned int dtls_srtp_mki_support : 1; /* support having mki_value
+                                               in the use_srtp extension     */
+#endif
 };
 
-
 struct mbedtls_ssl_context
 {
     const mbedtls_ssl_config *conf; /*!< configuration information          */
@@ -1298,6 +1348,13 @@
     const char *alpn_chosen;    /*!<  negotiated protocol                   */
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    /*
+     * use_srtp extension
+     */
+    mbedtls_dtls_srtp_info dtls_srtp_info;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
     /*
      * Information for DTLS hello verify
      */
@@ -2032,6 +2089,8 @@
  *                  (Default: none.)
  *
  * \note            See \c mbedtls_ssl_export_keys_ext_t.
+ * \warning         Exported key material must not be used for any purpose
+ *                  before the (D)TLS handshake is completed
  *
  * \param conf      SSL configuration context
  * \param f_export_keys_ext Callback for exporting keys
@@ -3120,6 +3179,105 @@
 const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+#if defined(MBEDTLS_DEBUG_C)
+static inline const char *mbedtls_ssl_get_srtp_profile_as_string( mbedtls_ssl_srtp_profile profile )
+{
+    switch( profile )
+    {
+        case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
+            return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" );
+        case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32:
+            return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" );
+        case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80:
+            return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" );
+        case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
+            return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" );
+        default: break;
+    }
+    return( "" );
+}
+#endif /* MBEDTLS_DEBUG_C */
+/**
+ * \brief                   Manage support for mki(master key id) value
+ *                          in use_srtp extension.
+ *                          MKI is an optional part of SRTP used for key management
+ *                          and re-keying. See RFC3711 section 3.1 for details.
+ *                          The default value is
+ *                          #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED.
+ *
+ * \param conf              The SSL configuration to manage mki support.
+ * \param support_mki_value Enable or disable mki usage. Values are
+ *                          #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED
+ *                          or #MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED.
+ */
+void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
+                                                int support_mki_value );
+
+/**
+ * \brief                   Set the supported DTLS-SRTP protection profiles.
+ *
+ * \param conf              SSL configuration
+ * \param profiles          Pointer to a List of MBEDTLS_TLS_SRTP_UNSET terminated
+ *                          supported protection profiles
+ *                          in decreasing preference order.
+ *                          The pointer to the list is recorded by the library
+ *                          for later reference as required, so the lifetime
+ *                          of the table must be at least as long as the lifetime
+ *                          of the SSL configuration structure.
+ *                          The list must not hold more than
+ *                          MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH elements
+ *                          (excluding the terminating MBEDTLS_TLS_SRTP_UNSET).
+ *
+ * \return                  0 on success
+ * \return                  #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of
+ *                          protection profiles is incorrect.
+ */
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles
+                               ( mbedtls_ssl_config *conf,
+                                 const mbedtls_ssl_srtp_profile *profiles );
+
+/**
+ * \brief                  Set the mki_value for the current DTLS-SRTP session.
+ *
+ * \param ssl              SSL context to use.
+ * \param mki_value        The MKI value to set.
+ * \param mki_len          The length of the MKI value.
+ *
+ * \note                   This function is relevant on client side only.
+ *                         The server discovers the mki value during handshake.
+ *                         A mki value set on server side using this function
+ *                         is ignored.
+ *
+ * \return                 0 on success
+ * \return                 #MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+ * \return                 #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
+ */
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
+                                         unsigned char *mki_value,
+                                         uint16_t mki_len );
+/**
+ * \brief                  Get the negotiated DTLS-SRTP informations:
+ *                         Protection profile and MKI value.
+ *
+ * \warning                This function must be called after the handshake is
+ *                         completed. The value returned by this function must
+ *                         not be trusted or acted upon before the handshake completes.
+ *
+ * \param ssl              The SSL context to query.
+ * \param dtls_srtp_info   The negotiated DTLS-SRTP informations:
+ *                         - Protection profile in use.
+ *                         A direct mapping of the iana defined value for protection
+ *                         profile on an uint16_t.
+                   http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+ *                         #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated
+ *                         or peer's Hello packet was not parsed yet.
+ *                         - mki size and value( if size is > 0 ).
+ */
+void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl,
+                                                   mbedtls_dtls_srtp_info *dtls_srtp_info );
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 /**
  * \brief          Set the maximum supported version sent from the client side
  *                 and/or accepted at the server side
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 7b78c73..1dc9648 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1095,6 +1095,23 @@
                                 mbedtls_md_type_t md );
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value
+                                                    ( const uint16_t srtp_profile_value )
+{
+    switch( srtp_profile_value )
+    {
+        case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
+        case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32:
+        case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80:
+        case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
+            return srtp_profile_value;
+        default: break;
+    }
+    return( MBEDTLS_TLS_SRTP_UNSET );
+}
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl )
 {
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
new file mode 100644
index 0000000..8dbb18d
--- /dev/null
+++ b/include/psa/crypto_config.h
@@ -0,0 +1,56 @@
+/**
+ * \file psa/crypto_config.h
+ * \brief PSA crypto configuration options (set of defines)
+ *
+ */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+/**
+ * When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in config.h,
+ * this file determines which cryptographic mechanisms are enabled
+ * through the PSA Cryptography API (\c psa_xxx() functions).
+ *
+ * To enable a cryptographic mechanism, uncomment the definition of
+ * the corresponding \c PSA_WANT_xxx preprocessor symbol.
+ * To disable a cryptographic mechanism, comment out the definition of
+ * the corresponding \c PSA_WANT_xxx preprocessor symbol.
+ * The names of cryptographic mechanisms correspond to values
+ * defined in psa/crypto_values.h, with the prefix \c PSA_WANT_ instead
+ * of \c PSA_.
+ *
+ * Note that many cryptographic mechanisms involve two symbols: one for
+ * the key type (\c PSA_WANT_KEY_TYPE_xxx) and one for the algorithm
+ * (\c PSA_WANT_ALG_xxx). Mechanisms with additional parameters may involve
+ * additional symbols.
+ */
+#else
+/**
+ * When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in 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.
+ */
+#endif
+/*
+ *  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_CONFIG_H
+#define PSA_CRYPTO_CONFIG_H
+
+#define PSA_WANT_ALG_ECDSA                      1
+#define PSA_WANT_ALG_DETERMINISTIC_ECDSA        1
+
+#endif /* PSA_CRYPTO_CONFIG_H */
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index f6373b8..4dc8ad4 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -657,4 +657,91 @@
      PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
      0)
 
+/** The default nonce size for an AEAD algorithm, in bytes.
+ *
+ * This macro can be used to allocate a buffer of sufficient size to
+ * store the nonce output from #psa_aead_generate_nonce().
+ *
+ * See also #PSA_AEAD_NONCE_MAX_SIZE.
+ *
+ * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(),
+ *       #psa_aead_encrypt() or #psa_aead_decrypt(), just the default size that is generated by
+ *       #psa_aead_generate_nonce().
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ *          zero times, so you should not pass arguments that contain
+ *          side effects.
+ *
+ * \param key_type  A symmetric key type that is compatible with algorithm \p alg.
+ *
+ * \param alg       An AEAD algorithm (\c PSA_ALG_XXX value such that #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return The default nonce size for the specified key type and algorithm.
+ *         If the key type or AEAD algorithm is not recognized,
+ *         or the parameters are incompatible, return 0.
+ *         An implementation can return either 0 or a correct size for a key type
+ *         and AEAD algorithm that it recognizes, but does not support.
+ */
+#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \
+    (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) == 16 && \
+         (PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CCM || \
+          PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_GCM) ? 12 : \
+     (key_type) == PSA_KEY_TYPE_CHACHA20 && \
+          PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CHACHA20_POLY1305 ? 12 : \
+     0)
+
+/** The maximum default nonce size among all supported pairs of key types and AEAD algorithms, in bytes.
+ *
+ * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH() may return.
+ *
+ * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(),
+ *       #psa_aead_encrypt() or #psa_aead_decrypt(), just the largest size that may be generated by
+ *       #psa_aead_generate_nonce().
+ */
+#define PSA_AEAD_NONCE_MAX_SIZE 12
+
+/** The default IV size for a cipher algorithm, in bytes.
+ *
+ * The IV that is generated as part of a call to #psa_cipher_encrypt() is always
+ * the default IV length for the algorithm.
+ *
+ * This macro can be used to allocate a buffer of sufficient size to
+ * store the IV output from #psa_cipher_generate_iv() when using
+ * a multi-part cipher operation.
+ *
+ * See also #PSA_CIPHER_IV_MAX_SIZE.
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ *          zero times, so you should not pass arguments that contain
+ *          side effects.
+ *
+ * \param key_type  A symmetric key type that is compatible with algorithm \p alg.
+ *
+ * \param alg       A cipher algorithm (\c PSA_ALG_XXX value such that #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \return The default IV size for the specified key type and algorithm.
+ *         If the algorithm does not use an IV, return 0.
+ *         If the key type or cipher algorithm is not recognized,
+ *         or the parameters are incompatible, return 0.
+ *         An implementation can return either 0 or a correct size for a key type
+ *         and cipher algorithm that it recognizes, but does not support.
+ */
+#define PSA_CIPHER_IV_LENGTH(key_type, alg) \
+    (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) > 1 && \
+        ((alg) == PSA_ALG_CTR || \
+         (alg) == PSA_ALG_CFB || \
+         (alg) == PSA_ALG_OFB || \
+         (alg) == PSA_ALG_XTS || \
+         (alg) == PSA_ALG_CBC_NO_PADDING || \
+         (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
+     (key_type) == PSA_KEY_TYPE_CHACHA20 && \
+         (alg) == PSA_ALG_CHACHA20 ? 12 : \
+     0)
+
+/** The maximum IV size for all supported cipher algorithms, in bytes.
+ *
+ * See also #PSA_CIPHER_IV_LENGTH().
+ */
+#define PSA_CIPHER_IV_MAX_SIZE 16
+
 #endif /* PSA_CRYPTO_SIZES_H */
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 4444b98..8962555 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -150,46 +150,59 @@
     message(FATAL_ERROR "Need to choose static or shared mbedtls build!")
 endif(NOT USE_STATIC_MBEDTLS_LIBRARY AND NOT USE_SHARED_MBEDTLS_LIBRARY)
 
-set(target_libraries "mbedcrypto" "mbedx509" "mbedtls")
+set(mbedtls_target    "${MBEDTLS_TARGET_PREFIX}mbedtls")
+set(mbedx509_target   "${MBEDTLS_TARGET_PREFIX}mbedx509")
+set(mbedcrypto_target "${MBEDTLS_TARGET_PREFIX}mbedcrypto")
+
+set(mbedtls_target    ${mbedtls_target}    PARENT_SCOPE)
+set(mbedx509_target   ${mbedx509_target}   PARENT_SCOPE)
+set(mbedcrypto_target ${mbedcrypto_target} PARENT_SCOPE)
+
+if (USE_STATIC_MBEDTLS_LIBRARY)
+    set(mbedtls_static_target    ${mbedtls_target})
+    set(mbedx509_static_target   ${mbedx509_target})
+    set(mbedcrypto_static_target ${mbedcrypto_target})
+endif()
+
+set(target_libraries ${mbedcrypto_target} ${mbedx509_target} ${mbedtls_target})
 
 if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
-    set(mbedtls_static_target "mbedtls_static")
-    set(mbedx509_static_target "mbedx509_static")
-    set(mbedcrypto_static_target "mbedcrypto_static")
+    string(APPEND mbedtls_static_target    "_static")
+    string(APPEND mbedx509_static_target   "_static")
+    string(APPEND mbedcrypto_static_target "_static")
+
     list(APPEND target_libraries
-        "mbedcrypto_static" "mbedx509_static" "mbedtls_static")
-elseif(USE_STATIC_MBEDTLS_LIBRARY)
-    set(mbedtls_static_target "mbedtls")
-    set(mbedx509_static_target "mbedx509")
-    set(mbedcrypto_static_target "mbedcrypto")
+        ${mbedcrypto_static_target}
+        ${mbedx509_static_target}
+        ${mbedtls_static_target})
 endif()
 
 if(USE_STATIC_MBEDTLS_LIBRARY)
     add_library(${mbedcrypto_static_target} STATIC ${src_crypto})
     set_target_properties(${mbedcrypto_static_target} PROPERTIES OUTPUT_NAME mbedcrypto)
-    target_link_libraries(${mbedcrypto_static_target} ${libs})
+    target_link_libraries(${mbedcrypto_static_target} PUBLIC ${libs})
 
     add_library(${mbedx509_static_target} STATIC ${src_x509})
     set_target_properties(${mbedx509_static_target} PROPERTIES OUTPUT_NAME mbedx509)
-    target_link_libraries(${mbedx509_static_target} ${libs} ${mbedcrypto_static_target})
+    target_link_libraries(${mbedx509_static_target} PUBLIC ${libs} ${mbedcrypto_static_target})
 
     add_library(${mbedtls_static_target} STATIC ${src_tls})
     set_target_properties(${mbedtls_static_target} PROPERTIES OUTPUT_NAME mbedtls)
-    target_link_libraries(${mbedtls_static_target} ${libs} ${mbedx509_static_target})
+    target_link_libraries(${mbedtls_static_target} PUBLIC ${libs} ${mbedx509_static_target})
 endif(USE_STATIC_MBEDTLS_LIBRARY)
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
-    add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.24.0 SOVERSION 5)
-    target_link_libraries(mbedcrypto ${libs})
+    add_library(${mbedcrypto_target} SHARED ${src_crypto})
+    set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.24.0 SOVERSION 5)
+    target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
 
-    add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.24.0 SOVERSION 1)
-    target_link_libraries(mbedx509 ${libs} mbedcrypto)
+    add_library(${mbedx509_target} SHARED ${src_x509})
+    set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.24.0 SOVERSION 1)
+    target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
 
-    add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.24.0 SOVERSION 13)
-    target_link_libraries(mbedtls ${libs} mbedx509)
+    add_library(${mbedtls_target} SHARED ${src_tls})
+    set_target_properties(${mbedtls_target} PROPERTIES VERSION 2.24.0 SOVERSION 13)
+    target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
 endif(USE_SHARED_MBEDTLS_LIBRARY)
 
 foreach(target IN LISTS target_libraries)
@@ -210,7 +223,9 @@
             PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
 endforeach(target)
 
-add_custom_target(lib DEPENDS mbedcrypto mbedx509 mbedtls)
+set(lib_target "${MBEDTLS_TARGET_PREFIX}lib")
+
+add_custom_target(${lib_target} DEPENDS ${mbedcrypto_target} ${mbedx509_target} ${mbedtls_target})
 if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
-    add_dependencies(lib mbedcrypto_static mbedx509_static mbedtls_static)
+    add_dependencies(${lib_target} ${mbedcrypto_static_target} ${mbedx509_static_target} ${mbedtls_static_target})
 endif()
diff --git a/library/ccm.c b/library/ccm.c
index e6ca588..424ee77 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -175,7 +175,7 @@
     if( iv_len < 7 || iv_len > 13 )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
 
-    if( add_len > 0xFF00 )
+    if( add_len >= 0xFF00 )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
 
     q = 16 - 1 - (unsigned char) iv_len;
diff --git a/library/ecp.c b/library/ecp.c
index 5d00de5..05a0b01 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -546,9 +546,12 @@
 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
     { MBEDTLS_ECP_DP_SECP192K1,    18,     192,    "secp192k1"         },
 #endif
-#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
     { MBEDTLS_ECP_DP_CURVE25519,   29,     256,    "x25519"            },
 #endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+    { MBEDTLS_ECP_DP_CURVE448,     30,     448,    "x448"              },
+#endif
     { MBEDTLS_ECP_DP_NONE,          0,     0,      NULL                },
 };
 
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 4bf660e..5250a7b 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -17,7 +17,7 @@
  *  limitations under the License.
  */
 
-#if defined(__linux__)
+#if defined(__linux__) && !defined(_GNU_SOURCE)
 /* Ensure that syscall() is available even when compiling with -std=c99 */
 #define _GNU_SOURCE
 #endif
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 3f96cab..54c2b47 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -318,7 +318,7 @@
 
 #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) ||  \
     defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \
-    defined(socklen_t)
+    defined(socklen_t) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L)
     socklen_t n = (socklen_t) sizeof( client_addr );
     socklen_t type_len = (socklen_t) sizeof( type );
 #else
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 931e2e9..ab4e47a 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -199,7 +199,7 @@
         case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
             return( PSA_ERROR_INVALID_PADDING );
         case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
-            return( PSA_ERROR_BAD_STATE );
+            return( PSA_ERROR_INVALID_ARGUMENT );
         case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
             return( PSA_ERROR_INVALID_SIGNATURE );
         case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
@@ -739,7 +739,7 @@
          * - The byte 0x04;
          * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
          * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
-         * So its data length is 2m+1 where n is the key size in bits.
+         * So its data length is 2m+1 where m is the curve size in bits.
          */
         if( ( data_length & 1 ) == 0 )
             return( PSA_ERROR_INVALID_ARGUMENT );
@@ -969,14 +969,45 @@
     return( PSA_SUCCESS );
 }
 
-/** Import key data into a slot. `slot->attr.type` must have been set
- * previously. This function assumes that the slot does not contain
- * any key material yet. On failure, the slot content is unchanged. */
-psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
-                                       const uint8_t *data,
-                                       size_t data_length )
+psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
+                                              const uint8_t* data,
+                                              size_t data_length )
+{
+    psa_status_t status = psa_allocate_buffer_to_slot( slot,
+                                                       data_length );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    memcpy( slot->data.key.data, data, data_length );
+    return( PSA_SUCCESS );
+}
+
+/** Import key data into a slot.
+ *
+ * `slot->type` must have been set previously.
+ * This function assumes that the slot does not contain any key material yet.
+ * On failure, the slot content is unchanged.
+ *
+ * Persistent storage is not affected.
+ *
+ * \param[in,out] slot  The key slot to import data into.
+ *                      Its `type` field must have previously been set to
+ *                      the desired key type.
+ *                      It must not contain any key material yet.
+ * \param[in] data      Buffer containing the key material to parse and import.
+ * \param data_length   Size of \p data in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ */
+static psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
+                                              const uint8_t *data,
+                                              size_t data_length )
 {
     psa_status_t status = PSA_SUCCESS;
+    size_t bit_size;
 
     /* zero-length keys are never supported. */
     if( data_length == 0 )
@@ -984,7 +1015,7 @@
 
     if( key_type_is_raw_bytes( slot->attr.type ) )
     {
-        size_t bit_size = PSA_BYTES_TO_BITS( data_length );
+        bit_size = PSA_BYTES_TO_BITS( data_length );
 
         /* Ensure that the bytes-to-bits conversion hasn't overflown. */
         if( data_length > SIZE_MAX / 8 )
@@ -1000,47 +1031,65 @@
             return( status );
 
         /* Allocate memory for the key */
-        status = psa_allocate_buffer_to_slot( slot, data_length );
+        status = psa_copy_key_material_into_slot( slot, data, data_length );
         if( status != PSA_SUCCESS )
             return( status );
 
-        /* copy key into allocated buffer */
-        memcpy( slot->data.key.data, data, data_length );
-
         /* Write the actual key size to the slot.
          * psa_start_key_creation() wrote the size declared by the
          * caller, which may be 0 (meaning unspecified) or wrong. */
         slot->attr.bits = (psa_key_bits_t) bit_size;
+
+        return( PSA_SUCCESS );
     }
-    else if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
+    else if( PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
     {
+        /* Try validation through accelerators first. */
+        bit_size = slot->attr.bits;
+        psa_key_attributes_t attributes = {
+          .core = slot->attr
+        };
+        status = psa_driver_wrapper_validate_key( &attributes,
+                                                  data,
+                                                  data_length,
+                                                  &bit_size );
+        if( status == PSA_SUCCESS )
+        {
+            /* Key has been validated successfully by an accelerator.
+             * Copy key material into slot. */
+            status = psa_copy_key_material_into_slot( slot, data, data_length );
+            if( status != PSA_SUCCESS )
+                return( status );
+
+            slot->attr.bits = (psa_key_bits_t) bit_size;
+            return( PSA_SUCCESS );
+        }
+        else if( status != PSA_ERROR_NOT_SUPPORTED )
+            return( status );
+
+        /* Key format is not supported by any accelerator, try software fallback
+         * if present. */
 #if defined(MBEDTLS_ECP_C)
-        status = psa_import_ecp_key( slot,
-                                     data, data_length );
-#else
-        /* No drivers have been implemented yet, so without mbed TLS backing
-         * there's no way to do ECP with the current library. */
-        return( PSA_ERROR_NOT_SUPPORTED );
+        if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
+        {
+            return( psa_import_ecp_key( slot, data, data_length ) );
+        }
 #endif /* defined(MBEDTLS_ECP_C) */
-    }
-    else if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
-    {
 #if defined(MBEDTLS_RSA_C)
-        status = psa_import_rsa_key( slot,
-                                     data, data_length );
-#else
-        /* No drivers have been implemented yet, so without mbed TLS backing
-         * there's no way to do RSA with the current library. */
-        status = PSA_ERROR_NOT_SUPPORTED;
+        if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
+        {
+            return( psa_import_rsa_key( slot, data, data_length ) );
+        }
 #endif /* defined(MBEDTLS_RSA_C) */
+
+        /* Fell through the fallback as well, so have nothing else to try. */
+        return( PSA_ERROR_NOT_SUPPORTED );
     }
     else
     {
         /* Unknown key type */
         return( PSA_ERROR_NOT_SUPPORTED );
     }
-
-    return( status );
 }
 
 /** Calculate the intersection of two algorithm usage policies.
@@ -1084,6 +1133,15 @@
         return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
                 ( requested_alg & ~PSA_ALG_HASH_MASK ) );
     }
+    /* If policy_alg is a generic key agreement operation, then using it for
+     * a key derivation with that key agreement should also be allowed. This
+     * behaviour is expected to be defined in a future specification version. */
+    if( PSA_ALG_IS_RAW_KEY_AGREEMENT( policy_alg ) &&
+        PSA_ALG_IS_KEY_AGREEMENT( requested_alg ) )
+    {
+        return( PSA_ALG_KEY_AGREEMENT_GET_BASE( requested_alg ) ==
+                policy_alg );
+    }
     /* If it isn't permitted, it's forbidden. */
     return( 0 );
 }
@@ -1897,13 +1955,9 @@
             static_assert( sizeof( slot->data.se.slot_number ) ==
                            sizeof( data.slot_number ),
                            "Slot number size does not match psa_se_key_data_storage_t" );
-            static_assert( sizeof( slot->attr.bits ) == sizeof( data.bits ),
-                           "Bit-size size does not match psa_se_key_data_storage_t" );
 #endif
             memcpy( &data.slot_number, &slot->data.se.slot_number,
                     sizeof( slot->data.se.slot_number ) );
-            memcpy( &data.bits, &slot->attr.bits,
-                    sizeof( slot->attr.bits ) );
             status = psa_save_persistent_key( &slot->attr,
                                               (uint8_t*) &data,
                                               sizeof( data ) );
@@ -1911,22 +1965,11 @@
         else
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
         {
-            size_t buffer_size =
-                PSA_KEY_EXPORT_MAX_SIZE( slot->attr.type,
-                                         slot->attr.bits );
-            uint8_t *buffer = mbedtls_calloc( 1, buffer_size );
-            size_t length = 0;
-            if( buffer == NULL )
-                return( PSA_ERROR_INSUFFICIENT_MEMORY );
-            status = psa_internal_export_key( slot,
-                                              buffer, buffer_size, &length,
-                                              0 );
-            if( status == PSA_SUCCESS )
-                status = psa_save_persistent_key( &slot->attr,
-                                                  buffer, length );
-
-            mbedtls_platform_zeroize( buffer, buffer_size );
-            mbedtls_free( buffer );
+            /* Key material is saved in export representation in the slot, so
+             * just pass the slot buffer for storage. */
+            status = psa_save_persistent_key( &slot->attr,
+                                              slot->data.key.data,
+                                              slot->data.key.bytes );
         }
     }
 #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
@@ -2174,26 +2217,16 @@
 static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
                                            psa_key_slot_t *target )
 {
-    psa_status_t status;
-    uint8_t *buffer = NULL;
-    size_t buffer_size = 0;
-    size_t length;
-
-    buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->attr.type,
-                                           psa_get_key_slot_bits( source ) );
-    buffer = mbedtls_calloc( 1, buffer_size );
-    if( buffer == NULL )
-        return( PSA_ERROR_INSUFFICIENT_MEMORY );
-    status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 );
+    psa_status_t status = psa_copy_key_material_into_slot( target,
+                                                           source->data.key.data,
+                                                           source->data.key.bytes );
     if( status != PSA_SUCCESS )
-        goto exit;
-    target->attr.type = source->attr.type;
-    status = psa_import_key_into_slot( target, buffer, length );
+        return( status );
 
-exit:
-    mbedtls_platform_zeroize( buffer, buffer_size );
-    mbedtls_free( buffer );
-    return( status );
+    target->attr.type = source->attr.type;
+    target->attr.bits = source->attr.bits;
+
+    return( PSA_SUCCESS );
 }
 
 psa_status_t psa_copy_key( psa_key_handle_t source_handle,
@@ -2256,7 +2289,7 @@
 /* Message digests */
 /****************************************************************/
 
-#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_DETERMINISTIC)
+#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
 static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
 {
     switch( alg )
@@ -2299,7 +2332,7 @@
             return( NULL );
     }
 }
-#endif
+#endif /* defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
 
 psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
 {
@@ -3530,7 +3563,7 @@
 }
 #endif /* MBEDTLS_RSA_C */
 
-#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
 /* `ecp` cannot be const because `ecp->grp` needs to be non-const
  * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
  * (even though these functions don't modify it). */
@@ -3554,7 +3587,7 @@
         goto cleanup;
     }
 
-#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
     if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
     {
         psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
@@ -3567,7 +3600,7 @@
                                                      &global_data.ctr_drbg ) );
     }
     else
-#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
     {
         (void) alg;
         MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
@@ -3629,7 +3662,7 @@
     mbedtls_mpi_free( &s );
     return( mbedtls_to_psa_error( ret ) );
 }
-#endif /* MBEDTLS_ECDSA_C */
+#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA */
 
 psa_status_t psa_sign_hash( psa_key_handle_t handle,
                             psa_algorithm_t alg,
@@ -3698,9 +3731,9 @@
 #if defined(MBEDTLS_ECP_C)
     if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
     {
-#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA)
         if(
-#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
             PSA_ALG_IS_ECDSA( alg )
 #else
             PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
@@ -3723,7 +3756,7 @@
             mbedtls_free( ecp );
         }
         else
-#endif /* defined(MBEDTLS_ECDSA_C) */
+#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) */
         {
             status = PSA_ERROR_INVALID_ARGUMENT;
         }
@@ -3799,7 +3832,7 @@
 #if defined(MBEDTLS_ECP_C)
     if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) )
     {
-#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
         if( PSA_ALG_IS_ECDSA( alg ) )
         {
             mbedtls_ecp_keypair *ecp = NULL;
@@ -3817,7 +3850,7 @@
             return( status );
         }
         else
-#endif /* defined(MBEDTLS_ECDSA_C) */
+#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
         {
             return( PSA_ERROR_INVALID_ARGUMENT );
         }
@@ -4473,8 +4506,7 @@
     if( operation->ctx.cipher.unprocessed_len != 0 )
     {
         if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
-            ( operation->alg == PSA_ALG_CBC_NO_PADDING &&
-              operation->ctx.cipher.operation == MBEDTLS_ENCRYPT ) )
+            operation->alg == PSA_ALG_CBC_NO_PADDING )
         {
             status = PSA_ERROR_INVALID_ARGUMENT;
             goto exit;
@@ -5868,7 +5900,6 @@
                                                 PSA_KEY_TYPE_DERIVE,
                                                 shared_secret,
                                                 shared_secret_length );
-
 exit:
     mbedtls_platform_zeroize( shared_secret, shared_secret_length );
     return( status );
@@ -5893,6 +5924,13 @@
                                          peer_key, peer_key_length );
     if( status != PSA_SUCCESS )
         psa_key_derivation_abort( operation );
+    else
+    {
+        /* If a private key has been added as SECRET, we allow the derived
+         * key material to be used as a key in PSA Crypto. */
+        if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
+            operation->can_output_key = 1;
+    }
     return( status );
 }
 
@@ -6110,8 +6148,6 @@
             return( PSA_ERROR_NOT_SUPPORTED );
         if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
             return( PSA_ERROR_NOT_SUPPORTED );
-        if( curve_info->bit_size != bits )
-            return( PSA_ERROR_INVALID_ARGUMENT );
         mbedtls_ecp_keypair_init( &ecp );
         ret = mbedtls_ecp_gen_key( grp_id, &ecp,
                                    mbedtls_ctr_drbg_random,
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index 6ee17fc..8d1f1bb 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -137,30 +137,26 @@
  */
 psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot );
 
-/** Import key data into a slot.
+/** Copy key data (in export format) into an empty key slot.
  *
- * `slot->type` must have been set previously.
- * This function assumes that the slot does not contain any key material yet.
- * On failure, the slot content is unchanged.
+ * This function assumes that the slot does not contain
+ * any key material yet. On failure, the slot content is unchanged.
  *
- * Persistent storage is not affected.
+ * \param[in,out] slot          Key slot to copy the key into.
+ * \param[in] data              Buffer containing the key material.
+ * \param data_length           Size of the key buffer.
  *
- * \param[in,out] slot  The key slot to import data into.
- *                      Its `type` field must have previously been set to
- *                      the desired key type.
- *                      It must not contain any key material yet.
- * \param[in] data      Buffer containing the key material to parse and import.
- * \param data_length   Size of \p data in bytes.
- *
- * \retval PSA_SUCCESS
- * \retval PSA_ERROR_INVALID_ARGUMENT
- * \retval PSA_ERROR_NOT_SUPPORTED
- * \retval PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_SUCCESS
+ *         The key has been copied successfully.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ *         Not enough memory was available for allocation of the
+ *         copy buffer.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ *         There was other key material already present in the slot.
  */
-psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
-                                       const uint8_t *data,
-                                       size_t data_length );
-
+psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
+                                              const uint8_t *data,
+                                              size_t data_length );
 
 /** Convert an mbed TLS error code to a PSA error code
  *
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index d41209b..4040b36 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -256,26 +256,60 @@
                                            size_t *expected_size )
 {
     size_t buffer_size = 0;
-    if( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) == PSA_KEY_LOCATION_LOCAL_STORAGE )
-    {
-        buffer_size = PSA_KEY_EXPORT_MAX_SIZE( attributes->core.type,
-                                               attributes->core.bits );
+    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+    psa_key_type_t key_type = attributes->core.type;
+    size_t key_bits = attributes->core.bits;
 
-        if( buffer_size == 0 )
+    switch( location )
+    {
+        case PSA_KEY_LOCATION_LOCAL_STORAGE:
+            buffer_size = PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits );
+
+            if( buffer_size == 0 )
+                return( PSA_ERROR_NOT_SUPPORTED );
+
+            *expected_size = buffer_size;
+            return( PSA_SUCCESS );
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TEST_DRIVER_LIFETIME:
+#ifdef TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION
+            *expected_size = test_size_function( key_type, key_bits );
+            return( PSA_SUCCESS );
+#else /* TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION */
+            if( PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) )
+            {
+                int public_key_overhead = ( ( TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY == 1 ) ?
+                                           PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits ) : 0 );
+                *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
+                                 + TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE
+                                 + public_key_overhead;
+            }
+            else if( PSA_KEY_TYPE_IS_PUBLIC_KEY( attributes->core.type ) )
+            {
+                *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
+                                 + TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE;
+            }
+            else if ( !PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) &&
+                      !PSA_KEY_TYPE_IS_PUBLIC_KEY ( attributes->core.type ) )
+            {
+                *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
+                                 + TEST_DRIVER_KEY_CONTEXT_SYMMETRIC_FACTOR
+                                 * ( ( key_bits + 7 ) / 8 );
+            }
+            else
+            {
+                return( PSA_ERROR_NOT_SUPPORTED );
+            }
+            return( PSA_SUCCESS );
+#endif /* TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION */
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+
+        default:
             return( PSA_ERROR_NOT_SUPPORTED );
-
-        *expected_size = buffer_size;
-        return( PSA_SUCCESS );
-    }
-    else
-    {
-        /* TBD: opaque driver support: need to calculate size through a
-         * driver-defined size function, since the size of an opaque (wrapped)
-         * key will be different for each implementation. */
-        return( PSA_ERROR_NOT_SUPPORTED );
     }
 }
-#endif /* PSA_CRYPTO_DRIVER_PRESENT */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
 
 psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
                                               psa_key_slot_t *slot )
@@ -376,6 +410,34 @@
 #endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
+psa_status_t psa_driver_wrapper_validate_key( const psa_key_attributes_t *attributes,
+                                              const uint8_t *data,
+                                              size_t data_length,
+                                              size_t *bits )
+{
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    /* Try accelerators in turn */
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+    status = test_transparent_validate_key( attributes,
+                                            data,
+                                            data_length,
+                                            bits );
+    /* Declared with fallback == true */
+    if( status != PSA_ERROR_NOT_SUPPORTED )
+        return( status );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+
+    return( PSA_ERROR_NOT_SUPPORTED );
+#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+    (void) attributes;
+    (void) data;
+    (void) data_length;
+    (void) bits;
+    return( PSA_ERROR_NOT_SUPPORTED );
+#endif /* PSA_CRYPTO_DRIVER_PRESENT */
+}
+
 /*
  * Cipher functions
  */
@@ -583,7 +645,7 @@
 #endif /* PSA_CRYPTO_DRIVER_TEST */
         default:
             /* Key is declared with a lifetime not known to us */
-            return( PSA_ERROR_BAD_STATE );
+            return( PSA_ERROR_NOT_SUPPORTED );
     }
 #else /* PSA_CRYPTO_DRIVER_PRESENT */
     (void)slot;
@@ -664,7 +726,7 @@
 #endif /* PSA_CRYPTO_DRIVER_TEST */
         default:
             /* Key is declared with a lifetime not known to us */
-            return( PSA_ERROR_BAD_STATE );
+            return( PSA_ERROR_NOT_SUPPORTED );
     }
 #else /* PSA_CRYPTO_DRIVER_PRESENT */
     (void)slot;
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index 0db15d6..b0b483b 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -43,9 +43,18 @@
                                              const uint8_t *signature,
                                              size_t signature_length );
 
+/*
+ * Key handling functions
+ */
+
 psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
                                               psa_key_slot_t *slot );
 
+psa_status_t psa_driver_wrapper_validate_key( const psa_key_attributes_t *attributes,
+                                              const uint8_t *data,
+                                              size_t data_length,
+                                              size_t *bits );
+
 /*
  * Cipher functions
  */
diff --git a/library/psa_crypto_its.h b/library/psa_crypto_its.h
index 93c4ce9..b671d63 100644
--- a/library/psa_crypto_its.h
+++ b/library/psa_crypto_its.h
@@ -142,4 +142,8 @@
  */
 psa_status_t psa_its_remove(psa_storage_uid_t uid);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* PSA_CRYPTO_ITS_H */
diff --git a/library/psa_crypto_se.h b/library/psa_crypto_se.h
index 5691738..67fadf8 100644
--- a/library/psa_crypto_se.h
+++ b/library/psa_crypto_se.h
@@ -182,7 +182,6 @@
 typedef struct
 {
     uint8_t slot_number[sizeof( psa_key_slot_number_t )];
-    uint8_t bits[sizeof( psa_key_bits_t )];
 } psa_se_key_data_storage_t;
 
 #endif /* PSA_CRYPTO_SE_H */
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index e526560..5140772 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -137,13 +137,13 @@
         data = (psa_se_key_data_storage_t *) key_data;
         memcpy( &slot->data.se.slot_number, &data->slot_number,
                 sizeof( slot->data.se.slot_number ) );
-        memcpy( &slot->attr.bits, &data->bits,
-                sizeof( slot->attr.bits ) );
     }
     else
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
     {
-        status = psa_import_key_into_slot( slot, key_data, key_data_length );
+        status = psa_copy_key_material_into_slot( slot, key_data, key_data_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
     }
 
 exit:
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index 46d0b65..2ab5903 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -253,6 +253,25 @@
 }
 #endif
 
+/*
+ * 16-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT16_LE
+#define GET_UINT16_LE( n, b, i )                        \
+{                                                       \
+    (n) = ( (uint16_t) (b)[(i)    ]       )             \
+        | ( (uint16_t) (b)[(i) + 1] <<  8 );            \
+}
+#endif
+
+#ifndef PUT_UINT16_LE
+#define PUT_UINT16_LE( n, b, i )                                \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+}
+#endif
+
 /**
  * Persistent key storage magic header.
  */
@@ -263,9 +282,8 @@
     uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
     uint8_t version[4];
     uint8_t lifetime[sizeof( psa_key_lifetime_t )];
-    uint8_t type[4]; /* Size=4 for a 2-byte type to keep the structure more
-                      * regular and aligned and to make potential future
-                      * extensibility easier. */
+    uint8_t type[2];
+    uint8_t bits[2];
     uint8_t policy[sizeof( psa_key_policy_t )];
     uint8_t data_len[4];
     uint8_t key_data[];
@@ -282,7 +300,8 @@
     memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
     PUT_UINT32_LE( 0, storage_format->version, 0 );
     PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
-    PUT_UINT32_LE( (uint32_t) attr->type, storage_format->type, 0 );
+    PUT_UINT16_LE( (uint16_t) attr->type, storage_format->type, 0 );
+    PUT_UINT16_LE( (uint16_t) attr->bits, storage_format->bits, 0 );
     PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
     PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
     PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
@@ -308,7 +327,6 @@
     const psa_persistent_key_storage_format *storage_format =
         (const psa_persistent_key_storage_format *)storage_data;
     uint32_t version;
-    uint32_t type;
 
     if( storage_data_length < sizeof(*storage_format) )
         return( PSA_ERROR_STORAGE_FAILURE );
@@ -339,11 +357,8 @@
     }
 
     GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
-    GET_UINT32_LE( type, storage_format->type, 0 );
-    if( type <= (psa_key_type_t) -1 )
-        attr->type = (psa_key_type_t) type;
-    else
-        return( PSA_ERROR_STORAGE_FAILURE );
+    GET_UINT16_LE( attr->type, storage_format->type, 0 );
+    GET_UINT16_LE( attr->bits, storage_format->bits, 0 );
     GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
     GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
     GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h
index de845a7..3def1b5 100644
--- a/library/psa_crypto_storage.h
+++ b/library/psa_crypto_storage.h
@@ -81,9 +81,10 @@
  * This function formats the key data and metadata and saves it to a
  * persistent storage backend. The storage location corresponding to the
  * key slot must be empty, otherwise this function will fail. This function
- * should be called after psa_import_key_into_slot() to ensure the
+ * should be called after loading the key into an internal slot to ensure the
  * persistent key is not saved into a storage location corresponding to an
- * already occupied non-persistent key, as well as validating the key data.
+ * already occupied non-persistent key, as well as ensuring the key data is
+ * validated.
  *
  *
  * \param[in] attr          The attributes of the key to save.
diff --git a/library/rsa.c b/library/rsa.c
index 84d87de..d6abd65 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -811,15 +811,14 @@
          * which one, we just loop and choose new values for both of them.
          * (Each iteration succeeds with overwhelming probability.) */
         ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
-        if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
-            continue;
-        if( ret != 0 )
+        if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
             goto cleanup;
 
-        /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
-    } while( 0 );
+    } while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+
+    /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
 
     /* Blinding value: Vi = Vf^(-e) mod N
      * (Vi already contains Vf^-1 at this point) */
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 083b720..76be8ab 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -756,6 +756,126 @@
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+                                   unsigned char *buf,
+                                   const unsigned char *end,
+                                   size_t *olen )
+{
+    unsigned char *p = buf;
+    size_t protection_profiles_index = 0, ext_len = 0;
+    uint16_t mki_len = 0, profile_value = 0;
+
+    *olen = 0;
+
+    if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+        ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+        ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+    {
+        return( 0 );
+    }
+
+    /* RFC 5764 section 4.1.1
+     * uint8 SRTPProtectionProfile[2];
+     *
+     * struct {
+     *   SRTPProtectionProfiles SRTPProtectionProfiles;
+     *   opaque srtp_mki<0..255>;
+     * } UseSRTPData;
+     * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+     */
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+    {
+        mki_len = ssl->dtls_srtp_info.mki_len;
+    }
+    /* Extension length = 2 bytes for profiles length,
+     *                    ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ),
+     *                    1 byte for srtp_mki vector length and the mki_len value
+     */
+    ext_len = 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding use_srtp extension" ) );
+
+    /* Check there is room in the buffer for the extension + 4 bytes
+     * - the extension tag (2 bytes)
+     * - the extension length (2 bytes)
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, ext_len + 4 );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
+
+
+    *p++ = (unsigned char)( ( ( ext_len & 0xFF00 ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ext_len & 0xFF );
+
+    /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
+    /* micro-optimization:
+     * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH
+     * which is lower than 127, so the upper byte of the length is always 0
+     * For the documentation, the more generic code is left in comments
+     * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
+     *                        >> 8 ) & 0xFF );
+     */
+    *p++ = 0;
+    *p++ = (unsigned char)( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
+                            & 0xFF );
+
+    for( protection_profiles_index=0;
+         protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
+         protection_profiles_index++ )
+    {
+        profile_value = mbedtls_ssl_check_srtp_profile_value
+                ( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] );
+        if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
+                                        profile_value ) );
+            *p++ = ( ( profile_value >> 8 ) & 0xFF );
+            *p++ = ( profile_value & 0xFF );
+        }
+        else
+        {
+            /*
+             * Note: we shall never arrive here as protection profiles
+             * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function
+             */
+            MBEDTLS_SSL_DEBUG_MSG( 3,
+                    ( "client hello, "
+                      "illegal DTLS-SRTP protection profile %d",
+                      ssl->conf->dtls_srtp_profile_list[protection_profiles_index]
+                    ) );
+            return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
+        }
+    }
+
+    *p++ = mki_len & 0xFF;
+
+    if( mki_len != 0 )
+    {
+        memcpy( p, ssl->dtls_srtp_info.mki_value, mki_len );
+        /*
+         * Increment p to point to the current position.
+         */
+        p += mki_len;
+        MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki",  ssl->dtls_srtp_info.mki_value,
+                               ssl->dtls_srtp_info.mki_len );
+    }
+
+    /*
+     * total extension length: extension type (2 bytes)
+     *                         + extension length (2 bytes)
+     *                         + protection profile length (2 bytes)
+     *                         + 2 * number of protection profiles
+     *                         + srtp_mki vector length(1 byte)
+     *                         + mki value
+     */
+    *olen = p - buf;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 /*
  * Generate random bytes for ClientHello
  */
@@ -1277,6 +1397,16 @@
     ext_len += olen;
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len,
+                                        end, &olen ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret );
+        return( ret );
+    }
+    ext_len += olen;
+#endif
+
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
     if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len,
                                               end, &olen ) ) != 0 )
@@ -1710,6 +1840,123 @@
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
+                                   const unsigned char *buf,
+                                   size_t len )
+{
+    mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET;
+    size_t i, mki_len = 0;
+    uint16_t server_protection_profile_value = 0;
+
+    /* If use_srtp is not configured, just ignore the extension */
+    if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+        ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+        ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+        return( 0 );
+
+    /* RFC 5764 section 4.1.1
+     * uint8 SRTPProtectionProfile[2];
+     *
+     * struct {
+     *   SRTPProtectionProfiles SRTPProtectionProfiles;
+     *   opaque srtp_mki<0..255>;
+     * } UseSRTPData;
+
+     * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+     *
+     */
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+    {
+        mki_len = ssl->dtls_srtp_info.mki_len;
+    }
+
+    /*
+     * Length is 5 + optional mki_value : one protection profile length (2 bytes)
+     *                                      + protection profile (2 bytes)
+     *                                      + mki_len(1 byte)
+     *                                      and optional srtp_mki
+     */
+    if( ( len < 5 ) || ( len != ( buf[4] + 5u ) ) )
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+
+    /*
+     * get the server protection profile
+     */
+
+    /*
+     * protection profile length must be 0x0002 as we must have only
+     * one protection profile in server Hello
+     */
+    if( (  buf[0] != 0 ) || ( buf[1] != 2 ) )
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+
+    server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
+    server_protection = mbedtls_ssl_check_srtp_profile_value(
+                    server_protection_profile_value );
+    if( server_protection != MBEDTLS_TLS_SRTP_UNSET )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s",
+                                      mbedtls_ssl_get_srtp_profile_as_string(
+                                              server_protection ) ) );
+    }
+
+    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
+
+    /*
+     * Check we have the server profile in our list
+     */
+    for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
+    {
+        if( server_protection == ssl->conf->dtls_srtp_profile_list[i] )
+        {
+            ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
+                                      mbedtls_ssl_get_srtp_profile_as_string(
+                                              server_protection ) ) );
+            break;
+        }
+    }
+
+    /* If no match was found : server problem, it shall never answer with incompatible profile */
+    if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+    {
+        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 );
+    }
+
+    /* If server does not use mki in its reply, make sure the client won't keep
+     * one as negotiated */
+    if( len == 5 )
+    {
+        ssl->dtls_srtp_info.mki_len = 0;
+    }
+
+    /*
+     * RFC5764:
+     *  If the client detects a nonzero-length MKI in the server's response
+     *  that is different than the one the client offered, then the client
+     *  MUST abort the handshake and SHOULD send an invalid_parameter alert.
+     */
+    if( len > 5  && ( buf[4] != mki_len ||
+        ( memcmp( ssl->dtls_srtp_info.mki_value, &buf[5], mki_len ) ) ) )
+    {
+        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 );
+    }
+#if defined (MBEDTLS_DEBUG_C)
+    if( len > 5 )
+    {
+        MBEDTLS_SSL_DEBUG_BUF( 3, "received mki", ssl->dtls_srtp_info.mki_value,
+                                                  ssl->dtls_srtp_info.mki_len );
+    }
+#endif
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 /*
  * Parse HelloVerifyRequest.  Only called after verifying the HS type.
  */
@@ -2278,6 +2525,16 @@
             break;
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+        case MBEDTLS_TLS_EXT_USE_SRTP:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+
+            if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 )
+                return( ret );
+
+            break;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
         default:
             MBEDTLS_SSL_DEBUG_MSG( 3,
                 ( "unknown extension found: %d (ignoring)", ext_id ) );
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 2ea3580..bdf882d 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -1045,21 +1045,86 @@
 
 #if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
 /*
- * Constant-flow conditional memcpy:
- *  - if c1 == c2, equivalent to memcpy(dst, src, len),
- *  - otherwise, a no-op,
- * but with execution flow independent of the values of c1 and c2.
+ * Turn a bit into a mask:
+ * - if bit == 1, return the all-bits 1 mask, aka (size_t) -1
+ * - if bit == 0, return the all-bits 0 mask, aka 0
  *
- * Use only bit operations to avoid branches that could be used by some
- * compilers on some platforms to translate comparison operators.
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * This function is implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
  */
-static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst,
-                                         const unsigned char *src,
-                                         size_t len,
-                                         size_t c1, size_t c2 )
+static size_t mbedtls_ssl_cf_mask_from_bit( size_t bit )
 {
-    /* diff = 0 if c1 == c2, non-zero otherwise */
-    const size_t diff = c1 ^ c2;
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return -bit;
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+/*
+ * Constant-flow mask generation for "less than" comparison:
+ * - if x < y,  return all bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * This function is implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+static size_t mbedtls_ssl_cf_mask_lt( size_t x, size_t y )
+{
+    /* This has the most significant bit set if and only if x < y */
+    const size_t sub = x - y;
+
+    /* sub1 = (x < y) ? 1 : 0 */
+    const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 );
+
+    /* mask = (x < y) ? 0xff... : 0x00... */
+    const size_t mask = mbedtls_ssl_cf_mask_from_bit( sub1 );
+
+    return( mask );
+}
+
+/*
+ * Constant-flow mask generation for "greater or equal" comparison:
+ * - if x >= y, return all bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * This function is implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+static size_t mbedtls_ssl_cf_mask_ge( size_t x, size_t y )
+{
+    return( ~mbedtls_ssl_cf_mask_lt( x, y ) );
+}
+
+/*
+ * Constant-flow boolean "equal" comparison:
+ * return x == y
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations - it can be used in conjunction with
+ * mbedtls_ssl_cf_mask_from_bit().
+ *
+ * This function is implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+static size_t mbedtls_ssl_cf_bool_eq( size_t x, size_t y )
+{
+    /* diff = 0 if x == y, non-zero otherwise */
+    const size_t diff = x ^ y;
 
     /* MSVC has a warning about unary minus on unsigned integer types,
      * but this is well-defined and precisely what we want to do here. */
@@ -1068,22 +1133,40 @@
 #pragma warning( disable : 4146 )
 #endif
 
-    /* diff_msb's most significant bit is equal to c1 != c2 */
+    /* diff_msb's most significant bit is equal to x != y */
     const size_t diff_msb = ( diff | -diff );
 
-    /* diff1 = c1 != c2 */
-    const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
-
-    /* mask = c1 != c2 ? 0xff : 0x00 */
-    const unsigned char mask = (unsigned char) -diff1;
-
 #if defined(_MSC_VER)
 #pragma warning( pop )
 #endif
 
-    /* dst[i] = c1 != c2 ? dst[i] : src[i] */
+    /* diff1 = (x != y) ? 1 : 0 */
+    const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
+
+    return( 1 ^ diff1 );
+}
+
+/*
+ * Constant-flow conditional memcpy:
+ *  - if c1 == c2, equivalent to memcpy(dst, src, len),
+ *  - otherwise, a no-op,
+ * but with execution flow independent of the values of c1 and c2.
+ *
+ * This function is implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst,
+                                         const unsigned char *src,
+                                         size_t len,
+                                         size_t c1, size_t c2 )
+{
+    /* mask = c1 == c2 ? 0xff : 0x00 */
+    const size_t equal = mbedtls_ssl_cf_bool_eq( c1, c2 );
+    const unsigned char mask = (unsigned char) mbedtls_ssl_cf_mask_from_bit( equal );
+
+    /* dst[i] = c1 == c2 ? src[i] : dst[i] */
     for( size_t i = 0; i < len; i++ )
-        dst[i] = ( dst[i] & mask ) | ( src[i] & ~mask );
+        dst[i] = ( src[i] & mask ) | ( dst[i] & ~mask );
 }
 
 /*
@@ -1528,8 +1611,11 @@
 
         if( auth_done == 1 )
         {
-            correct *= ( rec->data_len >= padlen + 1 );
-            padlen  *= ( rec->data_len >= padlen + 1 );
+            const size_t mask = mbedtls_ssl_cf_mask_ge(
+                                rec->data_len,
+                                padlen + 1 );
+            correct &= mask;
+            padlen  &= mask;
         }
         else
         {
@@ -1543,8 +1629,11 @@
             }
 #endif
 
-            correct *= ( rec->data_len >= transform->maclen + padlen + 1 );
-            padlen  *= ( rec->data_len >= transform->maclen + padlen + 1 );
+            const size_t mask = mbedtls_ssl_cf_mask_ge(
+                                rec->data_len,
+                                transform->maclen + padlen + 1 );
+            correct &= mask;
+            padlen  &= mask;
         }
 
         padlen++;
@@ -1555,6 +1644,10 @@
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
         if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
         {
+            /* This is the SSL 3.0 path, we don't have to worry about Lucky
+             * 13, because there's a strictly worse padding attack built in
+             * the protocol (known as part of POODLE), so we don't care if the
+             * code is not constant-time, in particular branches are OK. */
             if( padlen > transform->ivlen )
             {
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
@@ -1578,7 +1671,6 @@
              * `min(256,plaintext_len)` reads (but take into account
              * only the last `padlen` bytes for the padding check). */
             size_t pad_count = 0;
-            size_t real_count = 0;
             volatile unsigned char* const check = data;
 
             /* Index of first padding byte; it has been ensured above
@@ -1590,16 +1682,21 @@
 
             for( idx = start_idx; idx < rec->data_len; idx++ )
             {
-                real_count |= ( idx >= padding_idx );
-                pad_count += real_count * ( check[idx] == padlen - 1 );
+                /* pad_count += (idx >= padding_idx) &&
+                 *              (check[idx] == padlen - 1);
+                 */
+                const size_t mask = mbedtls_ssl_cf_mask_ge( idx, padding_idx );
+                const size_t equal = mbedtls_ssl_cf_bool_eq( check[idx],
+                                                             padlen - 1 );
+                pad_count += mask & equal;
             }
-            correct &= ( pad_count == padlen );
+            correct &= mbedtls_ssl_cf_bool_eq( pad_count, padlen );
 
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
             if( padlen > 0 && correct == 0 )
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
 #endif
-            padlen &= correct * 0x1FF;
+            padlen &= mbedtls_ssl_cf_mask_from_bit( correct );
         }
         else
 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
@@ -1921,14 +2018,6 @@
     {
         uint32_t timeout;
 
-        /* Just to be sure */
-        if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
-                        "mbedtls_ssl_set_timer_cb() for DTLS" ) );
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-        }
-
         /*
          * The point is, we need to always read a full datagram at once, so we
          * sometimes read more then requested, and handle the additional data.
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 2e63fce..070a591 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -776,6 +776,126 @@
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
+                                   const unsigned char *buf,
+                                   size_t len )
+{
+    mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET;
+    size_t i,j;
+    size_t profile_length;
+    uint16_t mki_length;
+    /*! 2 bytes for profile length and 1 byte for mki len */
+    const size_t size_of_lengths = 3;
+
+    /* If use_srtp is not configured, just ignore the extension */
+    if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+        ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+        ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+    {
+        return( 0 );
+    }
+
+    /* RFC5764 section 4.1.1
+     * uint8 SRTPProtectionProfile[2];
+     *
+     * struct {
+     *   SRTPProtectionProfiles SRTPProtectionProfiles;
+     *   opaque srtp_mki<0..255>;
+     * } UseSRTPData;
+
+     * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+     */
+
+    /*
+     * Min length is 5: at least one protection profile(2 bytes)
+     *                  and length(2 bytes) + srtp_mki length(1 byte)
+     * Check here that we have at least 2 bytes of protection profiles length
+     * and one of srtp_mki length
+     */
+    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 );
+    }
+
+   ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
+
+    /* first 2 bytes are protection profile length(in bytes) */
+    profile_length = ( buf[0] << 8 ) | buf[1];
+    buf += 2;
+
+    /* The profile length cannot be bigger than input buffer size - lengths fields */
+    if( profile_length > len - size_of_lengths ||
+        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 );
+    }
+    /*
+     * parse the extension list values are defined in
+     * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+     */
+    for( j = 0; j < profile_length; j += 2 )
+    {
+        uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1];
+        client_protection = mbedtls_ssl_check_srtp_profile_value( protection_profile_value );
+
+        if( client_protection != MBEDTLS_TLS_SRTP_UNSET )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s",
+                                    mbedtls_ssl_get_srtp_profile_as_string(
+                                            client_protection ) ) );
+        }
+        else
+        {
+            continue;
+        }
+        /* check if suggested profile is in our list */
+        for( i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
+        {
+            if( client_protection == ssl->conf->dtls_srtp_profile_list[i] )
+            {
+                ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
+                                            mbedtls_ssl_get_srtp_profile_as_string(
+                                                    client_protection ) ) );
+                break;
+            }
+        }
+        if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET )
+            break;
+    }
+    buf += profile_length; /* buf points to the mki length */
+    mki_length = *buf;
+    buf++;
+
+    if( mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ||
+        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 );
+    }
+
+    /* Parse the mki only if present and mki is supported locally */
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
+          mki_length > 0 )
+    {
+        ssl->dtls_srtp_info.mki_len = mki_length;
+
+        memcpy( ssl->dtls_srtp_info.mki_value, buf, mki_length );
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "using mki",  ssl->dtls_srtp_info.mki_value,
+                                                ssl->dtls_srtp_info.mki_len );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 /*
  * Auxiliary functions for ServerHello parsing and related actions
  */
@@ -1942,6 +2062,16 @@
                 break;
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+            case MBEDTLS_TLS_EXT_USE_SRTP:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+
+                ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
             default:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
                                ext_id ) );
@@ -2500,6 +2630,78 @@
 }
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP ) && defined(MBEDTLS_SSL_PROTO_DTLS)
+static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+                                    unsigned char *buf,
+                                    size_t *olen )
+{
+    size_t mki_len = 0, ext_len = 0;
+    uint16_t profile_value = 0;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+    *olen = 0;
+
+    if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+        ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) )
+    {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) );
+
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+    {
+        mki_len = ssl->dtls_srtp_info.mki_len;
+    }
+
+    /* The extension total size is 9 bytes :
+     * - 2 bytes for the extension tag
+     * - 2 bytes for the total size
+     * - 2 bytes for the protection profile length
+     * - 2 bytes for the protection profile
+     * - 1 byte for the mki length
+     * +  the actual mki length
+     * Check we have enough room in the output buffer */
+    if( (size_t)( end - buf ) < mki_len + 9 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    /* extension */
+    buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
+    buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
+    /*
+     * total length 5 and mki value: only one profile(2 bytes)
+     *              and length(2 bytes) and srtp_mki  )
+     */
+    ext_len = 5 + mki_len;
+    buf[2] = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
+    buf[3] = (unsigned char)( ext_len & 0xFF );
+
+    /* protection profile length: 2 */
+    buf[4] = 0x00;
+    buf[5] = 0x02;
+    profile_value = mbedtls_ssl_check_srtp_profile_value(
+                                ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
+    if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
+    {
+        buf[6] = (unsigned char)( ( profile_value >> 8 ) & 0xFF );
+        buf[7] = (unsigned char)( profile_value & 0xFF );
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "use_srtp extension invalid profile" ) );
+        return;
+    }
+
+    buf[8] = mki_len & 0xFF;
+    memcpy( &buf[9], ssl->dtls_srtp_info.mki_value, mki_len );
+
+    *olen = 9 + mki_len;
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
 static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
 {
@@ -2788,6 +2990,11 @@
     ext_len += olen;
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
 
     if( ext_len > 0 )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 7062d53..7cb5b8c 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3859,6 +3859,10 @@
 
     mbedtls_ssl_reset_in_out_pointers( ssl );
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    memset( &ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info) );
+#endif
+
     if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
         goto error;
 
@@ -4685,6 +4689,86 @@
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
+                                                int support_mki_value )
+{
+    conf->dtls_srtp_mki_support = support_mki_value;
+}
+
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
+                                         unsigned char *mki_value,
+                                         uint16_t mki_len )
+{
+    if( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH )
+    {
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED )
+    {
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
+
+    memcpy( ssl->dtls_srtp_info.mki_value, mki_value, mki_len );
+    ssl->dtls_srtp_info.mki_len = mki_len;
+    return( 0 );
+}
+
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
+                                                    const mbedtls_ssl_srtp_profile *profiles )
+{
+    const mbedtls_ssl_srtp_profile *p;
+    size_t list_size = 0;
+
+    /* check the profiles list: all entry must be valid,
+     * its size cannot be more than the total number of supported profiles, currently 4 */
+    for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET &&
+                       list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
+         p++ )
+    {
+        if( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET )
+        {
+            list_size++;
+        }
+        else
+        {
+            /* unsupported value, stop parsing and set the size to an error value */
+            list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
+        }
+    }
+
+    if( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH )
+    {
+                conf->dtls_srtp_profile_list = NULL;
+                conf->dtls_srtp_profile_list_len = 0;
+                return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    conf->dtls_srtp_profile_list = profiles;
+    conf->dtls_srtp_profile_list_len = list_size;
+
+    return( 0 );
+}
+
+void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl,
+                                                   mbedtls_dtls_srtp_info *dtls_srtp_info )
+{
+    dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile;
+    /* do not copy the mki value if there is no chosen profile */
+    if( dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+    {
+        dtls_srtp_info->mki_len = 0;
+    }
+    else
+    {
+        dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len;
+        memcpy( dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value,
+                ssl->dtls_srtp_info.mki_len );
+    }
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
 {
     conf->max_major_ver = major;
@@ -5682,11 +5766,24 @@
 {
     int ret = 0;
 
+    /* Sanity checks */
+
     if( ssl == NULL || ssl->conf == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
+                                     "mbedtls_ssl_set_timer_cb() for DTLS" ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
 
+    /* Main handshake loop */
     while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
     {
         ret = mbedtls_ssl_handshake_step( ssl );
diff --git a/library/version_features.c b/library/version_features.c
index 478d8fa..42ccaf9 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -534,6 +534,9 @@
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
     "MBEDTLS_SSL_DTLS_HELLO_VERIFY",
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    "MBEDTLS_SSL_DTLS_SRTP",
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
     "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE",
 #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */
@@ -576,6 +579,9 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     "MBEDTLS_USE_PSA_CRYPTO",
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+    "MBEDTLS_PSA_CRYPTO_CONFIG",
+#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
 #if defined(MBEDTLS_VERSION_FEATURES)
     "MBEDTLS_VERSION_FEATURES",
 #endif /* MBEDTLS_VERSION_FEATURES */
diff --git a/programs/aes/CMakeLists.txt b/programs/aes/CMakeLists.txt
index 2309789..6b8ce2a 100644
--- a/programs/aes/CMakeLists.txt
+++ b/programs/aes/CMakeLists.txt
@@ -5,7 +5,7 @@
 
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
-    target_link_libraries(${exe} mbedcrypto)
+    target_link_libraries(${exe} ${mbedcrypto_target})
 endforeach()
 
 install(TARGETS ${executables}
diff --git a/programs/fuzz/CMakeLists.txt b/programs/fuzz/CMakeLists.txt
index e2b0eac..35512c7 100644
--- a/programs/fuzz/CMakeLists.txt
+++ b/programs/fuzz/CMakeLists.txt
@@ -1,5 +1,5 @@
 set(libs
-    mbedtls
+    ${mbedtls_target}
 )
 
 if(USE_PKCS11_HELPER_LIBRARY)
diff --git a/programs/hash/CMakeLists.txt b/programs/hash/CMakeLists.txt
index ae29479..b2f2a1f 100644
--- a/programs/hash/CMakeLists.txt
+++ b/programs/hash/CMakeLists.txt
@@ -5,7 +5,7 @@
 
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
-    target_link_libraries(${exe} mbedcrypto)
+    target_link_libraries(${exe} ${mbedcrypto_target})
 endforeach()
 
 install(TARGETS ${executables}
diff --git a/programs/pkey/CMakeLists.txt b/programs/pkey/CMakeLists.txt
index b4b3d30..9c6fe7d 100644
--- a/programs/pkey/CMakeLists.txt
+++ b/programs/pkey/CMakeLists.txt
@@ -5,7 +5,7 @@
 
 foreach(exe IN LISTS executables_mbedtls)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
-    target_link_libraries(${exe} mbedtls)
+    target_link_libraries(${exe} ${mbedtls_target})
 endforeach()
 
 set(executables_mbedcrypto
@@ -31,7 +31,7 @@
 
 foreach(exe IN LISTS executables_mbedcrypto)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
-    target_link_libraries(${exe} mbedcrypto)
+    target_link_libraries(${exe} ${mbedcrypto_target})
 endforeach()
 
 install(TARGETS ${executables_mbedtls} ${executables_mbedcrypto}
diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt
index 5cbcf71..23e85fe 100644
--- a/programs/psa/CMakeLists.txt
+++ b/programs/psa/CMakeLists.txt
@@ -6,7 +6,7 @@
 
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
-    target_link_libraries(${exe} mbedcrypto)
+    target_link_libraries(${exe} ${mbedcrypto_target})
     target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
 endforeach()
 
diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c
index 623a090..15aabf9 100644
--- a/programs/psa/crypto_examples.c
+++ b/programs/psa/crypto_examples.c
@@ -317,18 +317,6 @@
         printf( "\tsuccess!\r\n" );
 }
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    exit( EXIT_FAILURE );
-}
-#endif
-
 int main( void )
 {
     ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
diff --git a/programs/psa/key_ladder_demo.c b/programs/psa/key_ladder_demo.c
index ae2442e..a3628f0 100644
--- a/programs/psa/key_ladder_demo.c
+++ b/programs/psa/key_ladder_demo.c
@@ -603,18 +603,6 @@
     printf( "                    and the same sequence of labels.\n" );
 }
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-#include "mbedtls/platform_util.h"
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    printf( "%s:%i: Input param failed - %s\n",
-                    file, line, failure_condition );
-    exit( EXIT_FAILURE );
-}
-#endif
-
 int main( int argc, char *argv[] )
 {
     const char *key_file_name = "master.key";
diff --git a/programs/random/CMakeLists.txt b/programs/random/CMakeLists.txt
index 95acb7e..8df8365 100644
--- a/programs/random/CMakeLists.txt
+++ b/programs/random/CMakeLists.txt
@@ -6,7 +6,7 @@
 
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
-    target_link_libraries(${exe} mbedcrypto)
+    target_link_libraries(${exe} ${mbedcrypto_target})
 endforeach()
 
 install(TARGETS ${executables}
diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt
index 28fbfc5..ca0a6a4 100644
--- a/programs/ssl/CMakeLists.txt
+++ b/programs/ssl/CMakeLists.txt
@@ -2,7 +2,7 @@
 find_package(Threads)
 
 set(libs
-    mbedtls
+    ${mbedtls_target}
 )
 
 if(USE_PKCS11_HELPER_LIBRARY)
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index a26dd51..54cdd7d 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -149,6 +149,10 @@
 #define DFL_NSS_KEYLOG          0
 #define DFL_NSS_KEYLOG_FILE     NULL
 #define DFL_SKIP_CLOSE_NOTIFY   0
+#define DFL_QUERY_CONFIG_MODE   0
+#define DFL_USE_SRTP            0
+#define DFL_SRTP_FORCE_PROFILE  0
+#define DFL_SRTP_MKI            ""
 
 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
 #define GET_REQUEST_END "\r\n\r\n"
@@ -253,10 +257,26 @@
     "                             This cannot be used with eap_tls=1\n"
 #define USAGE_NSS_KEYLOG_FILE                               \
     "    nss_keylog_file=%%s\n"
-#else
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+#define USAGE_SRTP \
+    "    use_srtp=%%d         default: 0 (disabled)\n" \
+    "                          This cannot be used with eap_tls=1 or "\
+    "                          nss_keylog=1\n"             \
+    "    srtp_force_profile=%%d  default: 0 (all enabled)\n"   \
+    "                        available profiles:\n"       \
+    "                        1 - SRTP_AES128_CM_HMAC_SHA1_80\n"  \
+    "                        2 - SRTP_AES128_CM_HMAC_SHA1_32\n"  \
+    "                        3 - SRTP_NULL_HMAC_SHA1_80\n"       \
+    "                        4 - SRTP_NULL_HMAC_SHA1_32\n"       \
+    "    mki=%%s              default: \"\" (in hex, without 0x)\n"
+#else /* MBEDTLS_SSL_DTLS_SRTP */
+#define USAGE_SRTP ""
+#endif
+#else /* MBEDTLS_SSL_EXPORT_KEYS */
 #define USAGE_EAP_TLS ""
 #define USAGE_NSS_KEYLOG ""
 #define USAGE_NSS_KEYLOG_FILE ""
+#define USAGE_SRTP ""
 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
@@ -406,6 +426,7 @@
     "\n"                                                    \
     USAGE_DTLS                                              \
     USAGE_CID                                               \
+    USAGE_SRTP                                              \
     "\n"
 #define USAGE2 \
     "    auth_mode=%%s        default: (library default: none)\n" \
@@ -539,6 +560,10 @@
                                  * after renegotiation                      */
     int reproducible;           /* make communication reproducible          */
     int skip_close_notify;      /* skip sending the close_notify alert      */
+    int query_config_mode;      /* whether to read config                   */
+    int use_srtp;               /* Support SRTP                             */
+    int force_srtp_profile;     /* SRTP protection profile to use or all    */
+    const char *mki;            /* The dtls mki value to use                */
 } opt;
 
 int query_config( const char *config );
@@ -653,7 +678,49 @@
                               sizeof( nss_keylog_line ) );
     return( ret );
 }
-#endif
+
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+/* Supported SRTP mode needs a maximum of :
+ * - 16 bytes for key (AES-128)
+ * - 14 bytes SALT
+ * One for sender, one for receiver context
+ */
+#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
+typedef struct dtls_srtp_keys
+{
+    unsigned char master_secret[48];
+    unsigned char randbytes[64];
+    mbedtls_tls_prf_types tls_prf_type;
+} dtls_srtp_keys;
+
+static int dtls_srtp_key_derivation( void *p_expkey,
+                                     const unsigned char *ms,
+                                     const unsigned char *kb,
+                                     size_t maclen,
+                                     size_t keylen,
+                                     size_t ivlen,
+                                     const unsigned char client_random[32],
+                                     const unsigned char server_random[32],
+                                     mbedtls_tls_prf_types tls_prf_type )
+{
+    dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey;
+
+    ( ( void ) kb );
+    memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
+    memcpy( keys->randbytes, client_random, 32 );
+    memcpy( keys->randbytes + 32, server_random, 32 );
+    keys->tls_prf_type = tls_prf_type;
+
+    if( opt.debug_level > 2 )
+    {
+        mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen );
+        mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen );
+        mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen );
+    }
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 static void my_debug( void *ctx, int level,
                       const char *file, int line,
@@ -1102,6 +1169,7 @@
 int main( int argc, char *argv[] )
 {
     int ret = 0, len, tail_len, i, written, frags, retry_left;
+    int query_config_ret = 0;
     mbedtls_net_context server_fd;
     io_ctx_t io_ctx;
 
@@ -1131,6 +1199,10 @@
     mbedtls_ecp_group_id curve_list[CURVE_LIST_SIZE];
     const mbedtls_ecp_curve_info *curve_cur;
 #endif
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    unsigned char mki[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH];
+    size_t mki_len=0;
+#endif
 
     const char *pers = "ssl_client2";
 
@@ -1174,7 +1246,20 @@
     unsigned char eap_tls_iv[8];
     const char* eap_tls_label = "client EAP encryption";
     eap_tls_keys eap_tls_keying;
-#endif
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+    /*! master keys and master salt for SRTP generated during handshake */
+    unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH];
+    const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
+    dtls_srtp_keys dtls_srtp_keying;
+    const mbedtls_ssl_srtp_profile default_profiles[] = {
+        MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
+        MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32,
+        MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80,
+        MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32,
+        MBEDTLS_TLS_SRTP_UNSET
+    };
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
@@ -1300,6 +1385,10 @@
     opt.nss_keylog          = DFL_NSS_KEYLOG;
     opt.nss_keylog_file     = DFL_NSS_KEYLOG_FILE;
     opt.skip_close_notify   = DFL_SKIP_CLOSE_NOTIFY;
+    opt.query_config_mode   = DFL_QUERY_CONFIG_MODE;
+    opt.use_srtp            = DFL_USE_SRTP;
+    opt.force_srtp_profile  = DFL_SRTP_FORCE_PROFILE;
+    opt.mki                 = DFL_SRTP_MKI;
 
     for( i = 1; i < argc; i++ )
     {
@@ -1686,7 +1775,9 @@
         }
         else if( strcmp( p, "query_config" ) == 0 )
         {
-            mbedtls_exit( query_config( q ) );
+            opt.query_config_mode = 1;
+            query_config_ret = query_config( q );
+            goto exit;
         }
         else if( strcmp( p, "serialize") == 0 )
         {
@@ -1724,6 +1815,18 @@
             if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 )
                 goto usage;
         }
+        else if( strcmp( p, "use_srtp" ) == 0 )
+        {
+            opt.use_srtp = atoi ( q );
+        }
+        else if( strcmp( p, "srtp_force_profile" ) == 0 )
+        {
+            opt.force_srtp_profile = atoi( q );
+        }
+        else if( strcmp( p, "mki" ) == 0 )
+        {
+            opt.mki = q;
+        }
         else
             goto usage;
     }
@@ -1831,7 +1934,6 @@
             opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
         }
 
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         if( opt.psk_opaque != 0 )
         {
@@ -2234,6 +2336,36 @@
     }
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( opt.use_srtp == 1 )
+    {
+        if( opt.force_srtp_profile != 0 )
+        {
+            const mbedtls_ssl_srtp_profile forced_profile[] =
+                                        { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles ( &conf, forced_profile );
+        }
+        else
+        {
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles ( &conf, default_profiles );
+        }
+
+        if( ret != 0 )
+        {
+            mbedtls_printf( " failed\n  ! "
+                            "mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n",
+                            ret );
+            goto exit;
+        }
+
+    }
+    else if( opt.force_srtp_profile != 0 )
+    {
+        mbedtls_printf( " failed\n  ! must enable use_srtp to force srtp profile\n\n" );
+        goto exit;
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
     if( opt.trunc_hmac != DFL_TRUNC_HMAC )
         mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
@@ -2261,7 +2393,14 @@
                                              nss_keylog_export,
                                              NULL );
     }
-#endif
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+    else if( opt.use_srtp != 0 )
+    {
+        mbedtls_ssl_conf_export_keys_ext_cb( &conf, dtls_srtp_key_derivation,
+                                             &dtls_srtp_keying );
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
     if( opt.recsplit != DFL_RECSPLIT )
@@ -2470,6 +2609,26 @@
         mbedtls_ecp_set_max_ops( opt.ec_max_ops );
 #endif
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( opt.use_srtp != 0 && strlen( opt.mki ) != 0 )
+    {
+        if( mbedtls_test_unhexify( mki, sizeof( mki ),
+                                   opt.mki,&mki_len ) != 0 )
+        {
+            mbedtls_printf( "mki value not valid hex\n" );
+            goto exit;
+        }
+
+        mbedtls_ssl_conf_srtp_mki_value_supported( &conf, MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED );
+        if( ( ret = mbedtls_ssl_dtls_srtp_set_mki_value( &ssl, mki,
+                                                         (uint16_t) strlen( opt.mki ) / 2 ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_dtls_srtp_set_mki_value returned %d\n\n", ret );
+            goto exit;
+        }
+    }
+#endif
+
     mbedtls_printf( " ok\n" );
 
     /*
@@ -2591,7 +2750,74 @@
         }
         mbedtls_printf("\n");
     }
-#endif
+
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+    else if( opt.use_srtp != 0  )
+    {
+        size_t j = 0;
+        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result;
+        mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl, &dtls_srtp_negotiation_result );
+
+        if( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
+                                == MBEDTLS_TLS_SRTP_UNSET )
+        {
+            mbedtls_printf( "    Unable to negotiate "
+                            "the use of DTLS-SRTP\n" );
+        }
+        else
+        {
+            if( ( ret = mbedtls_ssl_tls_prf( dtls_srtp_keying.tls_prf_type,
+                                             dtls_srtp_keying.master_secret,
+                                             sizeof( dtls_srtp_keying.master_secret ),
+                                             dtls_srtp_label,
+                                             dtls_srtp_keying.randbytes,
+                                             sizeof( dtls_srtp_keying.randbytes ),
+                                             dtls_srtp_key_material,
+                                             sizeof( dtls_srtp_key_material ) ) )
+                                             != 0 )
+            {
+                mbedtls_printf( " failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
+                                (unsigned int) -ret );
+                goto exit;
+            }
+
+            mbedtls_printf( "    DTLS-SRTP key material is:" );
+            for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ )
+            {
+                if( j % 8 == 0 )
+                    mbedtls_printf( "\n    " );
+                mbedtls_printf( "%02x ", dtls_srtp_key_material[j] );
+            }
+            mbedtls_printf( "\n" );
+
+            /* produce a less readable output used to perform automatic checks
+             * - compare client and server output
+             * - interop test with openssl which client produces this kind of output
+             */
+            mbedtls_printf( "    Keying material: " );
+            for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ )
+            {
+                mbedtls_printf( "%02X", dtls_srtp_key_material[j] );
+            }
+            mbedtls_printf( "\n" );
+
+            if ( dtls_srtp_negotiation_result.mki_len > 0 )
+            {
+                mbedtls_printf( "    DTLS-SRTP mki value: " );
+                for( j = 0; j < dtls_srtp_negotiation_result.mki_len; j++ )
+                {
+                    mbedtls_printf( "%02X", dtls_srtp_negotiation_result.mki_value[j] );
+                }
+            }
+            else
+            {
+                mbedtls_printf( "    DTLS-SRTP no mki value negotiated" );
+            }
+            mbedtls_printf( "\n" );
+        }
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
     if( opt.reconnect != 0 )
     {
         mbedtls_printf("  . Saving session for reuse..." );
@@ -2685,7 +2911,7 @@
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_set_cid returned %d\n\n",
                             ret );
-            return( ret );
+            goto exit;
         }
     }
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
@@ -3348,7 +3574,8 @@
          * immediately because of bad cmd line params,
          * for example). */
         status = psa_destroy_key( slot );
-        if( status != PSA_SUCCESS )
+        if( ( status != PSA_SUCCESS ) &&
+            ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
         {
             mbedtls_printf( "Failed to destroy key slot %u - error was %d",
                             (unsigned) slot, (int) status );
@@ -3367,15 +3594,21 @@
 #endif
 
 #if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
+    if( opt.query_config_mode == DFL_QUERY_CONFIG_MODE )
+    {
+        mbedtls_printf( "  + Press Enter to exit this program.\n" );
+        fflush( stdout ); getchar();
+    }
 #endif
 
     // Shell can not handle large exit numbers -> 1 for errors
     if( ret < 0 )
         ret = 1;
 
-    mbedtls_exit( ret );
+    if( opt.query_config_mode == DFL_QUERY_CONFIG_MODE )
+        mbedtls_exit( ret );
+    else
+        mbedtls_exit( query_config_ret );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
           MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c
index df8819a..d109c1e 100644
--- a/programs/ssl/ssl_context_info.c
+++ b/programs/ssl/ssl_context_info.c
@@ -377,13 +377,13 @@
     int valid_balance = 0;  /* balance between valid and invalid characters */
     size_t len = 0;
     char pad = 0;
-    char c = 0;
+    int c = 0;
 
     while( EOF != c )
     {
         char c_valid = 0;
 
-        c = (char) fgetc( b64_file );
+        c = fgetc( b64_file );
 
         if( pad > 0 )
         {
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index c445ddb..ec3d6ad 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -182,6 +182,10 @@
 #define DFL_REPRODUCIBLE        0
 #define DFL_NSS_KEYLOG          0
 #define DFL_NSS_KEYLOG_FILE     NULL
+#define DFL_QUERY_CONFIG_MODE   0
+#define DFL_USE_SRTP            0
+#define DFL_SRTP_FORCE_PROFILE  0
+#define DFL_SRTP_SUPPORT_MKI    0
 
 #define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
     "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
@@ -324,10 +328,24 @@
     "                             This cannot be used with eap_tls=1\n"
 #define USAGE_NSS_KEYLOG_FILE                               \
     "    nss_keylog_file=%%s\n"
-#else
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+#define USAGE_SRTP \
+    "    use_srtp=%%d         default: 0 (disabled)\n" \
+    "    srtp_force_profile=%%d  default: 0 (all enabled)\n"   \
+    "                        available profiles:\n"       \
+    "                        1 - SRTP_AES128_CM_HMAC_SHA1_80\n"  \
+    "                        2 - SRTP_AES128_CM_HMAC_SHA1_32\n"  \
+    "                        3 - SRTP_NULL_HMAC_SHA1_80\n"       \
+    "                        4 - SRTP_NULL_HMAC_SHA1_32\n"       \
+    "    support_mki=%%d     default: 0 (not supported)\n"
+#else /* MBEDTLS_SSL_DTLS_SRTP */
+#define USAGE_SRTP ""
+#endif
+#else /* MBEDTLS_SSL_EXPORT_KEYS */
 #define USAGE_EAP_TLS ""
 #define USAGE_NSS_KEYLOG ""
 #define USAGE_NSS_KEYLOG_FILE ""
+#define USAGE_SRTP ""
 #endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_CACHE_C)
@@ -489,6 +507,7 @@
     "    read_timeout=%%d     default: 0 ms (no timeout)\n"    \
     "\n"                                                    \
     USAGE_DTLS                                              \
+    USAGE_SRTP                                              \
     USAGE_COOKIES                                           \
     USAGE_ANTI_REPLAY                                       \
     USAGE_BADMAC_LIMIT                                      \
@@ -643,6 +662,10 @@
     const char *cid_val_renego; /* the CID to use for incoming messages
                                  * after renegotiation                      */
     int reproducible;           /* make communication reproducible          */
+    int query_config_mode;      /* whether to read config                   */
+    int use_srtp;               /* Support SRTP                             */
+    int force_srtp_profile;     /* SRTP protection profile to use or all    */
+    int support_mki;            /* The dtls mki mki support                 */
 } opt;
 
 int query_config( const char *config );
@@ -758,7 +781,49 @@
     return( ret );
 }
 
-#endif
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+/* Supported SRTP mode needs a maximum of :
+ * - 16 bytes for key (AES-128)
+ * - 14 bytes SALT
+ * One for sender, one for receiver context
+ */
+#define MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH    60
+typedef struct dtls_srtp_keys
+{
+    unsigned char master_secret[48];
+    unsigned char randbytes[64];
+    mbedtls_tls_prf_types tls_prf_type;
+} dtls_srtp_keys;
+
+static int dtls_srtp_key_derivation( void *p_expkey,
+                                     const unsigned char *ms,
+                                     const unsigned char *kb,
+                                     size_t maclen,
+                                     size_t keylen,
+                                     size_t ivlen,
+                                     const unsigned char client_random[32],
+                                     const unsigned char server_random[32],
+                                     mbedtls_tls_prf_types tls_prf_type )
+{
+    dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey;
+
+    ( ( void ) kb );
+    memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
+    memcpy( keys->randbytes, client_random, 32 );
+    memcpy( keys->randbytes + 32, server_random, 32 );
+    keys->tls_prf_type = tls_prf_type;
+
+    if( opt.debug_level > 2 )
+    {
+        mbedtls_printf( "exported maclen is %u\n", (unsigned) maclen );
+        mbedtls_printf( "exported keylen is %u\n", (unsigned) keylen );
+        mbedtls_printf( "exported ivlen is %u\n", (unsigned) ivlen );
+    }
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 static void my_debug( void *ctx, int level,
                       const char *file, int line,
@@ -1723,6 +1788,7 @@
 int main( int argc, char *argv[] )
 {
     int ret = 0, len, written, frags, exchanges_left;
+    int query_config_ret = 0;
     int version_suites[4][2];
     io_ctx_t io_ctx;
     unsigned char* buf = 0;
@@ -1789,7 +1855,6 @@
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     unsigned char alloc_buf[MEMORY_HEAP_SIZE];
 #endif
-
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     unsigned char cid[MBEDTLS_SSL_CID_IN_LEN_MAX];
     unsigned char cid_renego[MBEDTLS_SSL_CID_IN_LEN_MAX];
@@ -1812,7 +1877,20 @@
     unsigned char eap_tls_iv[8];
     const char* eap_tls_label = "client EAP encryption";
     eap_tls_keys eap_tls_keying;
-#endif
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+    /*! master keys and master salt for SRTP generated during handshake */
+     unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH];
+     const char* dtls_srtp_label = "EXTRACTOR-dtls_srtp";
+     dtls_srtp_keys dtls_srtp_keying;
+     const mbedtls_ssl_srtp_profile default_profiles[] = {
+         MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
+         MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32,
+         MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80,
+         MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32,
+         MBEDTLS_TLS_SRTP_UNSET
+     };
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
@@ -1972,6 +2050,10 @@
     opt.reproducible        = DFL_REPRODUCIBLE;
     opt.nss_keylog          = DFL_NSS_KEYLOG;
     opt.nss_keylog_file     = DFL_NSS_KEYLOG_FILE;
+    opt.query_config_mode   = DFL_QUERY_CONFIG_MODE;
+    opt.use_srtp            = DFL_USE_SRTP;
+    opt.force_srtp_profile  = DFL_SRTP_FORCE_PROFILE;
+    opt.support_mki         = DFL_SRTP_SUPPORT_MKI;
 
     for( i = 1; i < argc; i++ )
     {
@@ -2386,7 +2468,9 @@
         }
         else if( strcmp( p, "query_config" ) == 0 )
         {
-            mbedtls_exit( query_config( q ) );
+            opt.query_config_mode = 1;
+            query_config_ret = query_config( q );
+            goto exit;
         }
         else if( strcmp( p, "serialize") == 0 )
         {
@@ -2418,6 +2502,18 @@
         {
             opt.nss_keylog_file = q;
         }
+        else if( strcmp( p, "use_srtp" ) == 0 )
+        {
+            opt.use_srtp = atoi ( q );
+        }
+        else if( strcmp( p, "srtp_force_profile" ) == 0 )
+        {
+            opt.force_srtp_profile = atoi( q );
+        }
+        else if( strcmp( p, "support_mki" ) == 0 )
+        {
+            opt.support_mki = atoi( q );
+        }
         else
             goto usage;
     }
@@ -3022,7 +3118,7 @@
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret );
         goto exit;
-    };
+    }
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
@@ -3052,6 +3148,38 @@
     }
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( opt.use_srtp == 1 )
+    {
+        if( opt.force_srtp_profile != 0 )
+        {
+            const mbedtls_ssl_srtp_profile forced_profile[] = { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, forced_profile );
+        }
+        else
+        {
+            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles( &conf, default_profiles );
+        }
+
+        if( ret != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n", ret );
+            goto exit;
+        }
+
+        mbedtls_ssl_conf_srtp_mki_value_supported( &conf,
+                                                   opt.support_mki ?
+                                                   MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED :
+                                                   MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED );
+
+    }
+    else if( opt.force_srtp_profile != 0 )
+    {
+        mbedtls_printf( " failed\n  ! must enable use_srtp to force srtp profile\n\n" );
+        goto exit;
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
     if( opt.trunc_hmac != DFL_TRUNC_HMAC )
         mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
@@ -3079,7 +3207,14 @@
                                              nss_keylog_export,
                                              NULL );
     }
-#endif
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+    else if( opt.use_srtp != 0 )
+    {
+        mbedtls_ssl_conf_export_keys_ext_cb( &conf, dtls_srtp_key_derivation,
+                                             &dtls_srtp_keying );
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_ALPN)
     if( opt.alpn_string != NULL )
@@ -3725,7 +3860,75 @@
         }
         mbedtls_printf("\n");
     }
-#endif
+
+#if defined( MBEDTLS_SSL_DTLS_SRTP )
+    else if( opt.use_srtp != 0  )
+    {
+        size_t j = 0;
+        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result;
+        mbedtls_ssl_get_dtls_srtp_negotiation_result( &ssl, &dtls_srtp_negotiation_result );
+
+        if( dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
+                                == MBEDTLS_TLS_SRTP_UNSET )
+        {
+            mbedtls_printf( "    Unable to negotiate "
+                            "the use of DTLS-SRTP\n" );
+        }
+        else
+        {
+            if( ( ret = mbedtls_ssl_tls_prf( dtls_srtp_keying.tls_prf_type,
+                                             dtls_srtp_keying.master_secret,
+                                             sizeof( dtls_srtp_keying.master_secret ),
+                                             dtls_srtp_label,
+                                             dtls_srtp_keying.randbytes,
+                                             sizeof( dtls_srtp_keying.randbytes ),
+                                             dtls_srtp_key_material,
+                                             sizeof( dtls_srtp_key_material ) ) )
+                                             != 0 )
+            {
+                mbedtls_printf( " failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
+                                (unsigned int) -ret );
+                goto exit;
+            }
+
+            mbedtls_printf( "    DTLS-SRTP key material is:" );
+            for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ )
+            {
+                if( j % 8 == 0 )
+                    mbedtls_printf( "\n    " );
+                mbedtls_printf( "%02x ", dtls_srtp_key_material[j] );
+            }
+            mbedtls_printf( "\n" );
+
+            /* produce a less readable output used to perform automatic checks
+             * - compare client and server output
+             * - interop test with openssl which client produces this kind of output
+             */
+            mbedtls_printf( "    Keying material: " );
+            for( j = 0; j < sizeof( dtls_srtp_key_material ); j++ )
+            {
+                mbedtls_printf( "%02X", dtls_srtp_key_material[j] );
+            }
+            mbedtls_printf( "\n" );
+
+            if ( dtls_srtp_negotiation_result.mki_len > 0 )
+            {
+                mbedtls_printf( "    DTLS-SRTP mki value: " );
+                for( j = 0; j < dtls_srtp_negotiation_result.mki_len; j++ )
+                {
+                    mbedtls_printf( "%02X", dtls_srtp_negotiation_result.mki_value[j] );
+                }
+            }
+            else
+            {
+                mbedtls_printf( "    DTLS-SRTP no mki value negotiated" );
+            }
+            mbedtls_printf( "\n" );
+
+        }
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     ret = report_cid_usage( &ssl, "initial handshake" );
@@ -4261,8 +4464,11 @@
     }
 #endif
 
-    mbedtls_printf( "  . Cleaning up..." );
-    fflush( stdout );
+    if( opt.query_config_mode == DFL_QUERY_CONFIG_MODE )
+    {
+        mbedtls_printf( "  . Cleaning up..." );
+        fflush( stdout );
+    }
 
     mbedtls_net_free( &client_fd );
     mbedtls_net_free( &listen_fd );
@@ -4292,7 +4498,8 @@
     sni_free( sni_info );
 #endif
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
-    if( ( ret = psk_free( psk_info ) ) != 0 )
+    ret = psk_free( psk_info );
+    if( ( ret != 0 ) && ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
         mbedtls_printf( "Failed to list of opaque PSKs - error was %d\n", ret );
 #endif
 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
@@ -4308,7 +4515,8 @@
          * immediately because of bad cmd line params,
          * for example). */
         status = psa_destroy_key( psk_slot );
-        if( status != PSA_SUCCESS )
+        if( ( status != PSA_SUCCESS ) &&
+            ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
         {
             mbedtls_printf( "Failed to destroy key slot %u - error was %d",
                             (unsigned) psk_slot, (int) status );
@@ -4347,18 +4555,24 @@
     mbedtls_memory_buffer_alloc_free();
 #endif
 
-    mbedtls_printf( " done.\n" );
+    if( opt.query_config_mode == DFL_QUERY_CONFIG_MODE )
+    {
+        mbedtls_printf( " done.\n" );
 
 #if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
+        mbedtls_printf( "  + Press Enter to exit this program.\n" );
+        fflush( stdout ); getchar();
 #endif
+    }
 
     // Shell can not handle large exit numbers -> 1 for errors
     if( ret < 0 )
         ret = 1;
 
-    mbedtls_exit( ret );
+    if( opt.query_config_mode == DFL_QUERY_CONFIG_MODE )
+        mbedtls_exit( ret );
+    else
+        mbedtls_exit( query_config_ret );
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
           MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 0df0bec..217741b 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -1,5 +1,5 @@
 set(libs
-    mbedtls
+    ${mbedtls_target}
 )
 
 if(USE_PKCS11_HELPER_LIBRARY)
@@ -33,7 +33,7 @@
     if (${exe_index} GREATER -1)
         target_link_libraries(${exe} ${libs})
     else()
-        target_link_libraries(${exe} mbedcrypto)
+        target_link_libraries(${exe} ${mbedcrypto_target})
     endif()
 endforeach()
 
diff --git a/programs/test/cmake_subproject/CMakeLists.txt b/programs/test/cmake_subproject/CMakeLists.txt
index 3e32c5f..a9fcfde 100644
--- a/programs/test/cmake_subproject/CMakeLists.txt
+++ b/programs/test/cmake_subproject/CMakeLists.txt
@@ -1,5 +1,8 @@
 cmake_minimum_required(VERSION 2.6)
 
+# Test the target renaming support by adding a prefix to the targets built
+set(MBEDTLS_TARGET_PREFIX subproject_test_)
+
 # We use the parent Mbed TLS directory as the MBEDTLS_DIR for this test. Other
 # projects that use Mbed TLS as a subproject are likely to add by their own
 # relative paths.
@@ -8,11 +11,12 @@
 # Add Mbed TLS as a subdirectory.
 add_subdirectory(${MBEDTLS_DIR} build)
 
-# Link against all the Mbed TLS libraries.
+# Link against all the Mbed TLS libraries. Verifies that the targets have been
+# created using the specified prefix
 set(libs
-    mbedcrypto
-    mbedx509
-    mbedtls
+    subproject_test_mbedcrypto
+    subproject_test_mbedx509
+    subproject_test_mbedtls
 )
 
 add_executable(cmake_subproject cmake_subproject.c)
diff --git a/programs/test/cpp_dummy_build.cpp b/programs/test/cpp_dummy_build.cpp
index 09c5273..c69cd2b 100644
--- a/programs/test/cpp_dummy_build.cpp
+++ b/programs/test/cpp_dummy_build.cpp
@@ -109,6 +109,12 @@
 #include "mbedtls/memory_buffer_alloc.h"
 #endif
 
+#include "psa/crypto.h"
+#include "psa/crypto_se_driver.h"
+#include "psa/crypto_entropy_driver.h"
+#include "psa/crypto_accel_driver.h"
+#include "../library/psa_crypto_its.h"
+
 int main()
 {
     mbedtls_platform_context *ctx = NULL;
diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index 8873734..1345b11 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -1480,6 +1480,14 @@
     }
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
 
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+    if( strcmp( "MBEDTLS_SSL_DTLS_SRTP", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_DTLS_SRTP );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
     if( strcmp( "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", config ) == 0 )
     {
@@ -1592,6 +1600,14 @@
     }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+    if( strcmp( "MBEDTLS_PSA_CRYPTO_CONFIG", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_CONFIG );
+        return( 0 );
+    }
+#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
+
 #if defined(MBEDTLS_VERSION_FEATURES)
     if( strcmp( "MBEDTLS_VERSION_FEATURES", config ) == 0 )
     {
diff --git a/programs/util/CMakeLists.txt b/programs/util/CMakeLists.txt
index cb14a3e..2a11212 100644
--- a/programs/util/CMakeLists.txt
+++ b/programs/util/CMakeLists.txt
@@ -1,5 +1,5 @@
 set(libs
-    mbedcrypto
+    ${mbedcrypto_target}
 )
 
 set(executables
diff --git a/programs/x509/CMakeLists.txt b/programs/x509/CMakeLists.txt
index f7b5fe1..29cbeb8 100644
--- a/programs/x509/CMakeLists.txt
+++ b/programs/x509/CMakeLists.txt
@@ -1,5 +1,5 @@
 set(libs
-    mbedx509
+    ${mbedx509_target}
 )
 
 if(USE_PKCS11_HELPER_LIBRARY)
@@ -23,7 +23,7 @@
     target_link_libraries(${exe} ${libs})
 endforeach()
 
-target_link_libraries(cert_app mbedtls)
+target_link_libraries(cert_app ${mbedtls_target})
 
 install(TARGETS ${executables}
         DESTINATION "bin"
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index ade67e2..e8241a3 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -100,9 +100,8 @@
     "                          Add NsCertType even if it is empty\n"    \
     "    md=%%s               default: SHA256\n"       \
     "                          possible values:\n"     \
-    "                          MD2, MD4, MD5, SHA1\n"  \
-    "                          SHA224, SHA256\n"       \
-    "                          SHA384, SHA512\n"       \
+    "                          MD2, MD4, MD5, RIPEMD160, SHA1,\n" \
+    "                          SHA224, SHA256, SHA384, SHA512\n" \
     "\n"
 
 
@@ -217,58 +216,14 @@
         }
         else if( strcmp( p, "md" ) == 0 )
         {
-            if( strcmp( q, "SHA256" ) == 0 )
+            const mbedtls_md_info_t *md_info =
+                mbedtls_md_info_from_string( q );
+            if( md_info == NULL )
             {
-                opt.md_alg = MBEDTLS_MD_SHA256;
-            }
-            else if( strcmp( q, "SHA224" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_SHA224;
-            }
-            else
-#if defined(MBEDTLS_MD5_C)
-            if( strcmp( q, "MD5" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_MD5;
-            }
-            else
-#endif /* MBEDTLS_MD5_C */
-#if defined(MBEDTLS_MD4_C)
-            if( strcmp( q, "MD4" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_MD4;
-            }
-            else
-#endif /* MBEDTLS_MD5_C */
-#if defined(MBEDTLS_MD2_C)
-            if( strcmp( q, "MD2" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_MD2;
-            }
-            else
-#endif /* MBEDTLS_MD2_C */
-#if defined(MBEDTLS_SHA1_C)
-            if( strcmp( q, "SHA1" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_SHA1;
-            }
-            else
-#endif /* MBEDTLS_SHA1_C */
-#if defined(MBEDTLS_SHA512_C)
-            if( strcmp( q, "SHA384" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_SHA384;
-            }
-            else
-            if( strcmp( q, "SHA512" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_SHA512;
-            }
-            else
-#endif /* MBEDTLS_SHA512_C */
-            {
+                mbedtls_printf( "Invalid argument for option %s\n", p );
                 goto usage;
             }
+            opt.md_alg = mbedtls_md_get_type( md_info );
         }
         else if( strcmp( p, "key_usage" ) == 0 )
         {
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 1eeb861..18174d8 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -118,8 +118,9 @@
     "    is_ca=%%d                default: 0 (disabled)\n"  \
     "    max_pathlen=%%d          default: -1 (none)\n"     \
     "    md=%%s                   default: SHA256\n"        \
-    "                            Supported values:\n"       \
-    "                            MD2, MD4, MD5, SHA1, SHA256, SHA512\n"\
+    "                            Supported values (if enabled):\n"      \
+    "                            MD2, MD4, MD5, RIPEMD160, SHA1,\n" \
+    "                            SHA224, SHA256, SHA384, SHA512\n" \
     "    version=%%d              default: 3\n"            \
     "                            Possible values: 1, 2, 3\n"\
     "    subject_identifier=%%s   default: 1\n"             \
@@ -353,27 +354,14 @@
         }
         else if( strcmp( p, "md" ) == 0 )
         {
-            if( strcmp( q, "SHA1" ) == 0 )
-                opt.md = MBEDTLS_MD_SHA1;
-            else if( strcmp( q, "SHA224" ) == 0 )
-                opt.md = MBEDTLS_MD_SHA224;
-            else if( strcmp( q, "SHA256" ) == 0 )
-                opt.md = MBEDTLS_MD_SHA256;
-            else if( strcmp( q, "SHA384" ) == 0 )
-                opt.md = MBEDTLS_MD_SHA384;
-            else if( strcmp( q, "SHA512" ) == 0 )
-                opt.md = MBEDTLS_MD_SHA512;
-            else if( strcmp( q, "MD2" ) == 0 )
-                opt.md = MBEDTLS_MD_MD2;
-            else if( strcmp( q, "MD4" ) == 0 )
-                opt.md = MBEDTLS_MD_MD4;
-            else if( strcmp( q, "MD5" ) == 0 )
-                opt.md = MBEDTLS_MD_MD5;
-            else
+            const mbedtls_md_info_t *md_info =
+                mbedtls_md_info_from_string( q );
+            if( md_info == NULL )
             {
                 mbedtls_printf( "Invalid argument for option %s\n", p );
                 goto usage;
             }
+            opt.md = mbedtls_md_get_type( md_info );
         }
         else if( strcmp( p, "version" ) == 0 )
         {
diff --git a/scripts/config.py b/scripts/config.py
index 017bba0..6c29981 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -184,6 +184,7 @@
     'MBEDTLS_NO_UDBL_DIVISION', # influences anything that uses bignum
     'MBEDTLS_PKCS11_C', # build dependency (libpkcs11-helper)
     'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature
+    'MBEDTLS_PSA_CRYPTO_CONFIG', # toggles old/new style PSA config
     'MBEDTLS_PSA_CRYPTO_SPM', # platform dependency (PSA SPM)
     'MBEDTLS_PSA_INJECT_ENTROPY', # build dependency (hook functions)
     'MBEDTLS_REMOVE_3DES_CIPHERSUITES', # removes a feature
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index cc68663..f8ce925 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,5 +1,5 @@
 set(libs
-    mbedtls
+    ${mbedtls_target}
 )
 
 # Set the project root directory if it's not already defined, as may happen if
@@ -43,7 +43,7 @@
     add_custom_command(
         OUTPUT test_suite_${data_name}.c
         COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_test_code.py -f ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${suite_name}.function -d ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${data_name}.data -t ${CMAKE_CURRENT_SOURCE_DIR}/suites/main_test.function -p ${CMAKE_CURRENT_SOURCE_DIR}/suites/host_test.function -s ${CMAKE_CURRENT_SOURCE_DIR}/suites --helpers-file ${CMAKE_CURRENT_SOURCE_DIR}/suites/helpers.function -o .
-        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_test_code.py mbedtls ${CMAKE_CURRENT_SOURCE_DIR}/suites/helpers.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/main_test.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/host_test.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${suite_name}.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${data_name}.data
+        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_test_code.py ${mbedtls_target} ${CMAKE_CURRENT_SOURCE_DIR}/suites/helpers.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/main_test.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/host_test.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${suite_name}.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${data_name}.data
     )
 
     add_executable(test_suite_${data_name} test_suite_${data_name}.c $<TARGET_OBJECTS:mbedtls_test>)
@@ -166,6 +166,7 @@
         link_to_source(seedfile)
     endif()
     link_to_source(compat.sh)
+    link_to_source(context-info.sh)
     link_to_source(data_files)
     link_to_source(scripts)
     link_to_source(ssl-opt.sh)
diff --git a/tests/context-info.sh b/tests/context-info.sh
index 150584b..68614ff 100755
--- a/tests/context-info.sh
+++ b/tests/context-info.sh
@@ -430,6 +430,11 @@
          -u "Too many bad symbols detected. File check aborted" \
          -n "Deserializing"
 
+run_test "Decoder continues past 0xff character" \
+         "def_b64_ff.bin" \
+         -n "No valid base64" \
+         -u "ciphersuite.* TLS-"
+
 
 # End of tests
 
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 88f265c..bf2f538 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -13,8 +13,10 @@
 ## Tools
 OPENSSL ?= openssl
 FAKETIME ?= faketime
-MBEDTLS_CERT_WRITE ?= $(PWD)/../../programs/x509/cert_write
-MBEDTLS_CERT_REQ ?= $(PWD)/../../programs/x509/cert_req
+
+TOP_DIR = ../..
+MBEDTLS_CERT_WRITE ?= $(TOP_DIR)/programs/x509/cert_write
+MBEDTLS_CERT_REQ ?= $(TOP_DIR)/programs/x509/cert_req
 
 
 ## Build the generated test data. Note that since the final outputs
diff --git a/tests/data_files/base64/def_b64_ff.bin b/tests/data_files/base64/def_b64_ff.bin
new file mode 100644
index 0000000..66aa827
--- /dev/null
+++ b/tests/data_files/base64/def_b64_ff.bin
@@ -0,0 +1,5 @@
+// Ensure that the b64 parser continues after encountering a 0xFF
+// character.  Note that this byte is invalid UTF-8, making this
+// entire file invalid UTF-8.  Use care when editing.
+// -> ÿ <-
+AhUAAH8AAA4AAABtAAAAAF6HQx3MqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG2QbHbUj8eGpdx5KVIebiwk0jvRj9/3m6BOSzpA7qBXeEunhqr3D11NE7ciGjeHMAAACAAAAAAAAAAAAAAAAAAV6HQx248L77RH0Z973tSYNQ8zBsz861CZG5/T09TJz3XodDHe/iJ+cgXb5An3zTdnTBtw3EWAb68T+gCE33GN8AAAAAAAAAAAAAAAEAAAAAAAAAAwAAAQAAAAAAAgAAAA==
diff --git a/tests/data_files/cert_md2.csr b/tests/data_files/cert_md2.csr
new file mode 100644
index 0000000..a8c39bd
--- /dev/null
+++ b/tests/data_files/cert_md2.csr
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
+GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1EMjCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
++CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
+stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
+iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
+Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
+aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBAgUA
+A4IBAQBPUqodRcH2ZUa8A3fQX/nxrIwWiLmQ9BaOI6G7vzEWVE1sxmkrHP+pXgi9
+1eFceN9xUBKEd+LmUPmHpObZ4nwRSprFj3DeIXpn9aSBr+jGY8RaaC9cMkaSq5Mb
+q65THEJ1xemIfZvbhjvNi/ycXXu/v1Gpj62dpIFGbm+o4AXQF2ocYGEM+X1u2eVn
+mnuuvPAHTllGjB0daTSYoQtMy3luPUEj0Yct3iVR1pUeTrHchOs9p5ACDZcf6D3x
+sm9atH2ZIaXo1c9SqHzdk/uLt/CwxQrn1WU1inwOkzjim2Yq9vWgpQypfGZdScXV
+oHOmuGG901WMMemzZXjoLi+8ZpVL
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/data_files/cert_md4.csr b/tests/data_files/cert_md4.csr
new file mode 100644
index 0000000..d8a3dbf
--- /dev/null
+++ b/tests/data_files/cert_md4.csr
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
+GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1ENDCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
++CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
+stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
+iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
+Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
+aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBAwUA
+A4IBAQAztRb+vAecvhelhszzCctzmhGs4TGmr9h4zddZoQ8dTdy1OCsnmU+yz3oh
+oiQjy7UPLt8DS2ZKhGhvwPvtwFh5icMWQVnv2kE4Evz8xJT12VRw+U6L5rfKmf/L
+mVNxsuk17MDyBcMlwuNk+CHrYVdrXhSWUH3UCQQUH1iqqBMKmNiPa1UGU0budZ9X
+HZjn9uqyyOGy8l3hffqjDxsDjZyBDf5aqKIdnvukdrUiacPdUYVF0fwK8d1/1PA9
+dA4JjTvz+tTK6mL9Ic9Pv+64v1vwMU4Qu8IJHk5x3I0e7KuK2A/lK6az2Vb6FAh6
+MkGpWB68T8FRBoVrWLOh+a9yNwyp
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/data_files/cert_md5.csr b/tests/data_files/cert_md5.csr
new file mode 100644
index 0000000..dc6792d
--- /dev/null
+++ b/tests/data_files/cert_md5.csr
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
+GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1ENTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
++CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
+stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
+iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
+Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
+aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBBAUA
+A4IBAQBNEvxgn3Pc62hsMgMz33IdeNpazeK3ae2gwQQFgL7qMp/kskfpIKF4m8eB
+YrmjKn9cqszRD606/ZtWYDwINUUc6O7bQGmpGIFd7bSPm/pbsajc6R7kzA/tD/bk
+G5zqu9Bj0x92hEwdku0zY+Hx9PgT2dK8M72iFylHBwT3X1tNyXhh7xWJ9RlAfSvN
+KdS6s3kRjK4qcir0MnflV5f2HD6r1v9cSVyme6eVLvOmup89z0cihH7NDwDJaYbi
+oqcKXFbro8/2ruEzPUS6U8NA9cjlX9DW8buIu4cQACVx5YevlwKoayYfXcRRvIFo
+OLiPq14TuZj3c0+HFOxWj4UBAjvI
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/include/test/drivers/keygen.h b/tests/include/test/drivers/key_management.h
similarity index 61%
rename from tests/include/test/drivers/keygen.h
rename to tests/include/test/drivers/key_management.h
index b72c65c..56f3ef8 100644
--- a/tests/include/test/drivers/keygen.h
+++ b/tests/include/test/drivers/key_management.h
@@ -1,5 +1,5 @@
 /*
- * Test driver for generating keys.
+ * Test driver for generating and verifying keys.
  */
 /*  Copyright The Mbed TLS Contributors
  *  SPDX-License-Identifier: Apache-2.0
@@ -17,8 +17,8 @@
  *  limitations under the License.
  */
 
-#ifndef PSA_CRYPTO_TEST_DRIVERS_KEYGEN_H
-#define PSA_CRYPTO_TEST_DRIVERS_KEYGEN_H
+#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"
@@ -36,18 +36,19 @@
     /* If not PSA_SUCCESS, return this error code instead of processing the
      * function call. */
     psa_status_t forced_status;
-    /* Count the amount of times one of the keygen driver functions is called. */
+    /* Count the amount of times one of the key management driver functions
+     * is called. */
     unsigned long hits;
-} test_driver_keygen_hooks_t;
+} test_driver_key_management_hooks_t;
 
-#define TEST_DRIVER_KEYGEN_INIT { NULL, 0, PSA_ERROR_NOT_SUPPORTED, 0 }
-static inline test_driver_keygen_hooks_t test_driver_keygen_hooks_init( void )
+#define TEST_DRIVER_KEY_MANAGEMENT_INIT { NULL, 0, PSA_ERROR_NOT_SUPPORTED, 0 }
+static inline test_driver_key_management_hooks_t test_driver_key_management_hooks_init( void )
 {
-    const test_driver_keygen_hooks_t v = TEST_DRIVER_KEYGEN_INIT;
+    const test_driver_key_management_hooks_t v = TEST_DRIVER_KEY_MANAGEMENT_INIT;
     return( v );
 }
 
-extern test_driver_keygen_hooks_t test_driver_keygen_hooks;
+extern test_driver_key_management_hooks_t test_driver_key_management_hooks;
 
 psa_status_t test_transparent_generate_key(
     const psa_key_attributes_t *attributes,
@@ -57,5 +58,10 @@
     const psa_key_attributes_t *attributes,
     uint8_t *key, size_t key_size, size_t *key_length );
 
+psa_status_t test_transparent_validate_key(const psa_key_attributes_t *attributes,
+                                           const uint8_t *data,
+                                           size_t data_length,
+                                           size_t *bits);
+
 #endif /* PSA_CRYPTO_DRIVER_TEST */
-#endif /* PSA_CRYPTO_TEST_DRIVERS_KEYGEN_H */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_KEY_MANAGEMENT_H */
diff --git a/tests/include/test/drivers/signature.h b/tests/include/test/drivers/signature.h
index e41892e..8abcb11 100644
--- a/tests/include/test/drivers/signature.h
+++ b/tests/include/test/drivers/signature.h
@@ -36,7 +36,7 @@
     /* If not PSA_SUCCESS, return this error code instead of processing the
      * function call. */
     psa_status_t forced_status;
-    /* Count the amount of times one of the keygen driver functions is called. */
+    /* Count the amount of times one of the signature driver functions is called. */
     unsigned long hits;
 } test_driver_signature_hooks_t;
 
diff --git a/tests/include/test/drivers/size.h b/tests/include/test/drivers/size.h
new file mode 100644
index 0000000..4bfe986
--- /dev/null
+++ b/tests/include/test/drivers/size.h
@@ -0,0 +1,95 @@
+/*
+ * Test driver for context size functions
+ */
+/*  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_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
+
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#include <psa/crypto_driver_common.h>
+
+typedef struct {
+    unsigned int context;
+} test_driver_key_context_t;
+
+/** \def TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
+ *
+ * This macro returns the base size for the key context. It is the size of the
+ * driver specific information stored in each key context.
+ */
+#define TEST_DRIVER_KEY_CONTEXT_BASE_SIZE          sizeof( test_driver_key_context_t )
+
+/** \def TEST_DRIVER_KEY_CONTEXT_KEY_PAIR_SIZE
+ *
+ * Number of bytes included in every key context for a key pair.
+ *
+ * This pair size is for an ECC 256-bit private/public key pair.
+ * Based on this value, the size of the private key can be derived by
+ * subtracting the public key size below from this one.
+ */
+
+#define TEST_DRIVER_KEY_CONTEXT_KEY_PAIR_SIZE      65
+
+/** \def TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE
+ *
+ * Number of bytes included in every key context for a public key.
+ *
+ * For ECC public keys, it needs 257 bits so 33 bytes.
+ */
+#define TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE    33
+
+/** \def TEST_DRIVER_KEY_CONTEXT_SYMMETRIC_FACTOR
+ *
+ * Every key context for a symmetric key includes this many times the key size.
+ */
+#define TEST_DRIVER_KEY_CONTEXT_SYMMETRIC_FACTOR   0
+
+/** \def TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY
+ *
+ * If this is true for a key pair, the key context includes space for the public key.
+ * If this is false, no additional space is added for the public key.
+ *
+ * For this instance, store the public key with the private one.
+ */
+#define TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY   1
+
+/** \def TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION
+ *
+ * If TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION is defined, the test driver
+ * provides a size_function entry point, otherwise, it does not.
+ *
+ * Some opaque drivers have the need to support a custom size for the storage
+ * of key and context information. The size_function provides the ability to
+ * provide that customization.
+ */
+//#define TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION
+
+#ifdef TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION
+size_t test_size_function(
+    const psa_key_type_t key_type,
+    const size_t key_bits );
+#endif /* TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION */
+
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_TEST_DRIVERS_SIZE_H */
diff --git a/tests/include/test/drivers/test_driver.h b/tests/include/test/drivers/test_driver.h
index 7ee8e5e..f26b795 100644
--- a/tests/include/test/drivers/test_driver.h
+++ b/tests/include/test/drivers/test_driver.h
@@ -23,7 +23,8 @@
 #define PSA_CRYPTO_TEST_DRIVER_LIFETIME 0x7fffff
 
 #include "test/drivers/signature.h"
-#include "test/drivers/keygen.h"
+#include "test/drivers/key_management.h"
 #include "test/drivers/cipher.h"
+#include "test/drivers/size.h"
 
 #endif /* PSA_CRYPTO_TEST_DRIVER_H */
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index c4979cc..2c7b179 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -53,10 +53,8 @@
 void mbedtls_test_platform_teardown( void );
 
 /**
- * \brief          This function translates an ASCII string encoding an
- *                 hexadecimal number into the encoded hexadecimal number. The
- *                 hexadecimal number is represented as an array of
- *                 unsigned char.
+ * \brief          This function decodes the hexadecimal representation of
+ *                 data.
  *
  * \note           The output buffer can be the same as the input buffer. For
  *                 any other overlapping of the input and output buffers, the
@@ -70,7 +68,7 @@
  *
  * \return         \c 0 on success.
  * \return         \c -1 if the output buffer is too small or the input string
- *                 is not a valid ASCII encoding of an hexadecimal number.
+ *                 is not a valid hexadecimal representation.
  */
 int mbedtls_test_unhexify( unsigned char *obuf, size_t obufmax,
                            const char *ibuf, size_t *len );
@@ -103,4 +101,93 @@
 int mbedtls_test_hexcmp( uint8_t * a, uint8_t * b,
                          uint32_t a_len, uint32_t b_len );
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+
+typedef struct
+{
+    const char *failure_condition;
+    const char *file;
+    int line;
+}
+mbedtls_test_param_failed_location_record_t;
+
+/**
+ * \brief   Get the location record of the last call to
+ *          mbedtls_test_param_failed().
+ *
+ * \note    The call expectation is set up and active until the next call to
+ *          mbedtls_test_param_failed_check_expected_call() or
+ *          mbedtls_param_failed() that cancels it.
+ */
+void mbedtls_test_param_failed_get_location_record(
+         mbedtls_test_param_failed_location_record_t *location_record );
+
+/**
+ * \brief   State that a call to mbedtls_param_failed() is expected.
+ *
+ * \note    The call expectation is set up and active until the next call to
+ *          mbedtls_test_param_failed_check_expected_call() or
+ *          mbedtls_param_failed that cancel it.
+ */
+void mbedtls_test_param_failed_expect_call( void );
+
+/**
+ * \brief   Check whether mbedtls_param_failed() has been called as expected.
+ *
+ * \note    Check whether mbedtls_param_failed() has been called between the
+ *          last call to mbedtls_test_param_failed_expect_call() and the call
+ *          to this function.
+ *
+ * \return  \c 0 Since the last call to mbedtls_param_failed_expect_call(),
+ *               mbedtls_param_failed() has been called.
+ *          \c -1 Otherwise.
+ */
+int mbedtls_test_param_failed_check_expected_call( void );
+
+/**
+ * \brief   Get the address of the object of type jmp_buf holding the execution
+ *          state information used by mbedtls_param_failed() to do a long jump.
+ *
+ * \note    If a call to mbedtls_param_failed() is not expected in the sense
+ *          that there is no call to mbedtls_test_param_failed_expect_call()
+ *          preceding it, then mbedtls_param_failed() will try to restore the
+ *          execution to the state stored in the jmp_buf object whose address
+ *          is returned by the present function.
+ *
+ * \note    This function is intended to provide the parameter of the
+ *          setjmp() function to set-up where mbedtls_param_failed() should
+ *          long-jump if it has to. It is foreseen to be used as:
+ *
+ *          setjmp( mbedtls_test_param_failed_get_state_buf() ).
+ *
+ * \note    The type of the returned value is not jmp_buf as jmp_buf is an
+ *          an array type (C specification) and a function cannot return an
+ *          array type.
+ *
+ * \note    The type of the returned value is not jmp_buf* as then the return
+ *          value couldn't be used by setjmp(), as its parameter's type is
+ *          jmp_buf.
+ *
+ * \return  Address of the object of type jmp_buf holding the execution state
+ *          information used by mbedtls_param_failed() to do a long jump.
+ */
+void* mbedtls_test_param_failed_get_state_buf( void );
+
+/**
+ * \brief   Reset the execution state used by mbedtls_param_failed() to do a
+ *          long jump.
+ *
+ * \note    If a call to mbedtls_param_failed() is not expected in the sense
+ *          that there is no call to mbedtls_test_param_failed_expect_call()
+ *          preceding it, then mbedtls_param_failed() will try to restore the
+ *          execution state that this function reset.
+ *
+ * \note    It is recommended to reset the execution state when the state
+ *          is not relevant anymore. That way an unexpected call to
+ *          mbedtls_param_failed() will not trigger a long jump with
+ *          undefined behavior but rather a long jump that will rather fault.
+ */
+void mbedtls_test_param_failed_reset_state( void );
+#endif /* MBEDTLS_CHECK_PARAMS */
+
 #endif /* TEST_HELPERS_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 578d03e..757a9ec 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1290,14 +1290,57 @@
     if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
 }
 
+component_test_psa_crypto_config_basic() {
+    # full plus MBEDTLS_PSA_CRYPTO_CONFIG
+    msg "build: full + MBEDTLS_PSA_CRYPTO_CONFIG"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -I../tests/include -O2" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full + MBEDTLS_PSA_CRYPTO_CONFIG"
+    make test
+}
+
+component_test_psa_crypto_config_no_driver() {
+    # full plus MBEDTLS_PSA_CRYPTO_CONFIG
+    msg "build: full + MBEDTLS_PSA_CRYPTO_CONFIG minus MBEDTLS_PSA_CRYPTO_DRIVERS"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+    scripts/config.py unset MBEDTLS_PSA_CRYPTO_DRIVERS
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -O2" LDFLAGS="$ASAN_CFLAGS"
+
+    msg "test: full + MBEDTLS_PSA_CRYPTO_CONFIG minus MBEDTLS_PSA_CRYPTO_DRIVERS"
+    make test
+}
+
+# This should be renamed to test and updated once the accelerator ECDSA code is in place and ready to test.
+component_build_psa_want_ecdsa_disabled_software() {
+    # full plus MBEDTLS_PSA_CRYPTO_CONFIG with PSA_WANT_ALG_ECDSA
+    # without MBEDTLS_ECDSA_C
+    # PSA_WANT_ALG_ECDSA and PSA_WANT_ALG_DETERMINISTIC_ECDSA are already
+    # set in include/psa/crypto_config.h
+    msg "build: full + MBEDTLS_PSA_CRYPTO_CONFIG + PSA_WANT_ALG_ECDSA without MBEDTLS_ECDSA_C"
+    scripts/config.py full
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
+    scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
+    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
+    scripts/config.py unset MBEDTLS_ECDSA_C
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+    # Need to define the correct symbol and include the test driver header path in order to build with the test driver
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_ECDSA -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA -I../tests/include -O2" LDFLAGS="$ASAN_CFLAGS"
+}
+
 component_test_check_params_functionality () {
     msg "build+test: MBEDTLS_CHECK_PARAMS functionality"
     scripts/config.py full # includes CHECK_PARAMS
     # Make MBEDTLS_PARAM_FAILED call mbedtls_param_failed().
     scripts/config.py unset MBEDTLS_CHECK_PARAMS_ASSERT
-    # Only build and run tests. Do not build sample programs, because
-    # they don't have a mbedtls_param_failed() function.
-    make CC=gcc CFLAGS='-Werror -O1' lib test
+    make CC=gcc CFLAGS='-Werror -O1' all test
 }
 
 component_test_check_params_without_platform () {
diff --git a/tests/scripts/list-macros.sh b/tests/scripts/list-macros.sh
index 15d2590..a8617a0 100755
--- a/tests/scripts/list-macros.sh
+++ b/tests/scripts/list-macros.sh
@@ -30,4 +30,10 @@
     | egrep -v '^(asm|inline|EMIT|_CRT_SECURE_NO_DEPRECATE)$|^MULADDC_' \
     | sort -u > macros
 
+# For include/mbedtls/config_psa.h need to ignore the MBEDTLS_xxx define
+# in that file since they may not be defined in include/psa/crypto_config.h
+# This line renames the potentially missing defines to ones that should
+# be present.
+sed -ne 's/^MBEDTLS_PSA_BUILTIN_/MBEDTLS_PSA_ACCEL_/p' <macros >>macros
+
 wc -l macros
diff --git a/tests/src/drivers/key_management.c b/tests/src/drivers/key_management.c
new file mode 100644
index 0000000..9bef4b6
--- /dev/null
+++ b/tests/src/drivers/key_management.c
@@ -0,0 +1,241 @@
+/*
+ * Test driver for generating and verifying keys.
+ * Currently only supports generating and verifying ECC keys.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
+#include "psa/crypto.h"
+#include "psa_crypto_core.h"
+#include "mbedtls/ecp.h"
+#include "mbedtls/error.h"
+
+#include "test/drivers/key_management.h"
+
+#include "test/random.h"
+
+#include <string.h>
+
+test_driver_key_management_hooks_t test_driver_key_management_hooks =
+    TEST_DRIVER_KEY_MANAGEMENT_INIT;
+
+psa_status_t test_transparent_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key, size_t key_size, size_t *key_length )
+{
+    ++test_driver_key_management_hooks.hits;
+
+    if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS )
+        return( test_driver_key_management_hooks.forced_status );
+
+    if( test_driver_key_management_hooks.forced_output != NULL )
+    {
+        if( test_driver_key_management_hooks.forced_output_length > key_size )
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+        memcpy( key, test_driver_key_management_hooks.forced_output,
+                test_driver_key_management_hooks.forced_output_length );
+        *key_length = test_driver_key_management_hooks.forced_output_length;
+        return( PSA_SUCCESS );
+    }
+
+    /* Copied from psa_crypto.c */
+#if defined(MBEDTLS_ECP_C)
+    if ( PSA_KEY_TYPE_IS_ECC( psa_get_key_type( attributes ) )
+         && PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) )
+    {
+        psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
+            psa_get_key_type( attributes ) );
+        mbedtls_ecp_group_id grp_id =
+            mbedtls_ecc_group_of_psa(
+                curve,
+                PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) ) );
+        const mbedtls_ecp_curve_info *curve_info =
+            mbedtls_ecp_curve_info_from_grp_id( grp_id );
+        mbedtls_ecp_keypair ecp;
+        mbedtls_test_rnd_pseudo_info rnd_info;
+        memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
+
+        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+        if( attributes->domain_parameters_size != 0 )
+            return( PSA_ERROR_NOT_SUPPORTED );
+        if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
+            return( PSA_ERROR_NOT_SUPPORTED );
+        if( curve_info->bit_size != psa_get_key_bits( attributes ) )
+            return( PSA_ERROR_INVALID_ARGUMENT );
+        mbedtls_ecp_keypair_init( &ecp );
+        ret = mbedtls_ecp_gen_key( grp_id, &ecp,
+                                   &mbedtls_test_rnd_pseudo_rand,
+                                   &rnd_info );
+        if( ret != 0 )
+        {
+            mbedtls_ecp_keypair_free( &ecp );
+            return( mbedtls_to_psa_error( ret ) );
+        }
+
+        /* Make sure to use export representation */
+        size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) );
+        if( key_size < bytes )
+        {
+            mbedtls_ecp_keypair_free( &ecp );
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+        }
+        psa_status_t status = mbedtls_to_psa_error(
+            mbedtls_mpi_write_binary( &ecp.d, key, bytes ) );
+
+        if( status == PSA_SUCCESS )
+        {
+            *key_length = bytes;
+        }
+        else
+        {
+            memset( key, 0, bytes );
+        }
+
+        mbedtls_ecp_keypair_free( &ecp );
+        return( status );
+    }
+    else
+#endif /* MBEDTLS_ECP_C */
+    return( PSA_ERROR_NOT_SUPPORTED );
+}
+
+psa_status_t test_opaque_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key, size_t key_size, size_t *key_length )
+{
+    (void) attributes;
+    (void) key;
+    (void) key_size;
+    (void) key_length;
+    return( PSA_ERROR_NOT_SUPPORTED );
+}
+
+psa_status_t test_transparent_validate_key(const psa_key_attributes_t *attributes,
+                                           const uint8_t *data,
+                                           size_t data_length,
+                                           size_t *bits)
+{
+    ++test_driver_key_management_hooks.hits;
+
+    if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS )
+        return( test_driver_key_management_hooks.forced_status );
+
+#if defined(MBEDTLS_ECP_C)
+    psa_key_type_t type = psa_get_key_type( attributes );
+    if ( PSA_KEY_TYPE_IS_ECC( type ) )
+    {
+        // Code mostly copied from psa_load_ecp_representation
+        psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( type );
+        mbedtls_ecp_group_id grp_id;
+        mbedtls_ecp_keypair ecp;
+        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+        if( psa_get_key_bits( attributes ) == 0 )
+        {
+            // Attempt auto-detect of curve bit size
+            size_t curve_size = data_length;
+
+            if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) &&
+                PSA_KEY_TYPE_ECC_GET_FAMILY( type ) != PSA_ECC_FAMILY_MONTGOMERY )
+            {
+                /* A Weierstrass public key is represented as:
+                 * - The byte 0x04;
+                 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
+                 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
+                 * So its data length is 2m+1 where m is the curve size in bits.
+                 */
+                if( ( data_length & 1 ) == 0 )
+                    return( PSA_ERROR_INVALID_ARGUMENT );
+                curve_size = data_length / 2;
+
+                /* Montgomery public keys are represented in compressed format, meaning
+                 * their curve_size is equal to the amount of input. */
+
+                /* Private keys are represented in uncompressed private random integer
+                 * format, meaning their curve_size is equal to the amount of input. */
+            }
+
+            grp_id = mbedtls_ecc_group_of_psa( curve, curve_size );
+        }
+        else
+        {
+            grp_id = mbedtls_ecc_group_of_psa( curve,
+                PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) ) );
+        }
+
+        const mbedtls_ecp_curve_info *curve_info =
+            mbedtls_ecp_curve_info_from_grp_id( grp_id );
+
+        if( attributes->domain_parameters_size != 0 )
+            return( PSA_ERROR_NOT_SUPPORTED );
+        if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
+            return( PSA_ERROR_NOT_SUPPORTED );
+
+        *bits = curve_info->bit_size;
+
+        mbedtls_ecp_keypair_init( &ecp );
+
+        status = mbedtls_to_psa_error(
+                    mbedtls_ecp_group_load( &ecp.grp, grp_id ) );
+        if( status != PSA_SUCCESS )
+            goto ecp_exit;
+
+        /* Load the key material. */
+        if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
+        {
+            /* Load the public value. */
+            status = mbedtls_to_psa_error(
+                mbedtls_ecp_point_read_binary( &ecp.grp, &ecp.Q,
+                                               data,
+                                               data_length ) );
+            if( status != PSA_SUCCESS )
+                goto ecp_exit;
+
+            /* Check that the point is on the curve. */
+            status = mbedtls_to_psa_error(
+                mbedtls_ecp_check_pubkey( &ecp.grp, &ecp.Q ) );
+        }
+        else
+        {
+            /* Load and validate the secret value. */
+            status = mbedtls_to_psa_error(
+                mbedtls_ecp_read_key( ecp.grp.id,
+                                      &ecp,
+                                      data,
+                                      data_length ) );
+        }
+
+ecp_exit:
+        mbedtls_ecp_keypair_free( &ecp );
+        return( status );
+    }
+    return( PSA_ERROR_NOT_SUPPORTED );
+#else
+    (void) data;
+    (void) data_length;
+    (void) bits;
+    return( PSA_ERROR_NOT_SUPPORTED );
+#endif /* MBEDTLS_ECP_C */
+}
+
+#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */
diff --git a/tests/src/drivers/keygen.c b/tests/src/drivers/keygen.c
deleted file mode 100644
index f15a4bc..0000000
--- a/tests/src/drivers/keygen.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Test driver for generating keys.
- * Currently only supports generating ECC keys.
- */
-/*  Copyright The Mbed TLS Contributors
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
-#include "psa/crypto.h"
-#include "psa_crypto_core.h"
-#include "mbedtls/ecp.h"
-#include "mbedtls/error.h"
-
-#include "test/drivers/keygen.h"
-
-#include "test/random.h"
-
-#include <string.h>
-
-test_driver_keygen_hooks_t test_driver_keygen_hooks = TEST_DRIVER_KEYGEN_INIT;
-
-psa_status_t test_transparent_generate_key(
-    const psa_key_attributes_t *attributes,
-    uint8_t *key, size_t key_size, size_t *key_length )
-{
-    ++test_driver_keygen_hooks.hits;
-
-    if( test_driver_keygen_hooks.forced_status != PSA_SUCCESS )
-        return( test_driver_keygen_hooks.forced_status );
-
-    if( test_driver_keygen_hooks.forced_output != NULL )
-    {
-        if( test_driver_keygen_hooks.forced_output_length > key_size )
-            return( PSA_ERROR_BUFFER_TOO_SMALL );
-        memcpy( key, test_driver_keygen_hooks.forced_output,
-                test_driver_keygen_hooks.forced_output_length );
-        *key_length = test_driver_keygen_hooks.forced_output_length;
-        return( PSA_SUCCESS );
-    }
-
-    /* Copied from psa_crypto.c */
-#if defined(MBEDTLS_ECP_C)
-    if ( PSA_KEY_TYPE_IS_ECC( psa_get_key_type( attributes ) )
-         && PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) )
-    {
-        psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( psa_get_key_type( attributes ) );
-        mbedtls_ecp_group_id grp_id =
-            mbedtls_ecc_group_of_psa( curve, PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) ) );
-        const mbedtls_ecp_curve_info *curve_info =
-            mbedtls_ecp_curve_info_from_grp_id( grp_id );
-        mbedtls_ecp_keypair ecp;
-        mbedtls_test_rnd_pseudo_info rnd_info;
-        memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
-
-        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-        if( attributes->domain_parameters_size != 0 )
-            return( PSA_ERROR_NOT_SUPPORTED );
-        if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
-            return( PSA_ERROR_NOT_SUPPORTED );
-        if( curve_info->bit_size != psa_get_key_bits( attributes ) )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-        mbedtls_ecp_keypair_init( &ecp );
-        ret = mbedtls_ecp_gen_key( grp_id, &ecp,
-                                   &mbedtls_test_rnd_pseudo_rand,
-                                   &rnd_info );
-        if( ret != 0 )
-        {
-            mbedtls_ecp_keypair_free( &ecp );
-            return( mbedtls_to_psa_error( ret ) );
-        }
-
-        /* Make sure to use export representation */
-        size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) );
-        if( key_size < bytes )
-        {
-            mbedtls_ecp_keypair_free( &ecp );
-            return( PSA_ERROR_BUFFER_TOO_SMALL );
-        }
-        psa_status_t status = mbedtls_to_psa_error(
-            mbedtls_mpi_write_binary( &ecp.d, key, bytes ) );
-
-        if( status == PSA_SUCCESS )
-        {
-            *key_length = bytes;
-        }
-
-        mbedtls_ecp_keypair_free( &ecp );
-        return( status );
-    }
-    else
-#endif /* MBEDTLS_ECP_C */
-    return( PSA_ERROR_NOT_SUPPORTED );
-}
-
-psa_status_t test_opaque_generate_key(
-    const psa_key_attributes_t *attributes,
-    uint8_t *key, size_t key_size, size_t *key_length )
-{
-    (void) attributes;
-    (void) key;
-    (void) key_size;
-    (void) key_length;
-    return( PSA_ERROR_NOT_SUPPORTED );
-}
-
-#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */
diff --git a/tests/src/drivers/signature.c b/tests/src/drivers/signature.c
index 028d24a..cea0351 100644
--- a/tests/src/drivers/signature.c
+++ b/tests/src/drivers/signature.c
@@ -262,6 +262,8 @@
     (void) alg;
     (void) hash;
     (void) hash_length;
+    (void) signature;
+    (void) signature_length;
 #endif /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
           defined(MBEDTLS_SHA256_C) */
 
diff --git a/tests/src/drivers/size.c b/tests/src/drivers/size.c
new file mode 100644
index 0000000..16a8692
--- /dev/null
+++ b/tests/src/drivers/size.c
@@ -0,0 +1,42 @@
+/*
+ * Test driver for retrieving key context size.
+ * Only used by opaque drivers.
+ */
+/*  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
+
+#include "test/drivers/size.h"
+
+#ifdef TEST_KEY_CONTEXT_SIZE_FUNCTION
+size_t test_size_function(
+    const psa_key_type_t key_type,
+    const size_t key_bits )
+{
+    (void) key_type;
+    (void) key_bits;
+    return 0;
+}
+#endif /*TEST_KEY_CONTEXT_SIZE_FUNCTION */
+
+#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index f385079..a18f1d4 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -19,10 +19,34 @@
 #include <test/macros.h>
 #include <string.h>
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+#include <setjmp.h>
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* Static global variables */
+
+#if defined(MBEDTLS_CHECK_PARAMS)
+typedef struct
+{
+    uint8_t expected_call;
+    uint8_t expected_call_happened;
+
+    jmp_buf state;
+
+    mbedtls_test_param_failed_location_record_t location_record;
+}
+param_failed_ctx_t;
+static param_failed_ctx_t param_failed_ctx;
+#endif
+
 #if defined(MBEDTLS_PLATFORM_C)
 static mbedtls_platform_context platform_ctx;
 #endif
 
+/*----------------------------------------------------------------------------*/
+/* Helper Functions */
+
 int mbedtls_test_platform_setup( void )
 {
     int ret = 0;
@@ -159,3 +183,64 @@
     }
     return ret;
 }
+
+#if defined(MBEDTLS_CHECK_PARAMS)
+void mbedtls_test_param_failed_get_location_record(
+         mbedtls_test_param_failed_location_record_t *location_record )
+{
+    *location_record = param_failed_ctx.location_record;
+}
+
+void mbedtls_test_param_failed_expect_call( void )
+{
+    param_failed_ctx.expected_call_happened = 0;
+    param_failed_ctx.expected_call = 1;
+}
+
+int mbedtls_test_param_failed_check_expected_call( void )
+{
+    param_failed_ctx.expected_call = 0;
+
+    if( param_failed_ctx.expected_call_happened != 0 )
+        return( 0 );
+
+    return( -1 );
+}
+
+void* mbedtls_test_param_failed_get_state_buf( void )
+{
+    return &param_failed_ctx.state;
+}
+
+void mbedtls_test_param_failed_reset_state( void )
+{
+    memset( param_failed_ctx.state, 0, sizeof( param_failed_ctx.state ) );
+}
+
+void mbedtls_param_failed( const char *failure_condition,
+                           const char *file,
+                           int line )
+{
+    /* Record the location of the failure */
+    param_failed_ctx.location_record.failure_condition = failure_condition;
+    param_failed_ctx.location_record.file = file;
+    param_failed_ctx.location_record.line = line;
+
+    /* If we are testing the callback function...  */
+    if( param_failed_ctx.expected_call != 0 )
+    {
+        param_failed_ctx.expected_call = 0;
+        param_failed_ctx.expected_call_happened = 1;
+    }
+    else
+    {
+        /* ...else try a long jump. If the execution state has not been set-up
+         * or reset then the long jump buffer is all zero's and the call will
+         * with high probability fault, emphasizing there is something to look
+         * at.
+         */
+
+        longjmp( param_failed_ctx.state, 1 );
+    }
+}
+#endif /* MBEDTLS_CHECK_PARAMS */
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 653d88d..59e7974 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -634,6 +634,23 @@
     fi
 }
 
+# Compare file content
+# Usage: find_in_both pattern file1 file2
+# extract from file1 the first line matching the pattern
+# check in file2 that the same line can be found
+find_in_both() {
+        srv_pattern=$(grep -m 1 "$1" "$2");
+        if [ -z "$srv_pattern" ]; then
+                return 1;
+        fi
+
+        if grep "$srv_pattern" $3 >/dev/null; then :
+                return 0;
+        else
+                return 1;
+        fi
+}
+
 # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]]
 # Options:  -s pattern  pattern that must be present in server output
 #           -c pattern  pattern that must be present in client output
@@ -643,6 +660,7 @@
 #           -C pattern  pattern that must be absent in client output
 #           -U pattern  lines after pattern must be unique in server output
 #           -F call shell function on server output
+#           -g call shell function on server and client output
 run_test() {
     NAME="$1"
     shift 1
@@ -865,6 +883,12 @@
                     return
                 fi
                 ;;
+            "-g")
+                if ! eval "$2 '$SRV_OUT' '$CLI_OUT'"; then
+                    fail "function call to '$2' failed on Server and Client output"
+                    return
+                fi
+                ;;
 
             *)
                 echo "Unknown test: $1" >&2
@@ -8713,6 +8737,539 @@
             0 \
             -s "fragmenting handshake message"
 
+# Tests for DTLS-SRTP (RFC 5764)
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported" \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -C "error"
+
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=5 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one matching profile." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one different profile." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
+          -S "selected srtp profile" \
+          -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server doesn't support use_srtp extension." \
+          "$P_SRV dtls=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. mki used" \
+          "$P_SRV dtls=1 use_srtp=1 support_mki=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "dumping 'using mki' (8 bytes)" \
+          -s "DTLS-SRTP key material is"\
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "dumping 'sending mki' (8 bytes)" \
+          -c "dumping 'received mki' (8 bytes)" \
+          -c "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -g "find_in_both '^ *DTLS-SRTP mki value: [0-9A-F]*$'"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. server doesn't support mki." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -s "DTLS-SRTP no mki value negotiated"\
+          -S "dumping 'using mki' (8 bytes)" \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -c "DTLS-SRTP no mki value negotiated"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -c "dumping 'sending mki' (8 bytes)" \
+          -C "dumping 'received mki' (8 bytes)" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_80"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one matching profile. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -g "find_in_both '^ *Keying material: [0-9A-F]*$'"\
+          -c "SRTP Extension negotiated, profile=SRTP_AES128_CM_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one different profile. openssl client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -S "selected srtp profile" \
+          -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
+          -C "SRTP Extension negotiated, profile"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl client" \
+          "$P_SRV dtls=1 debug_level=3" \
+          "$O_CLI -dtls1 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          0 \
+          -s "found use_srtp extension" \
+          -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
+          -C "SRTP Extension negotiated, profile"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. openssl server" \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32:SRTP_AES128_CM_SHA1_80 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one matching profile. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server and Client support only one different profile. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP server doesn't support use_srtp extension. openssl server" \
+          "$O_SRV -dtls1" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+run_test  "DTLS-SRTP all profiles supported. server doesn't support mki. openssl server." \
+          "$O_SRV -dtls1 -verify 0 -use_srtp SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32 -keymatexport 'EXTRACTOR-dtls_srtp' -keymatexportlen 60" \
+          "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -c "DTLS-SRTP no mki value negotiated"\
+          -c "dumping 'sending mki' (8 bytes)" \
+          -C "dumping 'received mki' (8 bytes)" \
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP all profiles supported. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_80"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "SRTP profile: SRTP_NULL_HMAC_SHA1_80"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "SRTP profile: SRTP_NULL_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -s "selected srtp profile" \
+          -s "server hello, adding use_srtp extension" \
+          -s "DTLS-SRTP key material is"\
+          -c "SRTP profile: SRTP_AES128_CM_HMAC_SHA1_32"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server and Client support only one different profile. gnutls client." \
+          "$P_SRV dtls=1 use_srtp=1 srtp_force_profile=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32 --insecure 127.0.0.1" \
+          0 \
+          -s "found use_srtp extension" \
+          -s "found srtp profile" \
+          -S "selected srtp profile" \
+          -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
+          -C "SRTP profile:"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls client" \
+          "$P_SRV dtls=1 debug_level=3" \
+          "$G_CLI -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32 --insecure 127.0.0.1" \
+          0 \
+          -s "found use_srtp extension" \
+          -S "server hello, adding use_srtp extension" \
+          -S "DTLS-SRTP key material is"\
+          -C "SRTP profile:"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP all profiles supported. gnutls server" \
+          "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server supports all profiles. Client supports all profiles, in different order. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server supports all profiles. Client supports one profile. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_NULL_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_AES128_CM_HMAC_SHA1_80:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server supports one profile. Client supports all profiles. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_NULL_HMAC_SHA1_80" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server and Client support only one matching profile. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=2 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile: MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server and Client support only one different profile. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 srtp_force_profile=6 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP server doesn't support use_srtp extension. gnutls server" \
+          "$G_SRV -u" \
+          "$P_CLI dtls=1 use_srtp=1 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -C "found use_srtp extension" \
+          -C "found srtp profile" \
+          -C "selected srtp profile" \
+          -C "DTLS-SRTP key material is"\
+          -C "error"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_SRTP
+requires_gnutls
+run_test  "DTLS-SRTP all profiles supported. mki used. gnutls server." \
+          "$G_SRV -u --srtp-profiles=SRTP_AES128_CM_HMAC_SHA1_80:SRTP_AES128_CM_HMAC_SHA1_32:SRTP_NULL_HMAC_SHA1_80:SRTP_NULL_SHA1_32" \
+          "$P_CLI dtls=1 use_srtp=1 mki=542310ab34290481 debug_level=3" \
+          0 \
+          -c "client hello, adding use_srtp extension" \
+          -c "found use_srtp extension" \
+          -c "found srtp profile" \
+          -c "selected srtp profile" \
+          -c "DTLS-SRTP key material is"\
+          -c "DTLS-SRTP mki value:"\
+          -c "dumping 'sending mki' (8 bytes)" \
+          -c "dumping 'received mki' (8 bytes)" \
+          -C "error"
+
 # Tests for specific things with "unreliable" UDP connection
 
 not_with_valgrind # spurious resend due to timeout
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index ec43d13..aafcf5c 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -74,16 +74,6 @@
 #define DISPATCH_UNSUPPORTED_SUITE      -5  /* Test suite not supported by the
                                                build */
 
-typedef enum
-{
-    PARAMFAIL_TESTSTATE_IDLE = 0,           /* No parameter failure call test */
-    PARAMFAIL_TESTSTATE_PENDING,            /* Test call to the parameter failure
-                                             * is pending */
-    PARAMFAIL_TESTSTATE_CALLED              /* The test call to the parameter
-                                             * failure function has been made */
-} paramfail_test_state_t;
-
-
 /*----------------------------------------------------------------------------*/
 /* Macros */
 
@@ -131,6 +121,7 @@
     TEST_ASSERT( ( expr1 ) == ( expr2 ) )
 
 /** Allocate memory dynamically and fail the test case if this fails.
+ * The allocated memory will be filled with zeros.
  *
  * You must set \p pointer to \c NULL before calling this macro and
  * put `mbedtls_free( pointer )` in the test's cleanup code.
@@ -237,15 +228,16 @@
  *
  * \param   TEST                The test expression to be tested.
  */
-#define TEST_INVALID_PARAM_RET( PARAM_ERR_VALUE, TEST )                     \
-    do {                                                                    \
-        test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_PENDING;       \
-        if( (TEST) != (PARAM_ERR_VALUE) ||                                  \
-            test_info.paramfail_test_state != PARAMFAIL_TESTSTATE_CALLED )  \
-        {                                                                   \
-            test_fail( #TEST, __LINE__, __FILE__ );                         \
-            goto exit;                                                      \
-        }                                                                   \
+#define TEST_INVALID_PARAM_RET( PARAM_ERR_VALUE, TEST )                 \
+    do {                                                                \
+        mbedtls_test_param_failed_expect_call( );                       \
+        if( ( ( TEST ) != ( PARAM_ERR_VALUE ) ) ||                      \
+            ( mbedtls_test_param_failed_check_expected_call( ) != 0 ) ) \
+        {                                                               \
+            test_fail( #TEST, __LINE__, __FILE__ );                     \
+            goto exit;                                                  \
+        }                                                               \
+        mbedtls_test_param_failed_check_expected_call( );               \
    } while( 0 )
 
 /**
@@ -268,16 +260,17 @@
  *
  * \param   TEST                The test expression to be tested.
  */
-#define TEST_INVALID_PARAM( TEST )                                          \
-    do {                                                                    \
-        memcpy(jmp_tmp, param_fail_jmp, sizeof(jmp_buf));                   \
-        if( setjmp( param_fail_jmp ) == 0 )                                 \
-        {                                                                   \
-            TEST;                                                           \
-            test_fail( #TEST, __LINE__, __FILE__ );                         \
-            goto exit;                                                      \
-        }                                                                   \
-        memcpy(param_fail_jmp, jmp_tmp, sizeof(jmp_buf));                   \
+#define TEST_INVALID_PARAM( TEST )                                       \
+    do {                                                                 \
+        memcpy( jmp_tmp, mbedtls_test_param_failed_get_state_buf( ),     \
+                sizeof( jmp_tmp ) );                                     \
+        if( setjmp(  mbedtls_test_param_failed_get_state_buf( ) ) == 0 ) \
+        {                                                                \
+            TEST;                                                        \
+            test_fail( #TEST, __LINE__, __FILE__ );                      \
+            goto exit;                                                   \
+        }                                                                \
+        mbedtls_test_param_failed_reset_state( );                        \
     } while( 0 )
 #endif /* MBEDTLS_CHECK_PARAMS && !MBEDTLS_PARAM_FAILED_ALT */
 
@@ -359,7 +352,6 @@
 
 typedef struct
 {
-    paramfail_test_state_t paramfail_test_state;
     test_result_t result;
     const char *test;
     const char *filename;
@@ -370,7 +362,6 @@
 static test_info_t test_info;
 
 #if defined(MBEDTLS_CHECK_PARAMS)
-jmp_buf param_fail_jmp;
 jmp_buf jmp_tmp;
 #endif
 
@@ -427,30 +418,6 @@
     test_info.filename = filename;
 }
 
-#if defined(MBEDTLS_CHECK_PARAMS)
-void mbedtls_param_failed( const char *failure_condition,
-                           const char *file,
-                           int line )
-{
-    /* If we are testing the callback function...  */
-    if( test_info.paramfail_test_state == PARAMFAIL_TESTSTATE_PENDING )
-    {
-        test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_CALLED;
-    }
-    else
-    {
-        /* ...else we treat this as an error */
-
-        /* Record the location of the failure, but not as a failure yet, in case
-         * it was part of the test */
-        test_fail( failure_condition, line, file );
-        test_info.result = TEST_RESULT_SUCCESS;
-
-        longjmp( param_fail_jmp, 1 );
-    }
-}
-#endif
-
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 static int redirect_output( FILE* out_stream, const char* path )
 {
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index cce2899..db53e97 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -683,7 +683,6 @@
             if( unmet_dep_count == 0 )
             {
                 test_info.result = TEST_RESULT_SUCCESS;
-                test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_IDLE;
                 test_info.step = (unsigned long)( -1 );
 
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 6901256..256224e 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -165,17 +165,23 @@
 void execute_function_ptr(TestWrapper_t fp, void **params)
 {
 #if defined(MBEDTLS_CHECK_PARAMS)
-    if ( setjmp( param_fail_jmp ) == 0 )
+    mbedtls_test_param_failed_location_record_t location_record;
+
+    if ( setjmp( mbedtls_test_param_failed_get_state_buf( ) ) == 0 )
     {
         fp( params );
     }
     else
     {
         /* Unexpected parameter validation error */
+        mbedtls_test_param_failed_get_location_record( &location_record );
+        test_fail( location_record.failure_condition,
+                   location_record.line,
+                   location_record.file );
         test_info.result = TEST_RESULT_FAILED;
     }
 
-    memset( param_fail_jmp, 0, sizeof(jmp_buf) );
+    mbedtls_test_param_failed_reset_state( );
 #else
     fp( params );
 #endif
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index 1d453db..754a167 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -9,7 +9,7 @@
 
 /* BEGIN_CASE */
 void aes_encrypt_ecb( data_t * key_str, data_t * src_str,
-                      data_t * hex_dst_string, int setkey_result )
+                      data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -23,8 +23,7 @@
     {
         TEST_ASSERT( mbedtls_aes_crypt_ecb( &ctx, MBEDTLS_AES_ENCRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          16, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
     }
 
 exit:
@@ -34,7 +33,7 @@
 
 /* BEGIN_CASE */
 void aes_decrypt_ecb( data_t * key_str, data_t * src_str,
-                      data_t * hex_dst_string, int setkey_result )
+                      data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -48,8 +47,7 @@
     {
         TEST_ASSERT( mbedtls_aes_crypt_ecb( &ctx, MBEDTLS_AES_DECRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          16, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
     }
 
 exit:
@@ -59,7 +57,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void aes_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                      data_t * src_str, data_t * hex_dst_string,
+                      data_t * src_str, data_t * dst,
                       int cbc_result )
 {
     unsigned char output[100];
@@ -74,9 +72,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
     }
 
 exit:
@@ -86,7 +83,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void aes_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                      data_t * src_str, data_t * hex_dst_string,
+                      data_t * src_str, data_t * dst,
                       int cbc_result )
 {
     unsigned char output[100];
@@ -100,9 +97,8 @@
     if( cbc_result == 0)
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
     }
 
 exit:
@@ -236,7 +232,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aes_encrypt_cfb128( data_t * key_str, data_t * iv_str,
-                         data_t * src_str, data_t * hex_dst_string )
+                         data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -249,8 +245,7 @@
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_ENCRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      16, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
 
 exit:
     mbedtls_aes_free( &ctx );
@@ -259,7 +254,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aes_decrypt_cfb128( data_t * key_str, data_t * iv_str,
-                         data_t * src_str, data_t * hex_dst_string )
+                         data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -272,8 +267,7 @@
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_DECRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      16, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
 
 exit:
     mbedtls_aes_free( &ctx );
@@ -282,7 +276,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aes_encrypt_cfb8( data_t * key_str, data_t * iv_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -294,9 +288,8 @@
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      src_str->len,
-                                      hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 
 exit:
     mbedtls_aes_free( &ctx );
@@ -305,7 +298,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aes_decrypt_cfb8( data_t * key_str, data_t * iv_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -317,9 +310,8 @@
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      src_str->len,
-                                      hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 
 exit:
     mbedtls_aes_free( &ctx );
@@ -329,17 +321,15 @@
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_OFB */
 void aes_encrypt_ofb( int fragment_size, data_t *key_str,
                       data_t *iv_str, data_t *src_str,
-                      char *expected_output_string)
+                      data_t *expected_output )
 {
     unsigned char output[32];
-    unsigned char output_string[65];
     mbedtls_aes_context ctx;
     size_t iv_offset = 0;
     int in_buffer_len;
     unsigned char* src_str_next;
 
     memset( output, 0x00, sizeof( output ) );
-    memset( output_string, 0x00, sizeof( output_string ) );
     mbedtls_aes_init( &ctx );
 
     TEST_ASSERT( (size_t)fragment_size < sizeof( output ) );
@@ -354,12 +344,10 @@
         TEST_ASSERT( mbedtls_aes_crypt_ofb( &ctx, fragment_size, &iv_offset,
                                             iv_str->x, src_str_next, output ) == 0 );
 
-        mbedtls_test_hexify( output_string, output, fragment_size );
-        TEST_ASSERT( strncmp( (char *) output_string, expected_output_string,
-                              ( 2 * fragment_size ) ) == 0 );
+        TEST_ASSERT( memcmp( output, expected_output->x, fragment_size ) == 0 );
 
         in_buffer_len -= fragment_size;
-        expected_output_string += ( fragment_size * 2 );
+        expected_output->x += fragment_size;
         src_str_next += fragment_size;
 
         if( in_buffer_len < fragment_size )
diff --git a/tests/suites/test_suite_arc4.function b/tests/suites/test_suite_arc4.function
index 9aa4913..c1e2386 100644
--- a/tests/suites/test_suite_arc4.function
+++ b/tests/suites/test_suite_arc4.function
@@ -8,8 +8,7 @@
  */
 
 /* BEGIN_CASE */
-void mbedtls_arc4_crypt( data_t * src_str, data_t * key_str,
-                         data_t * hex_dst_string )
+void mbedtls_arc4_crypt( data_t * src_str, data_t * key_str, data_t * dst )
 {
     unsigned char dst_str[1000];
     mbedtls_arc4_context ctx;
@@ -19,11 +18,11 @@
 
 
     mbedtls_arc4_setup(&ctx, key_str->x, key_str->len);
-    TEST_ASSERT( mbedtls_arc4_crypt(&ctx, src_str->len, src_str->x, dst_str ) == 0 );
+    TEST_ASSERT( mbedtls_arc4_crypt(&ctx, src_str->len,
+                                    src_str->x, dst_str ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( dst_str, hex_dst_string->x,
-                                      src_str->len,
-                                      hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( dst_str, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 
 exit:
     mbedtls_arc4_free( &ctx );
diff --git a/tests/suites/test_suite_aria.function b/tests/suites/test_suite_aria.function
index d08c39d..6d6a203 100644
--- a/tests/suites/test_suite_aria.function
+++ b/tests/suites/test_suite_aria.function
@@ -207,14 +207,12 @@
 
 /* BEGIN_CASE */
 void aria_encrypt_ecb( data_t *key_str, data_t *src_str,
-                       char *hex_dst_string, int setkey_result )
+                       data_t *expected_output, int setkey_result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
     size_t i;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -227,9 +225,9 @@
             TEST_ASSERT( mbedtls_aria_crypt_ecb( &ctx, src_str->x + i,
                                                  output + i ) == 0 );
         }
-        mbedtls_test_hexify( dst_str, output, src_str->len );
 
-        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+        ASSERT_COMPARE( output, expected_output->len,
+                        expected_output->x, expected_output->len );
     }
 
 exit:
@@ -239,14 +237,12 @@
 
 /* BEGIN_CASE */
 void aria_decrypt_ecb( data_t *key_str, data_t *src_str,
-                       char *hex_dst_string, int setkey_result )
+                       data_t *expected_output, int setkey_result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
     size_t i;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -259,9 +255,9 @@
             TEST_ASSERT( mbedtls_aria_crypt_ecb( &ctx, src_str->x + i,
                                                  output + i ) == 0 );
         }
-        mbedtls_test_hexify( dst_str, output, src_str->len );
 
-        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+        ASSERT_COMPARE( output, expected_output->len,
+                        expected_output->x, expected_output->len );
     }
 
 exit:
@@ -271,14 +267,12 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void aria_encrypt_cbc( data_t *key_str, data_t *iv_str,
-                       data_t *src_str, char *hex_dst_string,
+                       data_t *src_str, data_t *expected_output,
                        int cbc_result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -288,9 +282,8 @@
                                          output ) == cbc_result );
     if( cbc_result == 0 )
     {
-        mbedtls_test_hexify( dst_str, output, src_str->len );
-
-        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+        ASSERT_COMPARE( output, expected_output->len,
+                        expected_output->x, expected_output->len );
     }
 
 exit:
@@ -300,14 +293,12 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void aria_decrypt_cbc( data_t *key_str, data_t *iv_str,
-                       data_t *src_str, char *hex_dst_string,
+                       data_t *src_str, data_t *expected_output,
                        int cbc_result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -317,9 +308,8 @@
                                          output ) == cbc_result );
     if( cbc_result == 0 )
     {
-        mbedtls_test_hexify( dst_str, output, src_str->len );
-
-        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+        ASSERT_COMPARE( output, expected_output->len,
+                        expected_output->x, expected_output->len );
     }
 
 exit:
@@ -329,15 +319,13 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aria_encrypt_cfb128( data_t *key_str, data_t *iv_str,
-                          data_t *src_str, char *hex_dst_string,
+                          data_t *src_str, data_t *expected_output,
                           int result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
     size_t iv_offset = 0;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -346,9 +334,9 @@
                                             src_str->len, &iv_offset,
                                             iv_str->x, src_str->x, output )
                  == result );
-    mbedtls_test_hexify( dst_str, output, src_str->len );
 
-    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output->len,
+                    expected_output->x, expected_output->len );
 
 exit:
     mbedtls_aria_free( &ctx );
@@ -357,15 +345,13 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aria_decrypt_cfb128( data_t *key_str, data_t *iv_str,
-                          data_t *src_str, char *hex_dst_string,
+                          data_t *src_str, data_t *expected_output,
                           int result  )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
     size_t iv_offset = 0;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -374,9 +360,9 @@
                                             src_str->len, &iv_offset,
                                             iv_str->x, src_str->x, output )
                  == result );
-    mbedtls_test_hexify( dst_str, output, src_str->len );
 
-    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output->len,
+                    expected_output->x, expected_output->len );
 
 exit:
     mbedtls_aria_free( &ctx );
@@ -385,16 +371,14 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
 void aria_encrypt_ctr( data_t *key_str, data_t *iv_str,
-                       data_t *src_str, char *hex_dst_string,
+                       data_t *src_str, data_t *expected_output,
                        int result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     unsigned char blk[MBEDTLS_ARIA_BLOCKSIZE];
     mbedtls_aria_context ctx;
     size_t iv_offset = 0;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -402,9 +386,9 @@
     TEST_ASSERT( mbedtls_aria_crypt_ctr( &ctx, src_str->len, &iv_offset,
                                          iv_str->x, blk, src_str->x, output )
                  == result );
-    mbedtls_test_hexify( dst_str, output, src_str->len );
 
-    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output->len,
+                    expected_output->x, expected_output->len );
 
 exit:
     mbedtls_aria_free( &ctx );
@@ -413,16 +397,14 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
 void aria_decrypt_ctr( data_t *key_str, data_t *iv_str,
-                       data_t *src_str, char *hex_dst_string,
+                       data_t *src_str, data_t *expected_output,
                        int result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     unsigned char blk[MBEDTLS_ARIA_BLOCKSIZE];
     mbedtls_aria_context ctx;
     size_t iv_offset = 0;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -430,9 +412,9 @@
     TEST_ASSERT( mbedtls_aria_crypt_ctr( &ctx, src_str->len, &iv_offset,
                                          iv_str->x, blk, src_str->x, output )
                  == result );
-    mbedtls_test_hexify( dst_str, output, src_str->len );
 
-    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output->len,
+                    expected_output->x, expected_output->len );
 
 exit:
     mbedtls_aria_free( &ctx );
diff --git a/tests/suites/test_suite_blowfish.function b/tests/suites/test_suite_blowfish.function
index eb6891c..f89353c 100644
--- a/tests/suites/test_suite_blowfish.function
+++ b/tests/suites/test_suite_blowfish.function
@@ -167,7 +167,7 @@
 
 /* BEGIN_CASE */
 void blowfish_encrypt_ecb( data_t * key_str, data_t * src_str,
-                           data_t * hex_dst_string, int setkey_result )
+                           data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_blowfish_context ctx;
@@ -181,8 +181,7 @@
     {
         TEST_ASSERT( mbedtls_blowfish_crypt_ecb( &ctx, MBEDTLS_BLOWFISH_ENCRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          8, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
     }
 
 exit:
@@ -192,7 +191,7 @@
 
 /* BEGIN_CASE */
 void blowfish_decrypt_ecb( data_t * key_str, data_t * src_str,
-                           data_t * hex_dst_string, int setkey_result )
+                           data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_blowfish_context ctx;
@@ -206,8 +205,7 @@
     {
         TEST_ASSERT( mbedtls_blowfish_crypt_ecb( &ctx, MBEDTLS_BLOWFISH_DECRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          8, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
     }
 
 exit:
@@ -217,7 +215,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void blowfish_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string,
+                           data_t * src_str, data_t * dst,
                            int cbc_result )
 {
     unsigned char output[100];
@@ -233,9 +231,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
     }
 
 exit:
@@ -245,7 +242,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void blowfish_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string,
+                           data_t * src_str, data_t * dst,
                            int cbc_result )
 {
     unsigned char output[100];
@@ -260,9 +257,8 @@
     if( cbc_result == 0)
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -272,8 +268,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void blowfish_encrypt_cfb64( data_t * key_str, data_t * iv_str,
-                             data_t * src_str, data_t * hex_dst_string
-                             )
+                             data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_blowfish_context ctx;
@@ -286,9 +281,8 @@
     mbedtls_blowfish_setkey( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_blowfish_crypt_cfb64( &ctx, MBEDTLS_BLOWFISH_ENCRYPT, src_str->len, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      src_str->len,
-                                      hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                      dst->len ) == 0 );
 
 exit:
     mbedtls_blowfish_free( &ctx );
@@ -297,8 +291,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void blowfish_decrypt_cfb64( data_t * key_str, data_t * iv_str,
-                             data_t * src_str, data_t * hex_dst_string
-                             )
+                             data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_blowfish_context ctx;
@@ -311,9 +304,8 @@
     mbedtls_blowfish_setkey( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_blowfish_crypt_cfb64( &ctx, MBEDTLS_BLOWFISH_DECRYPT, src_str->len, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      src_str->len,
-                                      hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                      dst->len ) == 0 );
 
 exit:
     mbedtls_blowfish_free( &ctx );
@@ -322,7 +314,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
 void blowfish_encrypt_ctr( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string )
+                           data_t * src_str, data_t * dst )
 {
     unsigned char stream_str[100];
     unsigned char output[100];
@@ -337,9 +329,8 @@
     mbedtls_blowfish_setkey( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_blowfish_crypt_ctr( &ctx, src_str->len, &iv_offset, iv_str->x, stream_str, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      src_str->len,
-                                      hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                      dst->len ) == 0 );
 
 exit:
     mbedtls_blowfish_free( &ctx );
diff --git a/tests/suites/test_suite_camellia.function b/tests/suites/test_suite_camellia.function
index 4949feb..312495c 100644
--- a/tests/suites/test_suite_camellia.function
+++ b/tests/suites/test_suite_camellia.function
@@ -175,7 +175,7 @@
 
 /* BEGIN_CASE */
 void camellia_encrypt_ecb( data_t * key_str, data_t * src_str,
-                           data_t * hex_dst_string, int setkey_result )
+                           data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -189,8 +189,7 @@
     {
         TEST_ASSERT( mbedtls_camellia_crypt_ecb( &ctx, MBEDTLS_CAMELLIA_ENCRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          16, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
     }
 
 exit:
@@ -200,7 +199,7 @@
 
 /* BEGIN_CASE */
 void camellia_decrypt_ecb( data_t * key_str, data_t * src_str,
-                           data_t * hex_dst_string, int setkey_result )
+                           data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -214,8 +213,7 @@
     {
         TEST_ASSERT( mbedtls_camellia_crypt_ecb( &ctx, MBEDTLS_CAMELLIA_DECRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          16, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
     }
 
 exit:
@@ -225,8 +223,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void camellia_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string,
-                           int cbc_result )
+                           data_t * src_str, data_t * dst, int cbc_result )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -240,9 +237,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -252,7 +248,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void camellia_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string,
+                           data_t * src_str, data_t * dst,
                            int cbc_result )
 {
     unsigned char output[100];
@@ -267,9 +263,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -279,8 +274,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void camellia_encrypt_cfb128( data_t * key_str, data_t * iv_str,
-                              data_t * src_str,
-                              data_t * hex_dst_string )
+                              data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -293,8 +287,7 @@
     mbedtls_camellia_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_camellia_crypt_cfb128( &ctx, MBEDTLS_CAMELLIA_ENCRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      16, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
 
 exit:
     mbedtls_camellia_free( &ctx );
@@ -304,7 +297,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void camellia_decrypt_cfb128( data_t * key_str, data_t * iv_str,
                               data_t * src_str,
-                              data_t * hex_dst_string )
+                              data_t * dst )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -317,8 +310,7 @@
     mbedtls_camellia_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_camellia_crypt_cfb128( &ctx, MBEDTLS_CAMELLIA_DECRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      16, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
 
 exit:
     mbedtls_camellia_free( &ctx );
diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data
index 46c172b..4f83468 100644
--- a/tests/suites/test_suite_ccm.data
+++ b/tests/suites/test_suite_ccm.data
@@ -41,9 +41,9 @@
 CCM lengths #6 tag length not even
 ccm_lengths:5:10:5:7:MBEDTLS_ERR_CCM_BAD_INPUT
 
-CCM lengths #7 AD too long (2^16 - 2^8 + 1)
+CCM lengths #7 AD too long (2^16 - 2^8)
 depends_on:!MBEDTLS_CCM_ALT
-ccm_lengths:5:10:65281:8:MBEDTLS_ERR_CCM_BAD_INPUT
+ccm_lengths:5:10:65280:8:MBEDTLS_ERR_CCM_BAD_INPUT
 
 CCM lengths #8 msg too long for this IV length (2^16, q = 2)
 ccm_lengths:65536:13:5:8:MBEDTLS_ERR_CCM_BAD_INPUT
@@ -51,6 +51,9 @@
 CCM lengths #9 tag length 0
 ccm_lengths:5:10:5:0:MBEDTLS_ERR_CCM_BAD_INPUT
 
+CCM lengths #10 Large AD
+ccm_lengths:5:10:32768:8:0
+
 CCM* fixed tag lengths #1 all OK
 ccm_star_lengths:5:10:5:8:0
 
diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function
index 5724d8b..faa7e13 100644
--- a/tests/suites/test_suite_ccm.function
+++ b/tests/suites/test_suite_ccm.function
@@ -41,17 +41,17 @@
     unsigned char key[16];
     unsigned char msg[10];
     unsigned char iv[14];
-    unsigned char add[10];
+    unsigned char *add = NULL;
     unsigned char out[10];
     unsigned char tag[18];
     int decrypt_ret;
 
     mbedtls_ccm_init( &ctx );
 
+    ASSERT_ALLOC_WEAK( add, add_len );
     memset( key, 0, sizeof( key ) );
     memset( msg, 0, sizeof( msg ) );
     memset( iv, 0, sizeof( iv ) );
-    memset( add, 0, sizeof( add ) );
     memset( out, 0, sizeof( out ) );
     memset( tag, 0, sizeof( tag ) );
 
@@ -70,6 +70,7 @@
         TEST_ASSERT( decrypt_ret == res );
 
 exit:
+    mbedtls_free( add );
     mbedtls_ccm_free( &ctx );
 }
 /* END_CASE */
@@ -152,7 +153,7 @@
 void mbedtls_ccm_auth_decrypt( int cipher_id, data_t * key,
                                data_t * msg, data_t * iv,
                                data_t * add, int tag_len, int result,
-                               data_t * hex_msg )
+                               data_t * expected_msg )
 {
     unsigned char tag[16];
     mbedtls_ccm_context ctx;
@@ -172,7 +173,7 @@
 
     if( result == 0 )
     {
-        TEST_ASSERT( memcmp( msg->x, hex_msg->x, hex_msg->len ) == 0 );
+        TEST_ASSERT( memcmp( msg->x, expected_msg->x, expected_msg->len ) == 0 );
     }
     else
     {
diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function
index afe2418..67c8de2 100644
--- a/tests/suites/test_suite_chacha20.function
+++ b/tests/suites/test_suite_chacha20.function
@@ -17,13 +17,6 @@
     unsigned char output[375];
     mbedtls_chacha20_context ctx;
 
-    /*
-     * Buffers to store the ASCII string representation of output and
-     * expected_output_str.
-     */
-    unsigned char output_string[751] = { '\0' };
-    unsigned char expected_output_string[751] = { '\0' };
-
     memset( output, 0x00, sizeof( output ) );
 
     TEST_ASSERT( src_str->len   == expected_output_str->len );
@@ -35,12 +28,8 @@
      */
     TEST_ASSERT( mbedtls_chacha20_crypt( key_str->x, nonce_str->x, counter, src_str->len, src_str->x, output ) == 0 );
 
-    mbedtls_test_hexify( expected_output_string,
-                         expected_output_str->x,
-                         expected_output_str->len);
-    mbedtls_test_hexify( output_string, output, src_str->len );
-    TEST_ASSERT( strcmp( (char *)output_string,
-                         (char *)expected_output_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output_str->len,
+                    expected_output_str->x, expected_output_str->len );
 
     /*
      * Test the streaming API
@@ -54,9 +43,8 @@
     memset( output, 0x00, sizeof( output ) );
     TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_str->len, src_str->x, output ) == 0 );
 
-    mbedtls_test_hexify( output_string, output, src_str->len );
-    TEST_ASSERT( strcmp( (char *)output_string,
-                         (char *)expected_output_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output_str->len,
+                    expected_output_str->x, expected_output_str->len );
 
     /*
      * Test the streaming API again, piecewise
@@ -71,9 +59,8 @@
     TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_str->len - 1,
                                           src_str->x + 1, output + 1 ) == 0 );
 
-    mbedtls_test_hexify( output_string, output, src_str->len );
-    TEST_ASSERT( strcmp( (char *)output_string,
-                         (char *)expected_output_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output_str->len,
+                    expected_output_str->x, expected_output_str->len );
 
     mbedtls_chacha20_free( &ctx );
 }
diff --git a/tests/suites/test_suite_des.function b/tests/suites/test_suite_des.function
index 625c87a..5b24935 100644
--- a/tests/suites/test_suite_des.function
+++ b/tests/suites/test_suite_des.function
@@ -15,8 +15,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void des_encrypt_ecb( data_t * key_str, data_t * src_str,
-                      data_t * hex_dst_string )
+void des_encrypt_ecb( data_t * key_str, data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_des_context ctx;
@@ -28,8 +27,7 @@
     mbedtls_des_setkey_enc( &ctx, key_str->x );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 
 exit:
     mbedtls_des_free( &ctx );
@@ -37,8 +35,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void des_decrypt_ecb( data_t * key_str, data_t * src_str,
-                      data_t * hex_dst_string )
+void des_decrypt_ecb( data_t * key_str, data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_des_context ctx;
@@ -50,8 +47,7 @@
     mbedtls_des_setkey_dec( &ctx, key_str->x );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 
 exit:
     mbedtls_des_free( &ctx );
@@ -60,8 +56,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void des_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                      data_t * src_str, data_t * hex_dst_string,
-                      int cbc_result )
+                      data_t * src_str, data_t * dst, int cbc_result )
 {
     unsigned char output[100];
     mbedtls_des_context ctx;
@@ -75,9 +70,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -87,7 +81,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void des_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                      data_t * src_str, data_t * hex_dst_string,
+                      data_t * src_str, data_t * dst,
                       int cbc_result )
 {
     unsigned char output[100];
@@ -102,9 +96,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -114,7 +107,7 @@
 
 /* BEGIN_CASE */
 void des3_encrypt_ecb( int key_count, data_t * key_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_des3_context ctx;
@@ -132,8 +125,7 @@
 
     TEST_ASSERT( mbedtls_des3_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 
 exit:
     mbedtls_des3_free( &ctx );
@@ -142,7 +134,7 @@
 
 /* BEGIN_CASE */
 void des3_decrypt_ecb( int key_count, data_t * key_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_des3_context ctx;
@@ -160,8 +152,7 @@
 
     TEST_ASSERT( mbedtls_des3_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 
 exit:
     mbedtls_des3_free( &ctx );
@@ -171,7 +162,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void des3_encrypt_cbc( int key_count, data_t * key_str,
                        data_t * iv_str, data_t * src_str,
-                       data_t * hex_dst_string, int cbc_result )
+                       data_t * dst, int cbc_result )
 {
     unsigned char output[100];
     mbedtls_des3_context ctx;
@@ -192,9 +183,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
     }
 
 exit:
@@ -205,7 +195,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void des3_decrypt_cbc( int key_count, data_t * key_str,
                        data_t * iv_str, data_t * src_str,
-                       data_t * hex_dst_string, int cbc_result )
+                       data_t * dst, int cbc_result )
 {
     unsigned char output[100];
     mbedtls_des3_context ctx;
@@ -226,9 +216,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index b28d918ba..9b7b0ee 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -35,8 +35,8 @@
 /* BEGIN_CASE */
 void gcm_encrypt_and_tag( int cipher_id, data_t * key_str,
                           data_t * src_str, data_t * iv_str,
-                          data_t * add_str, data_t * hex_dst_string,
-                          int tag_len_bits, data_t * hex_tag_string,
+                          data_t * add_str, data_t * dst,
+                          int tag_len_bits, data_t * tag,
                           int init_result )
 {
     unsigned char output[128];
@@ -55,11 +55,10 @@
     {
         TEST_ASSERT( mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x, iv_str->len, add_str->x, add_str->len, src_str->x, output, tag_len, tag_output ) == 0 );
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                          src_str->len,
-                                          hex_dst_string->len ) == 0 );
-        TEST_ASSERT( mbedtls_test_hexcmp( tag_output, hex_tag_string->x,
-                                          tag_len, hex_tag_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( tag_output, tag->x,
+                                          tag_len, tag->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_hkdf.function b/tests/suites/test_suite_hkdf.function
index 967df36..4c597c3 100644
--- a/tests/suites/test_suite_hkdf.function
+++ b/tests/suites/test_suite_hkdf.function
@@ -14,13 +14,6 @@
 {
     int ret;
     unsigned char okm[128] = { '\0' };
-    /*
-     * okm_string and expected_okm_string are the ASCII string representations
-     * of km and expected_okm, so their size should be twice the size of
-     * okm and expected_okm, and an extra null-termination.
-     */
-    unsigned char okm_string[257] = { '\0' };
-    unsigned char expected_okm_string[257] = { '\0' };
 
     const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md != NULL );
@@ -31,14 +24,8 @@
                         info->x, info->len, okm, expected_okm->len );
     TEST_ASSERT( ret == 0 );
 
-    /*
-     * Run mbedtls_test_hexify on okm and expected_okm so that it looks nicer
-     * if the assertion fails.
-     */
-    mbedtls_test_hexify( okm_string, okm, expected_okm->len );
-    mbedtls_test_hexify( expected_okm_string,
-                         expected_okm->x, expected_okm->len );
-    TEST_ASSERT( !strcmp( (char *)okm_string, (char *)expected_okm_string ) );
+    ASSERT_COMPARE( okm            , expected_okm->len,
+                    expected_okm->x, expected_okm->len );
 }
 /* END_CASE */
 
@@ -62,12 +49,11 @@
     ikm = mbedtls_test_unhexify_alloc( hex_ikm_string, &ikm_len );
     salt = mbedtls_test_unhexify_alloc( hex_salt_string, &salt_len );
     prk = mbedtls_test_unhexify_alloc( hex_prk_string, &prk_len );
-    TEST_ASSERT( prk_len == output_prk_len );
 
     ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, output_prk );
     TEST_ASSERT( ret == 0 );
 
-    TEST_ASSERT( !memcmp( output_prk, prk, prk_len ) );
+    ASSERT_COMPARE( output_prk, output_prk_len, prk, prk_len );
 
 exit:
     mbedtls_free(ikm);
@@ -103,7 +89,7 @@
     ret = mbedtls_hkdf_expand( md, prk, prk_len, info, info_len,
                                output_okm, OKM_LEN );
     TEST_ASSERT( ret == 0 );
-    TEST_ASSERT( !memcmp( output_okm, okm, okm_len ) );
+    ASSERT_COMPARE( output_okm, okm_len, okm, okm_len );
 
 exit:
     mbedtls_free(info);
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index be57829..d918ce3 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -127,7 +127,7 @@
 
 /* BEGIN_CASE */
 void md_text( char * text_md_name, char * text_src_string,
-              data_t * hex_hash_string )
+              data_t * hash )
 {
     char md_name[100];
     unsigned char src_str[1000];
@@ -145,15 +145,14 @@
 
     TEST_ASSERT ( 0 == mbedtls_md( md_info, src_str, strlen( (char *) src_str ), output ) );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
                                       mbedtls_md_get_size( md_info ),
-                                      hex_hash_string->len ) == 0 );
+                                      hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
-void md_hex( char * text_md_name, data_t * src_str,
-             data_t * hex_hash_string )
+void md_hex( char * text_md_name, data_t * src_str, data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -169,15 +168,15 @@
     TEST_ASSERT ( 0 == mbedtls_md( md_info, src_str->x, src_str->len, output ) );
 
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
                                       mbedtls_md_get_size( md_info ),
-                                      hex_hash_string->len ) == 0 );
+                                      hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
 void md_text_multi( char * text_md_name, char * text_src_string,
-                    data_t * hex_hash_string )
+                    data_t * hash )
 {
     char md_name[100];
     unsigned char src_str[1000];
@@ -211,18 +210,18 @@
 
     TEST_ASSERT ( 0 == mbedtls_md_update( &ctx, src_str + halfway, len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_finish( &ctx, output ) );
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
                                       mbedtls_md_get_size( md_info ),
-                                      hex_hash_string->len) == 0 );
+                                      hash->len) == 0 );
 
     /* Test clone */
     memset( output, 0x00, 100 );
 
     TEST_ASSERT ( 0 == mbedtls_md_update( &ctx_copy, src_str + halfway, len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_finish( &ctx_copy, output ) );
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
                                       mbedtls_md_get_size( md_info ),
-                                      hex_hash_string->len ) == 0 );
+                                      hash->len ) == 0 );
 
 exit:
     mbedtls_md_free( &ctx );
@@ -231,8 +230,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void md_hex_multi( char * text_md_name, data_t * src_str,
-                   data_t * hex_hash_string )
+void md_hex_multi( char * text_md_name, data_t * src_str, data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -261,18 +259,18 @@
 
     TEST_ASSERT ( 0 == mbedtls_md_update( &ctx, src_str->x + halfway, src_str->len - halfway) );
     TEST_ASSERT ( 0 == mbedtls_md_finish( &ctx, output ) );
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
                                       mbedtls_md_get_size( md_info ),
-                                      hex_hash_string->len ) == 0 );
+                                      hash->len ) == 0 );
 
     /* Test clone */
     memset( output, 0x00, 100 );
 
     TEST_ASSERT ( 0 == mbedtls_md_update( &ctx_copy, src_str->x + halfway, src_str->len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_finish( &ctx_copy, output ) );
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
                                       mbedtls_md_get_size( md_info ),
-                                      hex_hash_string->len ) == 0 );
+                                      hash->len ) == 0 );
 
 exit:
     mbedtls_md_free( &ctx );
@@ -283,7 +281,7 @@
 /* BEGIN_CASE */
 void mbedtls_md_hmac( char * text_md_name, int trunc_size,
                       data_t * key_str, data_t * src_str,
-                      data_t * hex_hash_string )
+                      data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -299,14 +297,14 @@
 
     TEST_ASSERT ( mbedtls_md_hmac( md_info, key_str->x, key_str->len, src_str->x, src_str->len, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      trunc_size, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      trunc_size, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
 void md_hmac_multi( char * text_md_name, int trunc_size, data_t * key_str,
-                    data_t * src_str, data_t * hex_hash_string )
+                    data_t * src_str, data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -332,8 +330,8 @@
     TEST_ASSERT ( 0 == mbedtls_md_hmac_update( &ctx, src_str->x + halfway, src_str->len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_hmac_finish( &ctx, output ) );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      trunc_size, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      trunc_size, hash->len ) == 0 );
 
     /* Test again, for reset() */
     memset( output, 0x00, 100 );
@@ -343,8 +341,8 @@
     TEST_ASSERT ( 0 == mbedtls_md_hmac_update( &ctx, src_str->x + halfway, src_str->len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_hmac_finish( &ctx, output ) );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      trunc_size, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      trunc_size, hash->len ) == 0 );
 
 exit:
     mbedtls_md_free( &ctx );
@@ -353,7 +351,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
 void mbedtls_md_file( char * text_md_name, char * filename,
-                      data_t * hex_hash_string )
+                      data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -368,8 +366,8 @@
 
     TEST_ASSERT( mbedtls_md_file( md_info, filename, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
                                       mbedtls_md_get_size( md_info ),
-                                      hex_hash_string->len ) == 0 );
+                                      hash->len ) == 0 );
 }
 /* END_CASE */
diff --git a/tests/suites/test_suite_mdx.function b/tests/suites/test_suite_mdx.function
index ed2ae58..aa35c58 100644
--- a/tests/suites/test_suite_mdx.function
+++ b/tests/suites/test_suite_mdx.function
@@ -6,7 +6,7 @@
 /* END_HEADER */
 
 /* BEGIN_CASE depends_on:MBEDTLS_MD2_C */
-void md2_text( char * text_src_string, data_t * hex_hash_string )
+void md2_text( char * text_src_string, data_t * hash )
 {
     int ret;
     unsigned char src_str[100];
@@ -20,14 +20,13 @@
     ret = mbedtls_md2_ret( src_str, strlen( (char *) src_str ), output );
     TEST_ASSERT( ret == 0 ) ;
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      sizeof  output,
-                                      hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      sizeof  output, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_MD4_C */
-void md4_text( char * text_src_string, data_t * hex_hash_string )
+void md4_text( char * text_src_string, data_t * hash )
 {
     int ret;
     unsigned char src_str[100];
@@ -41,14 +40,13 @@
     ret = mbedtls_md4_ret( src_str, strlen( (char *) src_str ), output );
     TEST_ASSERT( ret == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      sizeof  output,
-                                      hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      sizeof  output, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_MD5_C */
-void md5_text( char * text_src_string, data_t * hex_hash_string )
+void md5_text( char * text_src_string, data_t * hash )
 {
     int ret;
     unsigned char src_str[100];
@@ -62,14 +60,13 @@
     ret = mbedtls_md5_ret( src_str, strlen( (char *) src_str ), output );
     TEST_ASSERT( ret == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      sizeof  output,
-                                      hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      sizeof  output, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_RIPEMD160_C */
-void ripemd160_text( char * text_src_string, data_t * hex_hash_string )
+void ripemd160_text( char * text_src_string, data_t * hash )
 {
     int ret;
     unsigned char src_str[100];
@@ -83,9 +80,8 @@
     ret = mbedtls_ripemd160_ret( src_str, strlen( (char *) src_str ), output );
     TEST_ASSERT( ret == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      sizeof output,
-                                      hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      sizeof output, hash->len ) == 0 );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function
index 8a42180..068027b 100644
--- a/tests/suites/test_suite_pkcs1_v15.function
+++ b/tests/suites/test_suite_pkcs1_v15.function
@@ -12,7 +12,7 @@
 void pkcs1_rsaes_v15_encrypt( int mod, int radix_N, char * input_N,
                               int radix_E, char * input_E, int hash,
                               data_t * message_str, data_t * rnd_buf,
-                              data_t * result_hex_str, int result )
+                              data_t * result_str, int result )
 {
     unsigned char output[128];
     mbedtls_rsa_context ctx;
@@ -42,8 +42,8 @@
 
     if( result == 0 )
     {
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -56,7 +56,7 @@
 void pkcs1_rsaes_v15_decrypt( int mod, int radix_P, char * input_P,
                               int radix_Q, char * input_Q, int radix_N,
                               char * input_N, int radix_E, char * input_E,
-                              int hash, data_t * result_hex_str,
+                              int hash, data_t * result_str,
                               char * seed, data_t * message_str,
                               int result )
 {
@@ -84,7 +84,7 @@
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
-    if( result_hex_str->len == 0 )
+    if( result_str->len == 0 )
     {
         TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx,
                                                 &mbedtls_test_rnd_pseudo_rand,
@@ -102,9 +102,9 @@
                                                 output, 1000 ) == result );
         if( result == 0 )
         {
-            TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
+            TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
                                               output_len,
-                                              result_hex_str->len) == 0 );
+                                              result_str->len) == 0 );
         }
     }
 
@@ -267,7 +267,7 @@
                             char * input_Q, int radix_N, char * input_N,
                             int radix_E, char * input_E, int digest, int hash,
                             data_t * message_str, data_t * rnd_buf,
-                            data_t * result_hex_str, int result )
+                            data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
     unsigned char output[128];
@@ -305,8 +305,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_pkcs1_v21.function b/tests/suites/test_suite_pkcs1_v21.function
index c9e91c8..c28cf08 100644
--- a/tests/suites/test_suite_pkcs1_v21.function
+++ b/tests/suites/test_suite_pkcs1_v21.function
@@ -12,7 +12,7 @@
 void pkcs1_rsaes_oaep_encrypt( int mod, int radix_N, char * input_N,
                                int radix_E, char * input_E, int hash,
                                data_t * message_str, data_t * rnd_buf,
-                               data_t * result_hex_str, int result )
+                               data_t * result_str, int result )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx;
@@ -41,8 +41,8 @@
                                             output ) == result );
     if( result == 0 )
     {
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -55,7 +55,7 @@
 void pkcs1_rsaes_oaep_decrypt( int mod, int radix_P, char * input_P,
                                int radix_Q, char * input_Q, int radix_N,
                                char * input_N, int radix_E, char * input_E,
-                               int hash, data_t * result_hex_str,
+                               int hash, data_t * result_str,
                                char * seed, data_t * message_str,
                                int result )
 {
@@ -84,7 +84,7 @@
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
-    if( result_hex_str->len == 0 )
+    if( result_str->len == 0 )
     {
         TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx,
                                                 &mbedtls_test_rnd_pseudo_rand,
@@ -104,9 +104,9 @@
                                                 sizeof( output ) ) == result );
         if( result == 0 )
         {
-            TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
+            TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
                                               output_len,
-                                              result_hex_str->len ) == 0 );
+                                              result_str->len ) == 0 );
         }
     }
 
@@ -122,7 +122,7 @@
                             char * input_Q, int radix_N, char * input_N,
                             int radix_E, char * input_E, int digest, int hash,
                             data_t * message_str, data_t * rnd_buf,
-                            data_t * result_hex_str, int result )
+                            data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
     unsigned char output[256];
@@ -160,8 +160,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function
index 44617d9..4b8995b 100644
--- a/tests/suites/test_suite_poly1305.function
+++ b/tests/suites/test_suite_poly1305.function
@@ -9,14 +9,12 @@
  */
 
 /* BEGIN_CASE */
-void mbedtls_poly1305( data_t *key, char *hex_mac_string, data_t *src_str )
+void mbedtls_poly1305( data_t *key, data_t *expected_mac, data_t *src_str )
 {
     unsigned char mac[16]; /* size set by the standard */
-    unsigned char mac_str[33]; /* hex expansion of the above */
     mbedtls_poly1305_context ctx;
 
-    memset( mac_str, 0x00, sizeof( mac_str ) );
-    memset( mac,     0x00, sizeof( mac ) );
+    memset( mac, 0x00, sizeof( mac ) );
 
     /*
      * Test the integrated API
@@ -24,8 +22,8 @@
     TEST_ASSERT( mbedtls_poly1305_mac( key->x, src_str->x,
                                        src_str->len, mac ) == 0 );
 
-    mbedtls_test_hexify( mac_str, mac, 16 );
-    TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 );
+    ASSERT_COMPARE( mac, expected_mac->len,
+                    expected_mac->x, expected_mac->len );
 
     /*
      * Test the streaming API
@@ -38,8 +36,8 @@
 
     TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 );
 
-    mbedtls_test_hexify( mac_str, mac, 16 );
-    TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 );
+    ASSERT_COMPARE( mac, expected_mac->len,
+                    expected_mac->x, expected_mac->len );
 
     /*
      * Test the streaming API again, piecewise
@@ -56,8 +54,8 @@
 
         TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 );
 
-        mbedtls_test_hexify( mac_str, mac, 16 );
-        TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 );
+        ASSERT_COMPARE( mac, expected_mac->len,
+                        expected_mac->x, expected_mac->len );
     }
 
     /*
@@ -73,8 +71,8 @@
 
         TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 );
 
-        mbedtls_test_hexify( mac_str, mac, 16 );
-        TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 );
+        ASSERT_COMPARE( mac, expected_mac->len,
+                        expected_mac->x, expected_mac->len );
     }
 
     mbedtls_poly1305_free( &ctx );
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index aff7051..774050d 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -563,39 +563,43 @@
 
 PSA key policy: agreement + KDF, permitted
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256))
+agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_SUCCESS
 
 PSA key policy: agreement + KDF, not permitted
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-agreement_key_policy:0:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256))
+agreement_key_policy:0:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: agreement + KDF, wrong agreement algorithm
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_FFDH, PSA_ALG_HKDF(PSA_ALG_SHA_256))
+agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_FFDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: agreement + KDF, wrong KDF algorithm
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_224))
+agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_224)):PSA_ERROR_NOT_PERMITTED
 
-PSA key policy: agreement + KDF, key only permits raw agreement
+PSA key policy: agreement + KDF, key permits raw agreement
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256))
+agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_SUCCESS
 
 PSA key policy: raw agreement, permitted
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
-raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDH
+raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDH:PSA_SUCCESS
 
 PSA key policy: raw agreement, not permitted
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
-raw_agreement_key_policy:0:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDH
+raw_agreement_key_policy:0:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDH:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy: raw agreement, wrong algorithm
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
-raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_FFDH
+raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_FFDH:PSA_ERROR_NOT_PERMITTED
 
-PSA key policy: raw agreement, key only permits a KDF
+PSA key policy: raw agreement, key permits raw agreement, but algorithm is not raw
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
-raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256))
+raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ERROR_NOT_SUPPORTED
+
+PSA key policy: raw agreement, key specifies KDF
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
+raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_ECDH:PSA_ERROR_NOT_PERMITTED
 
 PSA key policy algorithm2: CTR, CBC
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_CIPHER_MODE_CBC
@@ -1240,7 +1244,7 @@
 
 PSA symmetric decrypt: AES-CBC-PKCS#7, input too short (15 bytes)
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
-cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"49e4e66c89a86b67758df89db9ad6955":PSA_ERROR_BAD_STATE
+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:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_MODE_CTR
@@ -1252,7 +1256,7 @@
 
 PSA symmetric decrypt: AES-CBC-nopad, input too short (5 bytes)
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
-cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":"6bc1bee223":PSA_ERROR_BAD_STATE
+cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
 
 PSA symmetric decrypt: DES-CBC-nopad, 8 bytes, good
 depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
@@ -2225,6 +2229,14 @@
 depends_on:MBEDTLS_SHA256_C
 derive_input:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"01020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_DERIVATION_INPUT_LABEL:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
 
+PSA key derivation: ECDH on P256 with HKDF-SHA256, raw output
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
+
+PSA key derivation: ECDH on P256 with HKDF-SHA256, key output
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_RAW_DATA:PSA_SUCCESS
+
 PSA key derivation: HKDF invalid state (double generate + read past capacity)
 depends_on:MBEDTLS_SHA256_C
 test_derive_invalid_key_derivation_state:PSA_ALG_HKDF(PSA_ALG_SHA_256)
@@ -2507,31 +2519,39 @@
 
 PSA key agreement setup: ECDH + HKDF-SHA-256: good
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_SUCCESS
+key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_SUCCESS
+
+PSA key agreement setup: ECDH + HKDF-SHA-256: good, key algorithm broader than required
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
+key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDH:"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_SUCCESS
+
+PSA key agreement setup: ECDH + HKDF-SHA-256: key algorithm KDF mismatch
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
+key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_512)):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_NOT_PERMITTED
 
 PSA key agreement setup: ECDH + HKDF-SHA-256: public key not on curve
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ff":PSA_ERROR_INVALID_ARGUMENT
+key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ff":PSA_ERROR_INVALID_ARGUMENT
 
 PSA key agreement setup: ECDH + HKDF-SHA-256: public key on different curve
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04e558dbef53eecde3d3fccfc1aea08a89a987475d12fd950d83cfa41732bc509d0d1ac43a0336def96fda41d0774a3571dcfbec7aacf3196472169e838430367f66eebe3c6e70c416dd5f0c68759dd1fff83fa40142209dff5eaad96db9e6386c":PSA_ERROR_INVALID_ARGUMENT
+key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04e558dbef53eecde3d3fccfc1aea08a89a987475d12fd950d83cfa41732bc509d0d1ac43a0336def96fda41d0774a3571dcfbec7aacf3196472169e838430367f66eebe3c6e70c416dd5f0c68759dd1fff83fa40142209dff5eaad96db9e6386c":PSA_ERROR_INVALID_ARGUMENT
 
 PSA key agreement setup: ECDH + HKDF-SHA-256: public key instead of private key
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
-key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_INVALID_ARGUMENT
+key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_INVALID_ARGUMENT
 
 PSA key agreement setup: ECDH, unknown KDF
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
-key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(0)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_NOT_SUPPORTED
+key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(0)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(0)):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_NOT_SUPPORTED
 
 PSA key agreement setup: bad key agreement algorithm
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
-key_agreement_setup:PSA_ALG_KEY_AGREEMENT(0, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_INVALID_ARGUMENT
+key_agreement_setup:PSA_ALG_KEY_AGREEMENT(0, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_KEY_AGREEMENT(0, PSA_ALG_HKDF(PSA_ALG_SHA_256)):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_INVALID_ARGUMENT
 
 PSA key agreement setup: KDF instead of a key agreement algorithm
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
-key_agreement_setup:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_INVALID_ARGUMENT
+key_agreement_setup:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_HKDF(PSA_ALG_SHA_256):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_INVALID_ARGUMENT
 
 PSA raw key agreement: ECDH SECP256R1 (RFC 5903)
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
@@ -2557,6 +2577,14 @@
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_ECDH_C
 raw_key_agreement:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"16302ff0dbbb5a8d733dab7141c1b45acbc8715939677f6a56850a38bd87bd59b09e80279609ff333eb9d4c061231fb26f92eeb04982a5f1d1764cad57665422":"049d45f66de5d67e2e6db6e93a59ce0bb48106097ff78a081de781cdb31fce8ccbaaea8dd4320c4119f1e9cd437a2eab3731fa9668ab268d871deda55a5473199f2fdc313095bcdd5fb3a91636f07a959c8e86b5636a1e930e8396049cb481961d365cc11453a06c719835475b12cb52fc3c383bce35e27ef194512b71876285fa":"a7927098655f1f9976fa50a9d566865dc530331846381c87256baf3226244b76d36403c024d7bbf0aa0803eaff405d3d24f11a9b5c0bef679fe1454b21c4cd1f"
 
+PSA raw key agreement: X25519 (RFC 7748: Alice)
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_CURVE25519_ENABLED:MBEDTLS_ECDH_C
+raw_key_agreement:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):"77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a":"de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f":"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
+
+PSA raw key agreement: X25519 (RFC 7748: Bob)
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_CURVE25519_ENABLED:MBEDTLS_ECDH_C
+raw_key_agreement:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):"5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb":"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
+
 PSA key agreement: ECDH SECP256R1 (RFC 5903) + HKDF-SHA-256: capacity=8160
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C
 key_agreement_capacity:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":8160
@@ -2718,6 +2746,10 @@
 # doesn't fully relate the curve with its size.
 generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_NOT_SUPPORTED
 
+PSA generate key: ECC, Curve25519, good
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_CURVE25519_ENABLED:MBEDTLS_ECDH_C
+generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS
+
 PSA generate key: RSA, default e
 generate_key_rsa:512:"":PSA_SUCCESS
 
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 45916b9..fc563cb 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -2208,13 +2208,15 @@
                            int policy_alg,
                            int key_type_arg,
                            data_t *key_data,
-                           int exercise_alg )
+                           int exercise_alg,
+                           int expected_status_arg )
 {
     psa_key_handle_t handle = 0;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
     psa_status_t status;
+    psa_status_t expected_status = expected_status_arg;
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -2228,11 +2230,7 @@
     PSA_ASSERT( psa_key_derivation_setup( &operation, exercise_alg ) );
     status = key_agreement_with_self( &operation, handle );
 
-    if( policy_alg == exercise_alg &&
-        ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
-        PSA_ASSERT( status );
-    else
-        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
+    TEST_EQUAL( status, expected_status );
 
 exit:
     psa_key_derivation_abort( &operation );
@@ -2283,13 +2281,15 @@
                                int policy_alg,
                                int key_type_arg,
                                data_t *key_data,
-                               int exercise_alg )
+                               int exercise_alg,
+                               int expected_status_arg )
 {
     psa_key_handle_t handle = 0;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_type_t key_type = key_type_arg;
     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
     psa_status_t status;
+    psa_status_t expected_status = expected_status_arg;
 
     PSA_ASSERT( psa_crypto_init( ) );
 
@@ -2302,11 +2302,7 @@
 
     status = raw_key_agreement_with_self( exercise_alg, handle );
 
-    if( policy_alg == exercise_alg &&
-        ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
-        PSA_ASSERT( status );
-    else
-        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
+    TEST_EQUAL( status, expected_status );
 
 exit:
     psa_key_derivation_abort( &operation );
@@ -4733,9 +4729,20 @@
             PSA_ASSERT( psa_import_key( &attributes,
                                         inputs[i]->x, inputs[i]->len,
                                         &handles[i] ) );
-            TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
-                                                      handles[i] ),
-                        expected_statuses[i] );
+            if( PSA_KEY_TYPE_IS_KEY_PAIR( key_types[i] ) &&
+                steps[i] == PSA_KEY_DERIVATION_INPUT_SECRET )
+            {
+                // When taking a private key as secret input, use key agreement
+                // to add the shared secret to the derivation
+                TEST_EQUAL( key_agreement_with_self( &operation, handles[i] ),
+                            expected_statuses[i] );
+            }
+            else
+            {
+                TEST_EQUAL( psa_key_derivation_input_key( &operation, steps[i],
+                                                          handles[i] ),
+                            expected_statuses[i] );
+            }
         }
         else
         {
@@ -5220,12 +5227,13 @@
 
 /* BEGIN_CASE */
 void key_agreement_setup( int alg_arg,
-                          int our_key_type_arg, data_t *our_key_data,
-                          data_t *peer_key_data,
+                          int our_key_type_arg, int our_key_alg_arg,
+                          data_t *our_key_data, data_t *peer_key_data,
                           int expected_status_arg )
 {
     psa_key_handle_t our_key = 0;
     psa_algorithm_t alg = alg_arg;
+    psa_algorithm_t our_key_alg = our_key_alg_arg;
     psa_key_type_t our_key_type = our_key_type_arg;
     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -5235,7 +5243,7 @@
     PSA_ASSERT( psa_crypto_init( ) );
 
     psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE );
-    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_algorithm( &attributes, our_key_alg );
     psa_set_key_type( &attributes, our_key_type );
     PSA_ASSERT( psa_import_key( &attributes,
                                 our_key_data->x, our_key_data->len,
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
index 7abc256..1f1ee39 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
@@ -40,6 +40,25 @@
 generate_key through transparent driver: error
 generate_key:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR
 
+validate key through transparent driver: good private key
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+validate_key:PSA_SUCCESS:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_SUCCESS
+
+validate key through transparent driver: good public key
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+validate_key:PSA_SUCCESS:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_SUCCESS
+
+validate key through transparent driver: fallback private key
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+validate_key:PSA_ERROR_NOT_SUPPORTED:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_SUCCESS
+
+validate key through transparent driver: fallback public key
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+validate_key:PSA_ERROR_NOT_SUPPORTED:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_SUCCESS
+
+validate key through transparent driver: error
+validate_key:PSA_ERROR_GENERIC_ERROR:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ERROR_GENERIC_ERROR
+
 PSA symmetric encrypt: AES-CTR, 16 bytes, good
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
 cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
index 951670d..a0140d2 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function
@@ -132,7 +132,7 @@
     psa_status_t actual_status;
     uint8_t actual_output[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(256)] = {0};
     size_t actual_output_length;
-    test_driver_keygen_hooks = test_driver_keygen_hooks_init();
+    test_driver_key_management_hooks = test_driver_key_management_hooks_init();
 
     psa_set_key_type( &attributes,
                       PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP_R1 ) );
@@ -142,18 +142,18 @@
 
     if( fake_output->len > 0 )
     {
-        expected_output = test_driver_keygen_hooks.forced_output = fake_output->x;
-        expected_output_length = test_driver_keygen_hooks.forced_output_length =
+        expected_output = test_driver_key_management_hooks.forced_output = fake_output->x;
+        expected_output_length = test_driver_key_management_hooks.forced_output_length =
             fake_output->len;
     }
 
-    test_driver_keygen_hooks.hits = 0;
-    test_driver_keygen_hooks.forced_status = force_status;
+    test_driver_key_management_hooks.hits = 0;
+    test_driver_key_management_hooks.forced_status = force_status;
 
     PSA_ASSERT( psa_crypto_init( ) );
 
     actual_status = psa_generate_key( &attributes, &handle );
-    TEST_EQUAL( test_driver_keygen_hooks.hits, 1 );
+    TEST_EQUAL( test_driver_key_management_hooks.hits, 1 );
     TEST_EQUAL( actual_status, expected_status );
 
     if( actual_status == PSA_SUCCESS )
@@ -180,7 +180,41 @@
     psa_reset_key_attributes( &attributes );
     psa_destroy_key( handle );
     PSA_DONE( );
-    test_driver_keygen_hooks = test_driver_keygen_hooks_init();
+    test_driver_key_management_hooks = test_driver_key_management_hooks_init();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+void validate_key( int force_status_arg,
+                   int key_type_arg,
+                   data_t *key_input,
+                   int expected_status_arg )
+{
+    psa_status_t force_status = force_status_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_type_t key_type = key_type_arg;
+    psa_key_handle_t handle = 0;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_status_t actual_status;
+    test_driver_key_management_hooks = test_driver_key_management_hooks_init();
+
+    psa_set_key_type( &attributes,
+                      key_type );
+    psa_set_key_bits( &attributes, 0 );
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
+
+    test_driver_key_management_hooks.forced_status = force_status;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    actual_status = psa_import_key( &attributes, key_input->x, key_input->len, &handle );
+    TEST_EQUAL( test_driver_key_management_hooks.hits, 1 );
+    TEST_EQUAL( actual_status, expected_status );
+exit:
+    psa_reset_key_attributes( &attributes );
+    psa_destroy_key( handle );
+    PSA_DONE( );
+    test_driver_key_management_hooks = test_driver_key_management_hooks_init();
 }
 /* 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 f65e57e..98db74d 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.data
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.data
@@ -1,26 +1,26 @@
 Format for storage: RSA private key
-format_storage_data_check:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"505341004b455900000000000100000001700000010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN
+format_storage_data_check:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"505341004b455900000000000100000001700004010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN
+
+Format for storage: AES-128 key
+format_storage_data_check:"404142434445464748494a4b4c4d4e4f":"505341004b45590000000000010000000024800000030000021040060000000010000000404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT:PSA_ALG_GCM:0
 
 Parse storage: RSA private key
-parse_storage_data_check:"505341004b455900000000000100000001700000010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_SUCCESS
+parse_storage_data_check:"505341004b455900000000000100000001700004010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_SUCCESS
 
 Parse storage: AES-128 key
-parse_storage_data_check:"505341004b45590000000000010000000024000000030000021040060000000010000000404142434445464748494a4b4c4d4e4f":"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_AES:PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT:PSA_ALG_GCM:0:PSA_SUCCESS
-
-Parse storage: type out of range
-parse_storage_data_check:"505341004b45590000000000010000000024010000030000021040060000000010000000404142434445464748494a4b4c4d4e4f":"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:0:PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT:PSA_ALG_GCM:0:PSA_ERROR_STORAGE_FAILURE
+parse_storage_data_check:"505341004b45590000000000010000000024800000030000021040060000000010000000404142434445464748494a4b4c4d4e4f":"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT:PSA_ALG_GCM:0:PSA_SUCCESS
 
 Parse storage: wrong version
-parse_storage_data_check:"505341004b455900ffffffff0100000001700000010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
+parse_storage_data_check:"505341004b455900ffffffff0100000001700004010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
 
 Parse storage: data too big
-parse_storage_data_check:"505341004b455900000000000100000001700000010000000000001200000010ffffffff3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
+parse_storage_data_check:"505341004b455900000000000100000001700000010000000000001200000010ffffffff3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
 
 Parse storage: bad magic
-parse_storage_data_check:"645341004b455900000000000100000001700000010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
+parse_storage_data_check:"645341004b455900000000000100000001700004010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
 
 Parse storage: truncated magic
-parse_storage_data_check:"505341004b4559":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
+parse_storage_data_check:"505341004b4559":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
 
 # Not specific to files, but only run this test in an environment where the maximum size could be reached.
 Save maximum-size persistent raw key
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index 9e2fbf6..7ee17f9 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -41,7 +41,7 @@
 /* BEGIN_CASE */
 void format_storage_data_check( data_t *key_data,
                                 data_t *expected_file_data,
-                                int key_lifetime, int key_type,
+                                int key_lifetime, int key_type, int key_bits,
                                 int key_usage, int key_alg, int key_alg2 )
 {
     uint8_t *file_data = NULL;
@@ -51,6 +51,7 @@
 
     psa_set_key_lifetime( &attributes, key_lifetime );
     psa_set_key_type( &attributes, key_type );
+    psa_set_key_bits( &attributes, key_bits );
     psa_set_key_usage_flags( &attributes, key_usage );
     psa_set_key_algorithm( &attributes, key_alg );
     psa_set_key_enrollment_algorithm( &attributes, key_alg2 );
@@ -73,6 +74,7 @@
                                data_t *expected_key_data,
                                int expected_key_lifetime,
                                int expected_key_type,
+                               int expected_key_bits,
                                int expected_key_usage,
                                int expected_key_alg,
                                int expected_key_alg2,
@@ -95,6 +97,8 @@
                 (psa_key_type_t) expected_key_lifetime );
     TEST_EQUAL( psa_get_key_type( &attributes ),
                 (psa_key_type_t) expected_key_type );
+    TEST_EQUAL( psa_get_key_bits( &attributes ),
+                (psa_key_bits_t) expected_key_bits );
     TEST_EQUAL( psa_get_key_usage_flags( &attributes ),
                 (uint32_t) expected_key_usage );
     TEST_EQUAL( psa_get_key_algorithm( &attributes ),
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index 90335db..6c73e39 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -471,7 +471,7 @@
                              int digest, int mod, int radix_P, char * input_P,
                              int radix_Q, char * input_Q, int radix_N,
                              char * input_N, int radix_E, char * input_E,
-                             data_t * result_hex_str, int result )
+                             data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
     unsigned char output[256];
@@ -507,8 +507,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -557,7 +557,7 @@
                          int padding_mode, int mod, int radix_P,
                          char * input_P, int radix_Q, char * input_Q,
                          int radix_N, char * input_N, int radix_E,
-                         char * input_E, data_t * result_hex_str )
+                         char * input_E, data_t * result_str )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx;
@@ -588,8 +588,8 @@
                                          hash_result->x, output ) == 0 );
 
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                      ctx.len, result_hex_str->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                      ctx.len, result_str->len ) == 0 );
 
 #if defined(MBEDTLS_PKCS1_V15)
     /* For PKCS#1 v1.5, there is an alternative way to generate signatures */
@@ -612,9 +612,9 @@
 
         if( res == 0 )
         {
-            TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
+            TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
                                               ctx.len,
-                                              result_hex_str->len ) == 0 );
+                                              result_str->len ) == 0 );
         }
     }
 #endif /* MBEDTLS_PKCS1_V15 */
@@ -692,7 +692,7 @@
 void mbedtls_rsa_pkcs1_encrypt( data_t * message_str, int padding_mode,
                                 int mod, int radix_N, char * input_N,
                                 int radix_E, char * input_E,
-                                data_t * result_hex_str, int result )
+                                data_t * result_str, int result )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx;
@@ -722,8 +722,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -736,7 +736,7 @@
 void rsa_pkcs1_encrypt_bad_rng( data_t * message_str, int padding_mode,
                                 int mod, int radix_N, char * input_N,
                                 int radix_E, char * input_E,
-                                data_t * result_hex_str, int result )
+                                data_t * result_str, int result )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx;
@@ -762,8 +762,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -777,7 +777,7 @@
                                 int mod, int radix_P, char * input_P,
                                 int radix_Q, char * input_Q, int radix_N,
                                 char * input_N, int radix_E, char * input_E,
-                                int max_output, data_t * result_hex_str,
+                                int max_output, data_t * result_str,
                                 int result )
 {
     unsigned char output[32];
@@ -814,9 +814,9 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
                                           output_len,
-                                          result_hex_str->len ) == 0 );
+                                          result_str->len ) == 0 );
     }
 
 exit:
@@ -829,7 +829,7 @@
 /* BEGIN_CASE */
 void mbedtls_rsa_public( data_t * message_str, int mod, int radix_N,
                          char * input_N, int radix_E, char * input_E,
-                         data_t * result_hex_str, int result )
+                         data_t * result_str, int result )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
@@ -853,8 +853,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
     /* And now with the copy */
@@ -869,8 +869,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                                          ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -884,7 +884,7 @@
 void mbedtls_rsa_private( data_t * message_str, int mod, int radix_P,
                           char * input_P, int radix_Q, char * input_Q,
                           int radix_N, char * input_N, int radix_E,
-                          char * input_E, data_t * result_hex_str,
+                          char * input_E, data_t * result_str,
                           int result )
 {
     unsigned char output[256];
@@ -921,9 +921,9 @@
         if( result == 0 )
         {
 
-            TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
+            TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
                                               ctx.len,
-                                              result_hex_str->len ) == 0 );
+                                              result_str->len ) == 0 );
         }
     }
 
@@ -941,9 +941,9 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
                                           ctx2.len,
-                                          result_hex_str->len ) == 0 );
+                                          result_str->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_shax.function b/tests/suites/test_suite_shax.function
index 6428009..f3477ec 100644
--- a/tests/suites/test_suite_shax.function
+++ b/tests/suites/test_suite_shax.function
@@ -52,7 +52,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA1_C */
-void mbedtls_sha1( data_t * src_str, data_t * hex_hash_string )
+void mbedtls_sha1( data_t * src_str, data_t * hash )
 {
     unsigned char output[41];
 
@@ -61,8 +61,7 @@
 
     TEST_ASSERT( mbedtls_sha1_ret( src_str->x, src_str->len, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      20, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 20, hash->len ) == 0 );
 }
 /* END_CASE */
 
@@ -123,7 +122,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
-void sha224( data_t * src_str, data_t * hex_hash_string )
+void sha224( data_t * src_str, data_t * hash )
 {
     unsigned char output[57];
 
@@ -132,13 +131,12 @@
 
     TEST_ASSERT( mbedtls_sha256_ret( src_str->x, src_str->len, output, 1 ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      28, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 28, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
-void mbedtls_sha256( data_t * src_str, data_t * hex_hash_string )
+void mbedtls_sha256( data_t * src_str, data_t * hash )
 {
     unsigned char output[65];
 
@@ -147,8 +145,7 @@
 
     TEST_ASSERT( mbedtls_sha256_ret( src_str->x, src_str->len, output, 0 ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      32, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 32, hash->len ) == 0 );
 }
 /* END_CASE */
 
@@ -209,7 +206,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA512_C */
-void sha384( data_t * src_str, data_t * hex_hash_string )
+void sha384( data_t * src_str, data_t * hash )
 {
     unsigned char output[97];
 
@@ -218,13 +215,12 @@
 
     TEST_ASSERT( mbedtls_sha512_ret( src_str->x, src_str->len, output, 1 ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      48, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 48, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA512_C */
-void mbedtls_sha512( data_t * src_str, data_t * hex_hash_string )
+void mbedtls_sha512( data_t * src_str, data_t * hash )
 {
     unsigned char output[129];
 
@@ -233,8 +229,7 @@
 
     TEST_ASSERT( mbedtls_sha512_ret( src_str->x, src_str->len, output, 0 ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_hash_string->x,
-                                      64, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 64, hash->len ) == 0 );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 9fcf367..f377ffa 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -3824,11 +3824,11 @@
 
 /* BEGIN_CASE */
 void ssl_tls_prf( int type, data_t * secret, data_t * random,
-                  char *label, data_t *result_hex_str, int exp_ret )
+                  char *label, data_t *result_str, int exp_ret )
 {
     unsigned char *output;
 
-    output = mbedtls_calloc( 1, result_hex_str->len );
+    output = mbedtls_calloc( 1, result_str->len );
     if( output == NULL )
         goto exit;
 
@@ -3838,12 +3838,12 @@
 
     TEST_ASSERT( mbedtls_ssl_tls_prf( type, secret->x, secret->len,
                                       label, random->x, random->len,
-                                      output, result_hex_str->len ) == exp_ret );
+                                      output, result_str->len ) == exp_ret );
 
     if( exp_ret == 0 )
     {
-        TEST_ASSERT( mbedtls_test_hexcmp( output, result_hex_str->x,
-                     result_hex_str->len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                     result_str->len, result_str->len ) == 0 );
     }
 exit:
 
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 9cac2ec..2bba4e2 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -1220,21 +1220,21 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT */
-void x509_parse_rsassa_pss_params( data_t * hex_params, int params_tag,
+void x509_parse_rsassa_pss_params( data_t * params, int params_tag,
                                    int ref_msg_md, int ref_mgf_md,
                                    int ref_salt_len, int ref_ret )
 {
     int my_ret;
-    mbedtls_x509_buf params;
+    mbedtls_x509_buf buf;
     mbedtls_md_type_t my_msg_md, my_mgf_md;
     int my_salt_len;
 
-    params.p = hex_params->x;
-    params.len = hex_params->len;
-    params.tag = params_tag;
+    buf.p = params->x;
+    buf.len = params->len;
+    buf.tag = params_tag;
 
-    my_ret = mbedtls_x509_get_rsassa_pss_params( &params, &my_msg_md, &my_mgf_md,
-                                         &my_salt_len );
+    my_ret = mbedtls_x509_get_rsassa_pss_params( &buf, &my_msg_md, &my_mgf_md,
+                                                 &my_salt_len );
 
     TEST_ASSERT( my_ret == ref_ret );
 
diff --git a/tests/suites/test_suite_xtea.function b/tests/suites/test_suite_xtea.function
index f286e67..1d5b29b 100644
--- a/tests/suites/test_suite_xtea.function
+++ b/tests/suites/test_suite_xtea.function
@@ -9,7 +9,7 @@
 
 /* BEGIN_CASE */
 void xtea_encrypt_ecb( data_t * key_str, data_t * src_str,
-                       data_t * hex_dst_string )
+                       data_t * dst )
 {
     unsigned char output[100];
     mbedtls_xtea_context ctx;
@@ -20,14 +20,12 @@
     mbedtls_xtea_setup( &ctx, key_str->x );
     TEST_ASSERT( mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
-void xtea_decrypt_ecb( data_t * key_str, data_t * src_str,
-                       data_t * hex_dst_string )
+void xtea_decrypt_ecb( data_t * key_str, data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_xtea_context ctx;
@@ -38,14 +36,13 @@
     mbedtls_xtea_setup( &ctx, key_str->x );
     TEST_ASSERT( mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_DECRYPT, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void xtea_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_xtea_context ctx;
@@ -57,15 +54,14 @@
     TEST_ASSERT( mbedtls_xtea_crypt_cbc( &ctx, MBEDTLS_XTEA_ENCRYPT, src_str->len, iv_str->x,
                                  src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      src_str->len,
-                                      hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void xtea_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_xtea_context ctx;
@@ -77,9 +73,8 @@
     TEST_ASSERT( mbedtls_xtea_crypt_cbc( &ctx, MBEDTLS_XTEA_DECRYPT, src_str->len, iv_str->x,
                                  src_str->x, output ) == 0 );
 
-    TEST_ASSERT( mbedtls_test_hexcmp( output, hex_dst_string->x,
-                                      src_str->len,
-                                      hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 }
 /* END_CASE */
 
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index b243b73..801f17c 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -162,6 +162,7 @@
     <ClInclude Include="..\..\include\mbedtls\cmac.h" />

     <ClInclude Include="..\..\include\mbedtls\compat-1.3.h" />

     <ClInclude Include="..\..\include\mbedtls\config.h" />

+    <ClInclude Include="..\..\include\mbedtls\config_psa.h" />

     <ClInclude Include="..\..\include\mbedtls\ctr_drbg.h" />

     <ClInclude Include="..\..\include\mbedtls\debug.h" />

     <ClInclude Include="..\..\include\mbedtls\des.h" />

@@ -223,6 +224,7 @@
     <ClInclude Include="..\..\include\psa\crypto.h" />

     <ClInclude Include="..\..\include\psa\crypto_accel_driver.h" />

     <ClInclude Include="..\..\include\psa\crypto_compat.h" />

+    <ClInclude Include="..\..\include\psa\crypto_config.h" />

     <ClInclude Include="..\..\include\psa\crypto_driver_common.h" />

     <ClInclude Include="..\..\include\psa\crypto_entropy_driver.h" />

     <ClInclude Include="..\..\include\psa\crypto_extra.h" />

@@ -239,8 +241,9 @@
     <ClInclude Include="..\..\tests\include\test\psa_helpers.h" />

     <ClInclude Include="..\..\tests\include\test\random.h" />

     <ClInclude Include="..\..\tests\include\test\drivers\cipher.h" />

-    <ClInclude Include="..\..\tests\include\test\drivers\keygen.h" />

+    <ClInclude Include="..\..\tests\include\test\drivers\key_management.h" />

     <ClInclude Include="..\..\tests\include\test\drivers\signature.h" />

+    <ClInclude Include="..\..\tests\include\test\drivers\size.h" />

     <ClInclude Include="..\..\tests\include\test\drivers\test_driver.h" />

     <ClInclude Include="..\..\library\common.h" />

     <ClInclude Include="..\..\library\psa_crypto_core.h" />