Merge pull request #6543 from mpg/improve-test-suites-listing

Improve test suite detection in run-test-suites.pl
diff --git a/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt b/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt
new file mode 100644
index 0000000..5797f48
--- /dev/null
+++ b/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt
@@ -0,0 +1,4 @@
+Bugfix
+    * Fix TLS 1.3 session resumption fail. Fixes #6488.
+    * Add configuration check to exclude TLS 1.3 optional authentication of
+      client.
diff --git a/ChangeLog.d/fix_x509_info_hwmodulename.txt b/ChangeLog.d/fix_x509_info_hwmodulename.txt
new file mode 100644
index 0000000..8b227ce
--- /dev/null
+++ b/ChangeLog.d/fix_x509_info_hwmodulename.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix a bug in which mbedtls_x509_crt_info() would produce non-printable
+     bytes when parsing certificates containing a binary RFC 4108
+     HardwareModuleName as a Subject Alternative Name extension. Hardware
+     serial numbers are now rendered in hex format. Fixes #6262.
diff --git a/ChangeLog.d/mbedtls_asn1_type_free.txt b/ChangeLog.d/mbedtls_asn1_type_free.txt
new file mode 100644
index 0000000..81f3a20
--- /dev/null
+++ b/ChangeLog.d/mbedtls_asn1_type_free.txt
@@ -0,0 +1,6 @@
+Features
+   * Shared code to free x509 structs like mbedtls_x509_named_data
+New deprecations
+   * Deprecate mbedtls_asn1_free_named_data().
+     Use mbedtls_asn1_free_named_data_list()
+     or mbedtls_asn1_free_named_data_list_shallow()
diff --git a/ChangeLog.d/psa_crypto_code_gen_1_1.txt b/ChangeLog.d/psa_crypto_code_gen_1_1.txt
new file mode 100644
index 0000000..2c18e6f
--- /dev/null
+++ b/ChangeLog.d/psa_crypto_code_gen_1_1.txt
@@ -0,0 +1,6 @@
+Features
+    * Brought in PSA code geneneration JSON driver list.
+      Added auto generated templating support for key management.
+      Added Support for transparent and opaque keys (import/export/copy).
+      Included some general JSON validation for the given entry points.
+      Addresses version 1.1 of #5137.
diff --git a/docs/proposed/psa-driver-developer-guide.md b/docs/proposed/psa-driver-developer-guide.md
index 70cb9d3..b39f559 100644
--- a/docs/proposed/psa-driver-developer-guide.md
+++ b/docs/proposed/psa-driver-developer-guide.md
@@ -36,6 +36,12 @@
 
 Mbed TLS calls driver entry points [as specified in the PSA Cryptography Driver Interface specification](psa-driver-interface.html#driver-entry-points) except as otherwise indicated in this section.
 
+## Mbed TLS extensions
+
+The driver description can include Mbed TLS extensions (marked by the namespace "mbedtls"). Mbed TLS extensions are meant to extend/help integrating the driver into the library's infrastructure.
+* `"mbedtls/h_condition"` (optional, string) can include complex preprocessor definitions to conditionally include header files for a given driver. 
+* `"mbedtls/c_condition"` (optional, string) can include complex preprocessor definitions to conditionally enable dispatch capabilities for a driver.
+
 ## Building and testing your driver
 
 <!-- TODO -->
diff --git a/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md b/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md
index 6172159..6144aad 100644
--- a/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md
+++ b/docs/proposed/psa-driver-wrappers-codegen-migration-guide.md
@@ -13,20 +13,28 @@
 
 ## Prerequisites
 
-Python3 and Jinja2 rev 2.10.1
+Python3, Jinja2 rev 2.10.1 and jsonschema rev 3.2.0
 
 ## Feature Version
 
-1.0
+1.1
 
 ### What's critical for a migrating user
 
 The Driver Wrapper auto generation project is designed to use a python templating library ( Jinja2 ) to render templates based on drivers that are defined using a Driver description JSON file(s).
 
-While that is the larger goal, for version 1.0 here's what's changed
+While that is the larger goal, for version 1.1 here's what's changed
 
 #### What's changed
 
 (1) psa_crypto_driver_wrappers.c will from this point on be auto generated.
-(2) The auto generation is based on the template file at scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja.
-(3) So while all driver wrapper templating support is yet to come in, the library user will need to patch into the template file as needed, this could be read as replacing the template file with the current psa_crypto_driver_wrappers.c file maintained by the library user.
+(2) The auto generation is based on the template file at **scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja**.
+(3) The driver JSONS to be used for generating the psa_crypto_driver_wrappers.c file can be found at **scripts/data_files/driver_jsons/** as their default location, this path includes the schemas against which the driver schemas will be validated (driver_opaque_schema.json, driver_transparent_schema.json) and a driverlist.json which specifies the drivers to be considered and the order in which they want to be called into. The default location for driverlist.json and driver JSONS can be overloaded by passing an argument --json-dir while running the script generate_driver_wrappers.py.
+(4) While the complete driver wrapper templating support is yet to come in, if the library user sees a need to patch psa_crypto_driver_wrappers.c file, the user will need to patch into the template file as needed (psa_crypto_driver_wrappers.c.jinja).
+
+#### How to set your driver up
+
+Please refer to psa-driver-interface.md for information on how a driver schema can be written.
+One can also refer to the example test drivers/ JSON schemas under **scripts/data_files/driver_jsons/**.
+
+The JSON file 'driverlist.json' is meant to be edited by the user to reflect the drivers one wants to use on a device. The order in which the drivers are passed is also essential if/when there are multiple transparent drivers on a given system to retain the same order in the templating.
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index be2cae7..8b66ee2 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -24,6 +24,7 @@
 #include "mbedtls/private_access.h"
 
 #include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 
@@ -606,25 +607,41 @@
 const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
                                        const char *oid, size_t len );
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 /**
  * \brief       Free a mbedtls_asn1_named_data entry
  *
+ * \deprecated  This function is deprecated and will be removed in a
+ *              future version of the library.
+ *              Please use mbedtls_asn1_free_named_data_list()
+ *              or mbedtls_asn1_free_named_data_list_shallow().
+ *
  * \param entry The named data entry to free.
  *              This function calls mbedtls_free() on
  *              `entry->oid.p` and `entry->val.p`.
  */
-void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
+void MBEDTLS_DEPRECATED mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
 
 /**
  * \brief       Free all entries in a mbedtls_asn1_named_data list.
  *
  * \param head  Pointer to the head of the list of named data entries to free.
- *              This function calls mbedtls_asn1_free_named_data() and
- *              mbedtls_free() on each list element and
- *              sets \c *head to \c NULL.
+ *              This function calls mbedtls_free() on
+ *              `entry->oid.p` and `entry->val.p` and then on `entry`
+ *              for each list entry, and sets \c *head to \c NULL.
  */
 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
 
+/**
+ * \brief       Free all shallow entries in a mbedtls_asn1_named_data list,
+ *              but do not free internal pointer targets.
+ *
+ * \param name  Head of the list of named data entries to free.
+ *              This function calls mbedtls_free() on each list element.
+ */
+void mbedtls_asn1_free_named_data_list_shallow( mbedtls_asn1_named_data *name );
+
 /** \} name Functions to parse ASN.1 data structures */
 /** \} addtogroup asn1_module */
 
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index ee37430..9d15955 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -758,11 +758,11 @@
  *
  * \param Q        The destination MPI for the quotient.
  *                 This may be \c NULL if the value of the
- *                 quotient is not needed.
+ *                 quotient is not needed. This must not alias A or B.
  * \param R        The destination MPI for the remainder value.
  *                 This may be \c NULL if the value of the
- *                 remainder is not needed.
- * \param A        The dividend. This must point to an initialized MPi.
+ *                 remainder is not needed. This must not alias A or B.
+ * \param A        The dividend. This must point to an initialized MPI.
  * \param B        The divisor. This must point to an initialized MPI.
  *
  * \return         \c 0 if successful.
@@ -779,10 +779,10 @@
  *
  * \param Q        The destination MPI for the quotient.
  *                 This may be \c NULL if the value of the
- *                 quotient is not needed.
+ *                 quotient is not needed.  This must not alias A.
  * \param R        The destination MPI for the remainder value.
  *                 This may be \c NULL if the value of the
- *                 remainder is not needed.
+ *                 remainder is not needed.  This must not alias A.
  * \param A        The dividend. This must point to an initialized MPi.
  * \param b        The divisor.
  *
@@ -837,6 +837,7 @@
  * \brief          Perform a sliding-window exponentiation: X = A^E mod N
  *
  * \param X        The destination MPI. This must point to an initialized MPI.
+ *                 This must not alias E or N.
  * \param A        The base of the exponentiation.
  *                 This must point to an initialized MPI.
  * \param E        The exponent MPI. This must point to an initialized MPI.
diff --git a/include/mbedtls/lms.h b/include/mbedtls/lms.h
index 5e03d9b..fe87d40 100644
--- a/include/mbedtls/lms.h
+++ b/include/mbedtls/lms.h
@@ -30,6 +30,7 @@
 #include <stdint.h>
 #include <stddef.h>
 
+#include "mbedtls/private_access.h"
 #include "mbedtls/build_info.h"
 
 #define MBEDTLS_ERR_LMS_BAD_INPUT_DATA   -0x0011 /**< Bad data has been input to an LMS function */
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 6c2e06e..4f65398 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -1765,9 +1765,9 @@
       primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,      \
                                       PSA_ECC_FAMILY_SECP_R1, 256) ?    \
       (                                                                 \
-        output_step == PSA_PAKE_STEP_KEY_SHARE ? 69 :                   \
-        output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 66 :                   \
-        33                                                              \
+        output_step == PSA_PAKE_STEP_KEY_SHARE ? 65 :                   \
+        output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 :                   \
+        32                                                              \
       ) :                                                               \
       0 )
 
@@ -1795,9 +1795,9 @@
       primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,      \
                                       PSA_ECC_FAMILY_SECP_R1, 256) ?    \
       (                                                                 \
-        input_step == PSA_PAKE_STEP_KEY_SHARE ? 69 :                    \
-        input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 66 :                    \
-        33                                                              \
+        input_step == PSA_PAKE_STEP_KEY_SHARE ? 65 :                    \
+        input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 :                    \
+        32                                                              \
       ) :                                                               \
       0 )
 
@@ -1808,7 +1808,7 @@
  *
  * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p step).
  */
-#define PSA_PAKE_OUTPUT_MAX_SIZE 69
+#define PSA_PAKE_OUTPUT_MAX_SIZE 65
 
 /** Input buffer size for psa_pake_input() for any of the supported PAKE
  * algorithm and primitive suites and input step.
@@ -1817,7 +1817,7 @@
  *
  * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p step).
  */
-#define PSA_PAKE_INPUT_MAX_SIZE 69
+#define PSA_PAKE_INPUT_MAX_SIZE 65
 
 /** Returns a suitable initializer for a PAKE cipher suite object of type
  * psa_pake_cipher_suite_t.
@@ -1906,7 +1906,10 @@
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
 #include <mbedtls/ecjpake.h>
-#define PSA_PAKE_BUFFER_SIZE ( ( 69 + 66 + 33 ) * 2 )
+/* Note: the format for mbedtls_ecjpake_read/write function has an extra
+ * length byte for each step, plus an extra 3 bytes for ECParameters in the
+ * server's 2nd round. */
+#define MBEDTLS_PSA_PAKE_BUFFER_SIZE ( ( 3 + 1 + 65 + 1 + 65 + 1 + 32 ) * 2 )
 #endif
 
 struct psa_pake_operation_s
@@ -1919,7 +1922,7 @@
     unsigned int MBEDTLS_PRIVATE(output_step);
     mbedtls_svc_key_id_t MBEDTLS_PRIVATE(password);
     psa_pake_role_t MBEDTLS_PRIVATE(role);
-    uint8_t MBEDTLS_PRIVATE(buffer[PSA_PAKE_BUFFER_SIZE]);
+    uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_PAKE_BUFFER_SIZE]);
     size_t MBEDTLS_PRIVATE(buffer_length);
     size_t MBEDTLS_PRIVATE(buffer_offset);
 #endif
diff --git a/library/asn1parse.c b/library/asn1parse.c
index d874fff..28a3b14 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -314,7 +314,6 @@
     while( seq != NULL )
     {
         mbedtls_asn1_sequence *next = seq->next;
-        mbedtls_platform_zeroize( seq, sizeof( *seq ) );
         mbedtls_free( seq );
         seq = next;
     }
@@ -432,6 +431,7 @@
     return( 0 );
 }
 
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
 {
     if( cur == NULL )
@@ -442,6 +442,7 @@
 
     mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
 }
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
 
 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
 {
@@ -450,11 +451,21 @@
     while( ( cur = *head ) != NULL )
     {
         *head = cur->next;
-        mbedtls_asn1_free_named_data( cur );
+        mbedtls_free( cur->oid.p );
+        mbedtls_free( cur->val.p );
         mbedtls_free( cur );
     }
 }
 
+void mbedtls_asn1_free_named_data_list_shallow( mbedtls_asn1_named_data *name )
+{
+    for( mbedtls_asn1_named_data *next; name != NULL; name = next )
+    {
+        next = name->next;
+        mbedtls_free( name );
+    }
+}
+
 const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
                                        const char *oid, size_t len )
 {
diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h
index 9cc63c2..1e4a3ab 100644
--- a/library/constant_time_internal.h
+++ b/library/constant_time_internal.h
@@ -138,6 +138,7 @@
  * \param B        The right-hand MPI. This must point to an array of limbs
  *                 with the same allocated length as \p A.
  * \param limbs    The number of limbs in \p A and \p B.
+ *                 This must not be 0.
  *
  * \return         The result of the comparison:
  *                 \c 1 if \p A is less than \p B.
diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c
index 10d3e4a..870b5b5 100644
--- a/library/psa_crypto_pake.c
+++ b/library/psa_crypto_pake.c
@@ -230,7 +230,7 @@
         operation->input_step = PSA_PAKE_STEP_X1_X2;
         operation->output_step = PSA_PAKE_STEP_X1_X2;
 
-        mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
+        mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
         operation->buffer_length = 0;
         operation->buffer_offset = 0;
 
@@ -385,7 +385,8 @@
 }
 #endif
 
-psa_status_t psa_pake_output( psa_pake_operation_t *operation,
+static psa_status_t psa_pake_output_internal(
+                              psa_pake_operation_t *operation,
                               psa_pake_step_t step,
                               uint8_t *output,
                               size_t output_size,
@@ -427,10 +428,7 @@
         if( operation->state == PSA_PAKE_STATE_SETUP ) {
             status = psa_pake_ecjpake_setup( operation );
             if( status != PSA_SUCCESS )
-            {
-                psa_pake_abort( operation );
                 return( status );
-            }
         }
 
         if( operation->state != PSA_PAKE_STATE_READY &&
@@ -491,15 +489,12 @@
         {
             ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake,
                                                    operation->buffer,
-                                                   PSA_PAKE_BUFFER_SIZE,
+                                                   MBEDTLS_PSA_PAKE_BUFFER_SIZE,
                                                    &operation->buffer_length,
                                                    mbedtls_psa_get_random,
                                                    MBEDTLS_PSA_RANDOM_STATE );
             if( ret != 0 )
-            {
-                psa_pake_abort( operation );
                 return( mbedtls_ecjpake_to_psa_error( ret ) );
-            }
 
             operation->buffer_offset = 0;
         }
@@ -508,68 +503,47 @@
         {
             ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake,
                                                    operation->buffer,
-                                                   PSA_PAKE_BUFFER_SIZE,
+                                                   MBEDTLS_PSA_PAKE_BUFFER_SIZE,
                                                    &operation->buffer_length,
                                                    mbedtls_psa_get_random,
                                                    MBEDTLS_PSA_RANDOM_STATE );
             if( ret != 0 )
-            {
-                psa_pake_abort( operation );
                 return( mbedtls_ecjpake_to_psa_error( ret ) );
-            }
 
             operation->buffer_offset = 0;
         }
 
         /*
-         * Steps sequences are stored as:
-         * struct {
-         *     opaque point <1..2^8-1>;
-         * } ECPoint;
+         * mbedtls_ecjpake_write_round_xxx() outputs thing in the format
+         * defined by draft-cragie-tls-ecjpake-01 section 7. The summary is
+         * that the data for each step is prepended with a length byte, and
+         * then they're concatenated. Additionally, the server's second round
+         * output is prepended with a 3-bytes ECParameters structure.
          *
-         * Where byte 0 stores the ECPoint curve point length.
-         *
-         * The sequence length is equal to:
-         * - data length extracted from byte 0
-         * - byte 0 size (1)
+         * In PSA, we output each step separately, and don't prepend the
+         * output with a length byte, even less a curve identifier, as that
+         * information is already available.
          */
         if( operation->state == PSA_PAKE_OUTPUT_X2S &&
-            operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
+            operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
+            operation->role == PSA_PAKE_ROLE_SERVER )
         {
-            if( operation->role == PSA_PAKE_ROLE_SERVER )
-                /*
-                 * The X2S KEY SHARE Server steps sequence is stored as:
-                 * struct {
-                 *     ECPoint X;
-                 *    opaque r <1..2^8-1>;
-                 * } ECSchnorrZKP;
-                 *
-                 * And MbedTLS uses a 3 bytes Ephemeral public key ECPoint,
-                 * so byte 3 stores the r Schnorr signature length.
-                 *
-                 * The sequence length is equal to:
-                 * - curve storage size (3)
-                 * - data length extracted from byte 3
-                 * - byte 3 size (1)
-                 */
-                length = 3 + operation->buffer[3] + 1;
-            else
-                length = operation->buffer[0] + 1;
+            /* Skip ECParameters, with is 3 bytes (RFC 8422) */
+            operation->buffer_offset += 3;
         }
-        else
-            length = operation->buffer[operation->buffer_offset] + 1;
 
-        if( length > operation->buffer_length )
+        /* Read the length byte then move past it to the data */
+        length = operation->buffer[operation->buffer_offset];
+        operation->buffer_offset += 1;
+
+        if( operation->buffer_offset + length > operation->buffer_length )
             return( PSA_ERROR_DATA_CORRUPT );
 
         if( output_size < length )
-        {
-            psa_pake_abort( operation );
             return( PSA_ERROR_BUFFER_TOO_SMALL );
-        }
 
         memcpy( output,
-                operation->buffer +  operation->buffer_offset,
+                operation->buffer + operation->buffer_offset,
                 length );
         *output_length = length;
 
@@ -581,7 +555,7 @@
             ( operation->state == PSA_PAKE_OUTPUT_X2S &&
               operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
         {
-            mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
+            mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
             operation->buffer_length = 0;
             operation->buffer_offset = 0;
 
@@ -599,14 +573,29 @@
     return( PSA_ERROR_NOT_SUPPORTED );
 }
 
-psa_status_t psa_pake_input( psa_pake_operation_t *operation,
+psa_status_t psa_pake_output( psa_pake_operation_t *operation,
+                              psa_pake_step_t step,
+                              uint8_t *output,
+                              size_t output_size,
+                              size_t *output_length )
+{
+    psa_status_t status = psa_pake_output_internal(
+            operation, step, output, output_size, output_length );
+
+    if( status != PSA_SUCCESS )
+        psa_pake_abort( operation );
+
+    return( status );
+}
+
+static psa_status_t psa_pake_input_internal(
+                             psa_pake_operation_t *operation,
                              psa_pake_step_t step,
                              const uint8_t *input,
                              size_t input_length )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-    size_t buffer_remain;
 
     if( operation->alg == PSA_ALG_NONE ||
         operation->state == PSA_PAKE_STATE_INVALID )
@@ -638,14 +627,16 @@
             step != PSA_PAKE_STEP_ZK_PROOF )
             return( PSA_ERROR_INVALID_ARGUMENT );
 
+        const psa_pake_primitive_t prim = PSA_PAKE_PRIMITIVE(
+                PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256 );
+        if( input_length > (size_t) PSA_PAKE_INPUT_SIZE( PSA_ALG_JPAKE, prim, step ) )
+            return( PSA_ERROR_INVALID_ARGUMENT );
+
         if( operation->state == PSA_PAKE_STATE_SETUP )
         {
             status = psa_pake_ecjpake_setup( operation );
             if( status != PSA_SUCCESS )
-            {
-                psa_pake_abort( operation );
                 return( status );
-            }
         }
 
         if( operation->state != PSA_PAKE_STATE_READY &&
@@ -675,15 +666,6 @@
             operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
         }
 
-        buffer_remain = PSA_PAKE_BUFFER_SIZE - operation->buffer_length;
-
-        if( input_length == 0 ||
-            input_length > buffer_remain )
-        {
-            psa_pake_abort( operation );
-            return( PSA_ERROR_INSUFFICIENT_MEMORY );
-        }
-
         /* Check if step matches current sequence */
         switch( operation->sequence )
         {
@@ -709,7 +691,35 @@
                 return( PSA_ERROR_BAD_STATE );
         }
 
-        /* Copy input to local buffer */
+        /*
+         * Copy input to local buffer and format it as the Mbed TLS API
+         * expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
+         * The summary is that the data for each step is prepended with a
+         * length byte, and then they're concatenated. Additionally, the
+         * server's second round output is prepended with a 3-bytes
+         * ECParameters structure - which means we have to prepend that when
+         * we're a client.
+         */
+        if( operation->state == PSA_PAKE_INPUT_X4S &&
+            operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
+            operation->role == PSA_PAKE_ROLE_CLIENT )
+        {
+            /* We only support secp256r1. */
+            /* This is the ECParameters structure defined by RFC 8422. */
+            unsigned char ecparameters[3] = {
+                3, /* named_curve */
+                0, 23 /* secp256r1 */
+            };
+            memcpy( operation->buffer + operation->buffer_length,
+                    ecparameters, sizeof( ecparameters ) );
+            operation->buffer_length += sizeof( ecparameters );
+        }
+
+        /* Write the length byte */
+        operation->buffer[operation->buffer_length] = (uint8_t) input_length;
+        operation->buffer_length += 1;
+
+        /* Finally copy the data */
         memcpy( operation->buffer + operation->buffer_length,
                 input, input_length );
         operation->buffer_length += input_length;
@@ -722,14 +732,11 @@
                                                   operation->buffer,
                                                   operation->buffer_length );
 
-            mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
+            mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
             operation->buffer_length = 0;
 
             if( ret != 0 )
-            {
-                psa_pake_abort( operation );
                 return( mbedtls_ecjpake_to_psa_error( ret ) );
-            }
         }
         else if( operation->state == PSA_PAKE_INPUT_X4S &&
                  operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF )
@@ -738,14 +745,11 @@
                                                   operation->buffer,
                                                   operation->buffer_length );
 
-            mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
+            mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
             operation->buffer_length = 0;
 
             if( ret != 0 )
-            {
-                psa_pake_abort( operation );
                 return( mbedtls_ecjpake_to_psa_error( ret ) );
-            }
         }
 
         if( ( operation->state == PSA_PAKE_INPUT_X1_X2 &&
@@ -767,6 +771,20 @@
     return( PSA_ERROR_NOT_SUPPORTED );
 }
 
+psa_status_t psa_pake_input( psa_pake_operation_t *operation,
+                             psa_pake_step_t step,
+                             const uint8_t *input,
+                             size_t input_length )
+{
+    psa_status_t status = psa_pake_input_internal(
+            operation, step, input, input_length );
+
+    if( status != PSA_SUCCESS )
+        psa_pake_abort( operation );
+
+    return( status );
+}
+
 psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
                                        psa_key_derivation_operation_t *output)
 {
@@ -784,7 +802,7 @@
     {
         ret = mbedtls_ecjpake_write_shared_key( &operation->ctx.ecjpake,
                                                 operation->buffer,
-                                                PSA_PAKE_BUFFER_SIZE,
+                                                MBEDTLS_PSA_PAKE_BUFFER_SIZE,
                                                 &operation->buffer_length,
                                                 mbedtls_psa_get_random,
                                                 MBEDTLS_PSA_RANDOM_STATE );
@@ -799,7 +817,7 @@
                                                  operation->buffer,
                                                  operation->buffer_length );
 
-        mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
+        mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
 
         psa_pake_abort( operation );
 
@@ -824,7 +842,7 @@
         operation->output_step = PSA_PAKE_STEP_INVALID;
         operation->password = MBEDTLS_SVC_KEY_ID_INIT;
         operation->role = PSA_PAKE_ROLE_NONE;
-        mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
+        mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
         operation->buffer_length = 0;
         operation->buffer_offset = 0;
         mbedtls_ecjpake_free( &operation->ctx.ecjpake );
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 4cd4107..dbc6391 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -1797,8 +1797,7 @@
 
     if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
-                            "or mbedtls_ssl_set_bio()" ) );
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " ) );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
@@ -2013,8 +2012,7 @@
 
     if( ssl->f_send == NULL )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
-                            "or mbedtls_ssl_set_bio()" ) );
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " ) );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 3c91b45..dbbd6f2 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1012,6 +1012,30 @@
     if( ret != 0 )
         return( ret );
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    /* RFC 8446 section 4.4.3
+     *
+     * If the verification fails, the receiver MUST terminate the handshake with
+     * a "decrypt_error" alert.
+     *
+     * If the client is configured as TLS 1.3 only with optional verify, return
+     * bad config.
+     *
+     */
+    if( mbedtls_ssl_conf_tls13_ephemeral_enabled(
+            (mbedtls_ssl_context *)ssl )                            &&
+        ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT                &&
+        ssl->conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3    &&
+        ssl->conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_3    &&
+        ssl->conf->authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG(
+            1, ( "Optional verify auth mode "
+                 "is not available for TLS 1.3 client" ) );
+        return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+
     /* Space for further checks */
 
     return( 0 );
@@ -3352,6 +3376,10 @@
     if( ret != 0 )
         goto cleanup;
 
+    /* If ssl->conf->endpoint is not one of MBEDTLS_SSL_IS_CLIENT or
+     * MBEDTLS_SSL_IS_SERVER, this is the return code we give */
+    ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+
 #if defined(MBEDTLS_SSL_CLI_C)
     if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
     {
@@ -3362,6 +3390,7 @@
         {
             case MBEDTLS_SSL_HELLO_REQUEST:
                 ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
+                ret = 0;
                 break;
 
             case MBEDTLS_SSL_CLIENT_HELLO:
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index 5360b3c..1c53a09 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -2680,7 +2680,6 @@
     {
         unsigned char *p = dn + i + 2;
         mbedtls_x509_name name;
-        mbedtls_x509_name *name_cur, *name_prv;
         size_t asn1_len;
         char s[MBEDTLS_X509_MAX_DN_NAME_SIZE];
         memset( &name, 0, sizeof( name ) );
@@ -2700,14 +2699,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 3,
             ( "DN hint: %.*s",
               mbedtls_x509_dn_gets( s, sizeof(s), &name ), s ) );
-        name_cur = name.next;
-        while( name_cur != NULL )
-        {
-            name_prv = name_cur;
-            name_cur = name_cur->next;
-            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
-            mbedtls_free( name_prv );
-        }
+        mbedtls_asn1_free_named_data_list_shallow( name.next );
     }
 #endif
 
diff --git a/library/x509.c b/library/x509.c
index c5b0161..362e036 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -472,7 +472,6 @@
     size_t set_len;
     const unsigned char *end_set;
     mbedtls_x509_name *head = cur;
-    mbedtls_x509_name *prev, *allocated;
 
     /* don't use recursion, we'd risk stack overflow if not optimized */
     while( 1 )
@@ -530,18 +529,8 @@
 
 error:
     /* Skip the first element as we did not allocate it */
-    allocated = head->next;
-
-    while( allocated != NULL )
-    {
-        prev = allocated;
-        allocated = allocated->next;
-
-        mbedtls_platform_zeroize( prev, sizeof( *prev ) );
-        mbedtls_free( prev );
-    }
-
-    mbedtls_platform_zeroize( head, sizeof( *head ) );
+    mbedtls_asn1_free_named_data_list_shallow( head->next );
+    head->next = NULL;
 
     return( ret );
 }
diff --git a/library/x509_crl.c b/library/x509_crl.c
index 2a3fac7..d830fcd 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -705,28 +705,16 @@
 {
     mbedtls_x509_crl *crl_cur = crl;
     mbedtls_x509_crl *crl_prv;
-    mbedtls_x509_name *name_cur;
-    mbedtls_x509_name *name_prv;
     mbedtls_x509_crl_entry *entry_cur;
     mbedtls_x509_crl_entry *entry_prv;
 
-    if( crl == NULL )
-        return;
-
-    do
+    while( crl_cur != NULL )
     {
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
         mbedtls_free( crl_cur->sig_opts );
 #endif
 
-        name_cur = crl_cur->issuer.next;
-        while( name_cur != NULL )
-        {
-            name_prv = name_cur;
-            name_cur = name_cur->next;
-            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
-            mbedtls_free( name_prv );
-        }
+        mbedtls_asn1_free_named_data_list_shallow( crl_cur->issuer.next );
 
         entry_cur = crl_cur->entry.next;
         while( entry_cur != NULL )
@@ -744,13 +732,6 @@
             mbedtls_free( crl_cur->raw.p );
         }
 
-        crl_cur = crl_cur->next;
-    }
-    while( crl_cur != NULL );
-
-    crl_cur = crl;
-    do
-    {
         crl_prv = crl_cur;
         crl_cur = crl_cur->next;
 
@@ -758,7 +739,6 @@
         if( crl_prv != crl )
             mbedtls_free( crl_prv );
     }
-    while( crl_cur != NULL );
 }
 
 #endif /* MBEDTLS_X509_CRL_PARSE_C */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index c4f97bb..0eee97c 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -685,16 +685,7 @@
          */
         if( ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
         {
-            mbedtls_x509_sequence *seq_cur = subject_alt_name->next;
-            mbedtls_x509_sequence *seq_prv;
-            while( seq_cur != NULL )
-            {
-                seq_prv = seq_cur;
-                seq_cur = seq_cur->next;
-                mbedtls_platform_zeroize( seq_prv,
-                                          sizeof( mbedtls_x509_sequence ) );
-                mbedtls_free( seq_prv );
-            }
+            mbedtls_asn1_sequence_free( subject_alt_name->next );
             subject_alt_name->next = NULL;
             return( ret );
         }
@@ -1846,6 +1837,7 @@
                                        const char *prefix )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t i;
     size_t n = *size;
     char *p = *buf;
     const mbedtls_x509_sequence *cur = subject_alt_name;
@@ -1898,18 +1890,11 @@
                     ret = mbedtls_snprintf( p, n, "\n%s            hardware serial number : ", prefix );
                     MBEDTLS_X509_SAFE_SNPRINTF;
 
-                    if( other_name->value.hardware_module_name.val.len >= n )
+                    for( i = 0; i < other_name->value.hardware_module_name.val.len; i++ )
                     {
-                        *p = '\0';
-                        return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+                        ret = mbedtls_snprintf( p, n, "%02X", other_name->value.hardware_module_name.val.p[i] );
+                        MBEDTLS_X509_SAFE_SNPRINTF;
                     }
-
-                    memcpy( p, other_name->value.hardware_module_name.val.p,
-                            other_name->value.hardware_module_name.val.len );
-                    p += other_name->value.hardware_module_name.val.len;
-
-                    n -= other_name->value.hardware_module_name.val.len;
-
                 }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
             }
             break;
@@ -3300,15 +3285,8 @@
 {
     mbedtls_x509_crt *cert_cur = crt;
     mbedtls_x509_crt *cert_prv;
-    mbedtls_x509_name *name_cur;
-    mbedtls_x509_name *name_prv;
-    mbedtls_x509_sequence *seq_cur;
-    mbedtls_x509_sequence *seq_prv;
 
-    if( crt == NULL )
-        return;
-
-    do
+    while( cert_cur != NULL )
     {
         mbedtls_pk_free( &cert_cur->pk );
 
@@ -3316,53 +3294,11 @@
         mbedtls_free( cert_cur->sig_opts );
 #endif
 
-        name_cur = cert_cur->issuer.next;
-        while( name_cur != NULL )
-        {
-            name_prv = name_cur;
-            name_cur = name_cur->next;
-            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
-            mbedtls_free( name_prv );
-        }
-
-        name_cur = cert_cur->subject.next;
-        while( name_cur != NULL )
-        {
-            name_prv = name_cur;
-            name_cur = name_cur->next;
-            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
-            mbedtls_free( name_prv );
-        }
-
-        seq_cur = cert_cur->ext_key_usage.next;
-        while( seq_cur != NULL )
-        {
-            seq_prv = seq_cur;
-            seq_cur = seq_cur->next;
-            mbedtls_platform_zeroize( seq_prv,
-                                      sizeof( mbedtls_x509_sequence ) );
-            mbedtls_free( seq_prv );
-        }
-
-        seq_cur = cert_cur->subject_alt_names.next;
-        while( seq_cur != NULL )
-        {
-            seq_prv = seq_cur;
-            seq_cur = seq_cur->next;
-            mbedtls_platform_zeroize( seq_prv,
-                                      sizeof( mbedtls_x509_sequence ) );
-            mbedtls_free( seq_prv );
-        }
-
-        seq_cur = cert_cur->certificate_policies.next;
-        while( seq_cur != NULL )
-        {
-            seq_prv = seq_cur;
-            seq_cur = seq_cur->next;
-            mbedtls_platform_zeroize( seq_prv,
-                                      sizeof( mbedtls_x509_sequence ) );
-            mbedtls_free( seq_prv );
-        }
+        mbedtls_asn1_free_named_data_list_shallow( cert_cur->issuer.next );
+        mbedtls_asn1_free_named_data_list_shallow( cert_cur->subject.next );
+        mbedtls_asn1_sequence_free( cert_cur->ext_key_usage.next );
+        mbedtls_asn1_sequence_free( cert_cur->subject_alt_names.next );
+        mbedtls_asn1_sequence_free( cert_cur->certificate_policies.next );
 
         if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
         {
@@ -3370,13 +3306,6 @@
             mbedtls_free( cert_cur->raw.p );
         }
 
-        cert_cur = cert_cur->next;
-    }
-    while( cert_cur != NULL );
-
-    cert_cur = crt;
-    do
-    {
         cert_prv = cert_cur;
         cert_cur = cert_cur->next;
 
@@ -3384,7 +3313,6 @@
         if( cert_prv != crt )
             mbedtls_free( cert_prv );
     }
-    while( cert_cur != NULL );
 }
 
 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
diff --git a/library/x509_csr.c b/library/x509_csr.c
index dee0ea6..f9462ad 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -375,9 +375,6 @@
  */
 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
 {
-    mbedtls_x509_name *name_cur;
-    mbedtls_x509_name *name_prv;
-
     if( csr == NULL )
         return;
 
@@ -387,14 +384,7 @@
     mbedtls_free( csr->sig_opts );
 #endif
 
-    name_cur = csr->subject.next;
-    while( name_cur != NULL )
-    {
-        name_prv = name_cur;
-        name_cur = name_cur->next;
-        mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
-        mbedtls_free( name_prv );
-    }
+    mbedtls_asn1_free_named_data_list_shallow( csr->subject.next );
 
     if( csr->raw.p != NULL )
     {
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 80862f9..86a9c1e 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -83,6 +83,7 @@
 #define DFL_RECSPLIT            -1
 #define DFL_DHMLEN              -1
 #define DFL_RECONNECT           0
+#define DFL_RECO_SERVER_NAME    NULL
 #define DFL_RECO_DELAY          0
 #define DFL_RECO_MODE           1
 #define DFL_CID_ENABLED         0
@@ -403,8 +404,8 @@
     USAGE_RENEGO                                            \
     "    exchanges=%%d        default: 1\n"                 \
     "    reconnect=%%d        number of reconnections using session resumption\n" \
-    "                        default: 0 (disabled)\n"      \
-    "    reco_server_name=%%s  default: localhost\n"         \
+    "                        default: 0 (disabled)\n"       \
+    "    reco_server_name=%%s  default: NULL\n"             \
     "    reco_delay=%%d       default: 0 seconds\n"         \
     "    reco_mode=%%d        0: copy session, 1: serialize session\n" \
     "                        default: 1\n"      \
@@ -921,7 +922,7 @@
     opt.recsplit            = DFL_RECSPLIT;
     opt.dhmlen              = DFL_DHMLEN;
     opt.reconnect           = DFL_RECONNECT;
-    opt.reco_server_name    = DFL_SERVER_NAME;
+    opt.reco_server_name    = DFL_RECO_SERVER_NAME;
     opt.reco_delay          = DFL_RECO_DELAY;
     opt.reco_mode           = DFL_RECO_MODE;
     opt.reconnect_hard      = DFL_RECONNECT_HARD;
@@ -1118,7 +1119,7 @@
             if( opt.reconnect < 0 || opt.reconnect > 2 )
                 goto usage;
         }
-        else if( strcmp( p, "rec_server_name" ) == 0 )
+        else if( strcmp( p, "reco_server_name" ) == 0 )
             opt.reco_server_name = q;
         else if( strcmp( p, "reco_delay" ) == 0 )
         {
@@ -2239,7 +2240,10 @@
                     "    or you didn't set ca_file or ca_path "
                         "to an appropriate value.\n"
                     "    Alternatively, you may want to use "
-                        "auth_mode=optional for testing purposes.\n" );
+                        "auth_mode=optional for testing purposes if "
+                        "not using TLS 1.3.\n"
+                    "    For TLS 1.3 server, try `ca_path=/etc/ssl/certs/`"
+                        "or other folder that has root certificates\n" );
             mbedtls_printf( "\n" );
             goto exit;
         }
@@ -3113,7 +3117,8 @@
         }
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
-        if( ( ret = mbedtls_ssl_set_hostname( &ssl,
+        if( opt.reco_server_name != NULL &&
+            ( ret = mbedtls_ssl_set_hostname( &ssl,
                                               opt.reco_server_name ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n",
diff --git a/scripts/data_files/driver_jsons/driver_opaque_schema.json b/scripts/data_files/driver_jsons/driver_opaque_schema.json
new file mode 100644
index 0000000..933eb07
--- /dev/null
+++ b/scripts/data_files/driver_jsons/driver_opaque_schema.json
@@ -0,0 +1,71 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "type": "object",
+  "properties": {
+    "_comment": {
+      "type": "string"
+    },
+    "prefix": {
+      "type": "string",
+      "pattern": "^[A-Z_a-z][0-9A-Z_a-z]*$"
+    },
+    "type": {
+      "type": "string",
+      "const": ["opaque"]
+    },
+    "location": {
+      "type": ["integer","string"],
+      "pattern": "^(0x|0X)?[a-fA-F0-9]+$"
+    },
+    "mbedtls/h_condition": {
+      "type": "string"
+    },
+    "headers": {
+      "type": "array",
+      "items": {
+          "type": "string"
+        },
+        "default": []
+    },
+    "capabilities": {
+      "type": "array",
+      "items": [
+        {
+          "type": "object",
+          "properties": {
+            "_comment": {
+              "type": "string"
+            },
+            "mbedtls/c_condition": {
+              "type": "string"
+            },
+            "entry_points": {
+              "type": "array",
+              "items": {
+                  "type": "string"
+                }
+            },
+            "names": {
+              "type": "object",
+              "patternProperties": {
+                "^[A-Z_a-z][0-9A-Z_a-z]*$": {
+                  "type": "string",
+                  "pattern": "^[A-Z_a-z][0-9A-Z_a-z]*$"
+                }
+              }
+            }
+          },
+          "required": [
+            "entry_points"
+          ]
+        }
+      ]
+    }
+  },
+  "required": [
+    "prefix",
+    "type",
+    "location",
+    "capabilities"
+  ]
+}
diff --git a/scripts/data_files/driver_jsons/driver_transparent_schema.json b/scripts/data_files/driver_jsons/driver_transparent_schema.json
new file mode 100644
index 0000000..f5d91eb
--- /dev/null
+++ b/scripts/data_files/driver_jsons/driver_transparent_schema.json
@@ -0,0 +1,70 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "type": "object",
+  "properties": {
+    "_comment": {
+      "type": "string"
+    },
+    "prefix": {
+      "type": "string",
+      "pattern": "^[A-Z_a-z][0-9A-Z_a-z]*$"
+    },
+    "type": {
+      "type": "string",
+      "const": ["transparent"]
+    },
+    "mbedtls/h_condition": {
+      "type": "string"
+    },
+    "headers": {
+      "type": "array",
+      "items": {
+          "type": "string"
+        },
+        "default": []
+    },
+    "capabilities": {
+      "type": "array",
+      "items": [
+        {
+          "type": "object",
+          "properties": {
+            "_comment": {
+              "type": "string"
+            },
+            "mbedtls/c_condition": {
+              "type": "string"
+            },
+            "entry_points": {
+              "type": "array",
+              "items": {
+                  "type": "string"
+                }
+            },
+            "names": {
+              "type": "object",
+              "patternProperties": {
+                "^[A-Z_a-z][0-9A-Z_a-z]*$": {
+                  "type": "string",
+                  "pattern": "^[A-Z_a-z][0-9A-Z_a-z]*$"
+                }
+              }
+            },
+            "fallback": {
+              "type": "boolean",
+              "default": "false"
+            }
+          },
+          "required": [
+            "entry_points"
+          ]
+        }
+      ]
+    }
+  },
+  "required": [
+    "prefix",
+    "type",
+    "capabilities"
+  ]
+}
diff --git a/scripts/data_files/driver_jsons/driverlist.json b/scripts/data_files/driver_jsons/driverlist.json
new file mode 100644
index 0000000..50ad816
--- /dev/null
+++ b/scripts/data_files/driver_jsons/driverlist.json
@@ -0,0 +1 @@
+["mbedtls_test_opaque_driver.json","mbedtls_test_transparent_driver.json"]
diff --git a/scripts/data_files/driver_jsons/mbedtls_test_opaque_driver.json b/scripts/data_files/driver_jsons/mbedtls_test_opaque_driver.json
new file mode 100644
index 0000000..41c74f2
--- /dev/null
+++ b/scripts/data_files/driver_jsons/mbedtls_test_opaque_driver.json
@@ -0,0 +1,20 @@
+{
+    "prefix":       "mbedtls_test",
+    "type":         "opaque",
+    "location":     "0x7fffff",
+    "mbedtls/h_condition":   "defined(PSA_CRYPTO_DRIVER_TEST)",
+    "headers":      ["test/drivers/test_driver.h"],
+    "capabilities": [
+        {
+            "_comment":     "The Mbed TLS opaque driver supports import key/export key/export_public key",
+            "mbedtls/c_condition":    "defined(PSA_CRYPTO_DRIVER_TEST)",
+            "entry_points": ["import_key", "export_key", "export_public_key"]
+        },
+        {
+            "_comment":     "The Mbed TLS opaque driver supports copy key/ get builtin key",
+            "mbedtls/c_condition":    "defined(PSA_CRYPTO_DRIVER_TEST)",
+            "entry_points": ["copy_key", "get_builtin_key"],
+            "names":         {"copy_key":"mbedtls_test_opaque_copy_key", "get_builtin_key":"mbedtls_test_opaque_get_builtin_key"}
+        }
+     ]
+}
diff --git a/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json b/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json
new file mode 100644
index 0000000..9eb259f
--- /dev/null
+++ b/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json
@@ -0,0 +1,22 @@
+{
+    "prefix":       "mbedtls_test",
+    "type":         "transparent",
+    "mbedtls/h_condition":   "defined(PSA_CRYPTO_DRIVER_TEST)",
+    "headers":      ["test/drivers/test_driver.h"],
+    "capabilities": [
+        {
+            "_comment":     "The Mbed TLS transparent driver supports import key/export key",
+            "mbedtls/c_condition":    "defined(PSA_CRYPTO_DRIVER_TEST)",
+            "entry_points": ["import_key", "export_key"],
+            "fallback":     true
+        },
+        {
+            "_comment":     "The Mbed TLS transparent driver supports export_public key",
+            "mbedtls/c_condition":    "defined(PSA_CRYPTO_DRIVER_TEST)",
+            "entry_points": ["export_public_key"],
+            "fallback":     true,
+            "names":         {"export_public_key":"mbedtls_test_transparent_export_public_key"}
+        }
+
+    ]
+}
diff --git a/scripts/data_files/driver_templates/OS-template-opaque.jinja b/scripts/data_files/driver_templates/OS-template-opaque.jinja
new file mode 100644
index 0000000..a25d1c3
--- /dev/null
+++ b/scripts/data_files/driver_templates/OS-template-opaque.jinja
@@ -0,0 +1,17 @@
+{# One Shot function's dispatch code for opaque drivers.
+Expected inputs:
+* drivers: the list of driver descriptions.
+* entry_point: the name of the entry point that this function dispatches to.
+* entry_point_param(driver): the parameters to pass to the entry point.
+* nest_indent: number of extra spaces to indent the code to.
+-#}
+{% for driver in drivers if driver.type == "opaque" -%}
+{% for capability in driver.capabilities if entry_point in capability.entry_points -%}
+#if ({% if capability['mbedtls/c_condition'] is defined -%}{{ capability['mbedtls/c_condition'] }} {% else -%} {{ 1 }} {% endif %})
+{%- filter indent(width = nest_indent) %}
+case {{ driver.location }}:
+    return( {{ entry_point_name(capability, entry_point, driver) }}({{entry_point_param(driver) | indent(20)}}));
+{% endfilter -%}
+#endif
+{% endfor %}
+{% endfor %}
diff --git a/scripts/data_files/driver_templates/OS-template-transparent.jinja b/scripts/data_files/driver_templates/OS-template-transparent.jinja
new file mode 100644
index 0000000..a6b7d69
--- /dev/null
+++ b/scripts/data_files/driver_templates/OS-template-transparent.jinja
@@ -0,0 +1,19 @@
+{# One Shot function's dispatch code for transparent drivers.
+Expected inputs:
+* drivers: the list of driver descriptions.
+* entry_point: the name of the entry point that this function dispatches to.
+* entry_point_param(driver): the parameters to pass to the entry point.
+* nest_indent: number of extra spaces to indent the code to.
+-#}
+{% for driver in drivers if driver.type == "transparent" -%}
+{% for capability in driver.capabilities if entry_point in capability.entry_points -%}
+#if ({% if capability['mbedtls/c_condition'] is defined -%}{{ capability['mbedtls/c_condition'] }} {% else -%} {{ 1 }} {% endif %})
+{%- filter indent(width = nest_indent) %}
+status = {{ entry_point_name(capability, entry_point, driver) }}({{entry_point_param(driver) | indent(20)}});
+
+if( status != PSA_ERROR_NOT_SUPPORTED )
+    return( status );
+{% endfilter -%}
+#endif
+{% endfor %}
+{% endfor %}
diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
index 8ef2e6d..a491b07 100644
--- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja
@@ -1,7 +1,7 @@
 /*
  *  Functions to delegate cryptographic operations to an available
  *  and appropriate accelerator.
- *  Warning: This file will be auto-generated in the future.
+ *  Warning: This file is now auto-generated.
  */
 /*  Copyright The Mbed TLS Contributors
  *  SPDX-License-Identifier: Apache-2.0
@@ -19,6 +19,8 @@
  *  limitations under the License.
  */
 
+
+/* BEGIN-common headers */
 #include "common.h"
 #include "psa_crypto_aead.h"
 #include "psa_crypto_cipher.h"
@@ -29,34 +31,46 @@
 #include "psa_crypto_rsa.h"
 
 #include "mbedtls/platform.h"
+/* END-common headers */
 
 #if defined(MBEDTLS_PSA_CRYPTO_C)
 
+/* BEGIN-driver headers */
 #if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
-
-/* Include test driver definition when running tests */
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-#ifndef PSA_CRYPTO_DRIVER_PRESENT
-#define PSA_CRYPTO_DRIVER_PRESENT
+{% for driver in drivers -%}
+/* Headers for {{driver.prefix}} {{driver.type}} driver */
+{% if driver['mbedtls/h_condition'] is defined -%}
+#if {{ driver['mbedtls/h_condition'] }}
+{% endif -%}
+{% for header in driver.headers -%}
+#include "{{ header }}"
+{% endfor %}
+{% if driver['mbedtls/h_condition'] is defined -%}
 #endif
-#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
-#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
-#endif
-#include "test/drivers/test_driver.h"
-#endif /* PSA_CRYPTO_DRIVER_TEST */
-
-/* Repeat above block for each JSON-declared driver during autogeneration */
+{% endif -%}
+{% endfor %}
 #endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
+/* END-driver headers */
 
 /* Auto-generated values depending on which drivers are registered.
  * ID 0 is reserved for unallocated operations.
  * ID 1 is reserved for the Mbed TLS software driver. */
+/* BEGIN-driver id definition */
 #define PSA_CRYPTO_MBED_TLS_DRIVER_ID (1)
+{% for driver in drivers -%}
+#define {{(driver.prefix + "_" + driver.type + "_driver_id").upper()}} ({{ loop.index + 1 }})
+{% endfor %}
+/* END-driver id */
 
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-#define PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID (2)
-#define PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID (3)
-#endif /* PSA_CRYPTO_DRIVER_TEST */
+/* BEGIN-Common Macro definitions */
+{% macro entry_point_name(capability, entry_point, driver) -%}
+    {% if capability.name is defined and entry_point in capability.names.keys() -%}
+    {{ capability.names[entry_point]}}
+    {% else -%}
+    {{driver.prefix}}_{{driver.type}}_{{entry_point}}
+    {% endif -%}
+{% endmacro %}
+/* END-Common Macro definitions */
 
 /* Support the 'old' SE interface when asked to */
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@@ -592,6 +606,16 @@
     size_t *key_buffer_length,
     size_t *bits )
 {
+{% with entry_point = "import_key" -%}
+{% macro entry_point_param(driver) -%}
+attributes,
+data,
+data_length,
+key_buffer,
+key_buffer_size,
+key_buffer_length,
+bits
+{% endmacro %}
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
                                       psa_get_key_lifetime( attributes ) );
@@ -631,17 +655,11 @@
             /* Key is stored in the slot in export representation, so
              * cycle through all known transparent accelerators */
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = mbedtls_test_transparent_import_key(
-                         attributes,
-                         data, data_length,
-                         key_buffer, key_buffer_size,
-                         key_buffer_length, bits );
-            /* Declared with fallback == true */
-            if( status != PSA_ERROR_NOT_SUPPORTED )
-                return( status );
-#endif /* PSA_CRYPTO_DRIVER_TEST */
+{% with nest_indent=12 %}
+{% include "OS-template-transparent.jinja" -%}
+{% endwith -%}
 #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
             /* Fell through, meaning no accelerator supports this operation */
             return( psa_import_key_into_slot( attributes,
                                               data, data_length,
@@ -649,20 +667,15 @@
                                               key_buffer_length, bits ) );
         /* Add cases for opaque driver here */
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_import_key(
-                         attributes,
-                         data, data_length,
-                         key_buffer, key_buffer_size,
-                         key_buffer_length, bits ) );
-#endif /* PSA_CRYPTO_DRIVER_TEST */
+{% with nest_indent=8 %}
+{% include "OS-template-opaque.jinja" -%}
+{% endwith -%}
 #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
         default:
             (void)status;
             return( PSA_ERROR_INVALID_ARGUMENT );
     }
-
+{% endwith %}
 }
 
 psa_status_t psa_driver_wrapper_export_key(
@@ -671,6 +684,15 @@
     uint8_t *data, size_t data_size, size_t *data_length )
 
 {
+{% with entry_point = "export_key" -%}
+{% macro entry_point_param(driver) -%}
+attributes,
+key_buffer,
+key_buffer_size,
+data,
+data_size,
+data_length
+{% endmacro %}
     psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
     psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
                                       psa_get_key_lifetime( attributes ) );
@@ -707,20 +729,15 @@
 
         /* Add cases for opaque driver here */
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_export_key( attributes,
-                                                    key_buffer,
-                                                    key_buffer_size,
-                                                    data,
-                                                    data_size,
-                                                    data_length ) );
-#endif /* PSA_CRYPTO_DRIVER_TEST */
+{% with nest_indent=8 %}
+{% include "OS-template-opaque.jinja" -%}
+{% endwith -%}
 #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
         default:
             /* Key is declared with a lifetime not known to us */
             return( status );
     }
+{% endwith %}
 }
 
 psa_status_t psa_driver_wrapper_export_public_key(
@@ -729,6 +746,15 @@
     uint8_t *data, size_t data_size, size_t *data_length )
 
 {
+{% with entry_point = "export_public_key" -%}
+{% macro entry_point_param(driver) -%}
+attributes,
+key_buffer,
+key_buffer_size,
+data,
+data_size,
+data_length
+{% endmacro %}
     psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
     psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
                                       psa_get_key_lifetime( attributes ) );
@@ -759,18 +785,9 @@
             /* Key is stored in the slot in export representation, so
              * cycle through all known transparent accelerators */
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = mbedtls_test_transparent_export_public_key(
-                         attributes,
-                         key_buffer,
-                         key_buffer_size,
-                         data,
-                         data_size,
-                         data_length );
-            /* Declared with fallback == true */
-            if( status != PSA_ERROR_NOT_SUPPORTED )
-                return( status );
-#endif /* PSA_CRYPTO_DRIVER_TEST */
+{% with nest_indent=12 %}
+{% include "OS-template-transparent.jinja" -%}
+{% endwith -%}
 #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
             /* Fell through, meaning no accelerator supports this operation */
             return( psa_export_public_key_internal( attributes,
@@ -782,20 +799,15 @@
 
         /* Add cases for opaque driver here */
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_export_public_key( attributes,
-                                                           key_buffer,
-                                                           key_buffer_size,
-                                                           data,
-                                                           data_size,
-                                                           data_length ) );
-#endif /* PSA_CRYPTO_DRIVER_TEST */
+{% with nest_indent=8 %}
+{% include "OS-template-opaque.jinja" -%}
+{% endwith -%}
 #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
         default:
             /* Key is declared with a lifetime not known to us */
             return( status );
     }
+{% endwith %}
 }
 
 psa_status_t psa_driver_wrapper_get_builtin_key(
@@ -803,15 +815,21 @@
     psa_key_attributes_t *attributes,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
 {
+{% with entry_point = "get_builtin_key" -%}
+{% macro entry_point_param(driver) -%}
+slot_number,
+attributes,
+key_buffer,
+key_buffer_size,
+key_buffer_length
+{% endmacro %}
     psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
     switch( location )
     {
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_get_builtin_key(
-                        slot_number,
-                        attributes,
-                        key_buffer, key_buffer_size, key_buffer_length ) );
+{% with nest_indent=8 %}
+{% include "OS-template-opaque.jinja" -%}
+{% endwith -%}
 #endif /* PSA_CRYPTO_DRIVER_TEST */
         default:
             (void) slot_number;
@@ -820,6 +838,7 @@
             (void) key_buffer_length;
             return( PSA_ERROR_DOES_NOT_EXIST );
     }
+{% endwith %}
 }
 
 psa_status_t psa_driver_wrapper_copy_key(
@@ -828,6 +847,15 @@
     uint8_t *target_key_buffer, size_t target_key_buffer_size,
     size_t *target_key_buffer_length )
 {
+{% with entry_point = "copy_key" -%}
+{% macro entry_point_param(driver) -%}
+attributes,
+source_key,
+source_key_length,
+target_key_buffer,
+target_key_buffer_size,
+target_key_buffer_length
+{% endmacro %}
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_key_location_t location =
         PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
@@ -846,14 +874,9 @@
     switch( location )
     {
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-#if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_copy_key( attributes, source_key,
-                                                  source_key_length,
-                                                  target_key_buffer,
-                                                  target_key_buffer_size,
-                                                  target_key_buffer_length) );
-#endif /* PSA_CRYPTO_DRIVER_TEST */
+{% with nest_indent=8 %}
+{% include "OS-template-opaque.jinja" -%}
+{% endwith -%}
 #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
         default:
             (void)source_key;
@@ -864,6 +887,7 @@
             status = PSA_ERROR_INVALID_ARGUMENT;
     }
     return( status );
+{% endwith %}
 }
 
 /*
@@ -1068,7 +1092,7 @@
                 alg );
             /* Declared with fallback == true */
             if( status == PSA_SUCCESS )
-                operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+                operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
 
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
@@ -1100,7 +1124,7 @@
                 alg );
 
             if( status == PSA_SUCCESS )
-                operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID;
+                operation->id = MBEDTLS_TEST_OPAQUE_DRIVER_ID;
 
             return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
@@ -1141,7 +1165,7 @@
                 alg );
             /* Declared with fallback == true */
             if( status == PSA_SUCCESS )
-                operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+                operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
 
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
@@ -1172,7 +1196,7 @@
                          alg );
 
             if( status == PSA_SUCCESS )
-                operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID;
+                operation->id = MBEDTLS_TEST_OPAQUE_DRIVER_ID;
 
             return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
@@ -1204,12 +1228,12 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_cipher_set_iv(
                         &operation->ctx.transparent_test_driver_ctx,
                         iv, iv_length ) );
 
-        case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_OPAQUE_DRIVER_ID:
             return( mbedtls_test_opaque_cipher_set_iv(
                         &operation->ctx.opaque_test_driver_ctx,
                         iv, iv_length ) );
@@ -1245,13 +1269,13 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_cipher_update(
                         &operation->ctx.transparent_test_driver_ctx,
                         input, input_length,
                         output, output_size, output_length ) );
 
-        case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_OPAQUE_DRIVER_ID:
             return( mbedtls_test_opaque_cipher_update(
                         &operation->ctx.opaque_test_driver_ctx,
                         input, input_length,
@@ -1287,12 +1311,12 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_cipher_finish(
                         &operation->ctx.transparent_test_driver_ctx,
                         output, output_size, output_length ) );
 
-        case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_OPAQUE_DRIVER_ID:
             return( mbedtls_test_opaque_cipher_finish(
                         &operation->ctx.opaque_test_driver_ctx,
                         output, output_size, output_length ) );
@@ -1321,7 +1345,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             status = mbedtls_test_transparent_cipher_abort(
                          &operation->ctx.transparent_test_driver_ctx );
             mbedtls_platform_zeroize(
@@ -1329,7 +1353,7 @@
                 sizeof( operation->ctx.transparent_test_driver_ctx ) );
             return( status );
 
-        case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_OPAQUE_DRIVER_ID:
             status = mbedtls_test_opaque_cipher_abort(
                          &operation->ctx.opaque_test_driver_ctx );
             mbedtls_platform_zeroize(
@@ -1394,7 +1418,7 @@
     status = mbedtls_test_transparent_hash_setup(
                 &operation->ctx.test_driver_ctx, alg );
     if( status == PSA_SUCCESS )
-        operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+        operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
 
     if( status != PSA_ERROR_NOT_SUPPORTED )
         return( status );
@@ -1429,8 +1453,8 @@
                                             &target_operation->ctx.mbedtls_ctx ) );
 #endif
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
-            target_operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
+            target_operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
             return( mbedtls_test_transparent_hash_clone(
                         &source_operation->ctx.test_driver_ctx,
                         &target_operation->ctx.test_driver_ctx ) );
@@ -1454,7 +1478,7 @@
                                              input, input_length ) );
 #endif
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_hash_update(
                         &operation->ctx.test_driver_ctx,
                         input, input_length ) );
@@ -1480,7 +1504,7 @@
                                              hash, hash_size, hash_length ) );
 #endif
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_hash_finish(
                         &operation->ctx.test_driver_ctx,
                         hash, hash_size, hash_length ) );
@@ -1503,7 +1527,7 @@
             return( mbedtls_psa_hash_abort( &operation->ctx.mbedtls_ctx ) );
 #endif
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_hash_abort(
                         &operation->ctx.test_driver_ctx ) );
 #endif
@@ -1634,7 +1658,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+            operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
             status = mbedtls_test_transparent_aead_encrypt_setup(
                         &operation->ctx.transparent_test_driver_ctx,
                         attributes, key_buffer, key_buffer_size,
@@ -1682,7 +1706,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+            operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
             status = mbedtls_test_transparent_aead_decrypt_setup(
                         &operation->ctx.transparent_test_driver_ctx,
                         attributes,
@@ -1731,7 +1755,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_aead_set_nonce(
                          &operation->ctx.transparent_test_driver_ctx,
                          nonce, nonce_length ) );
@@ -1765,7 +1789,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_aead_set_lengths(
                         &operation->ctx.transparent_test_driver_ctx,
                         ad_length, plaintext_length ) );
@@ -1799,7 +1823,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_aead_update_ad(
                         &operation->ctx.transparent_test_driver_ctx,
                         input, input_length ) );
@@ -1837,7 +1861,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_aead_update(
                         &operation->ctx.transparent_test_driver_ctx,
                         input, input_length, output, output_size,
@@ -1881,7 +1905,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_aead_finish(
                         &operation->ctx.transparent_test_driver_ctx,
                         ciphertext, ciphertext_size,
@@ -1945,7 +1969,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_aead_verify(
                         &operation->ctx.transparent_test_driver_ctx,
                         plaintext, plaintext_size,
@@ -1979,7 +2003,7 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_aead_abort(
                &operation->ctx.transparent_test_driver_ctx ) );
 
@@ -2088,7 +2112,7 @@
                 alg );
             /* Declared with fallback == true */
             if( status == PSA_SUCCESS )
-                operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+                operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
 
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
@@ -2119,7 +2143,7 @@
                 alg );
 
             if( status == PSA_SUCCESS )
-                operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID;
+                operation->id = MBEDTLS_TEST_OPAQUE_DRIVER_ID;
 
             return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
@@ -2160,7 +2184,7 @@
                 alg );
             /* Declared with fallback == true */
             if( status == PSA_SUCCESS )
-                operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID;
+                operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID;
 
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
@@ -2191,7 +2215,7 @@
                 alg );
 
             if( status == PSA_SUCCESS )
-                operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID;
+                operation->id = MBEDTLS_TEST_OPAQUE_DRIVER_ID;
 
             return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
@@ -2222,12 +2246,12 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_mac_update(
                         &operation->ctx.transparent_test_driver_ctx,
                         input, input_length ) );
 
-        case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_OPAQUE_DRIVER_ID:
             return( mbedtls_test_opaque_mac_update(
                         &operation->ctx.opaque_test_driver_ctx,
                         input, input_length ) );
@@ -2256,12 +2280,12 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_mac_sign_finish(
                         &operation->ctx.transparent_test_driver_ctx,
                         mac, mac_size, mac_length ) );
 
-        case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_OPAQUE_DRIVER_ID:
             return( mbedtls_test_opaque_mac_sign_finish(
                         &operation->ctx.opaque_test_driver_ctx,
                         mac, mac_size, mac_length ) );
@@ -2290,12 +2314,12 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_mac_verify_finish(
                         &operation->ctx.transparent_test_driver_ctx,
                         mac, mac_length ) );
 
-        case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_OPAQUE_DRIVER_ID:
             return( mbedtls_test_opaque_mac_verify_finish(
                         &operation->ctx.opaque_test_driver_ctx,
                         mac, mac_length ) );
@@ -2320,10 +2344,10 @@
 
 #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-        case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID:
             return( mbedtls_test_transparent_mac_abort(
                         &operation->ctx.transparent_test_driver_ctx ) );
-        case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID:
+        case MBEDTLS_TEST_OPAQUE_DRIVER_ID:
             return( mbedtls_test_opaque_mac_abort(
                         &operation->ctx.opaque_test_driver_ctx ) );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
diff --git a/scripts/driver.requirements.txt b/scripts/driver.requirements.txt
index 5364d8e..9e26b3c 100644
--- a/scripts/driver.requirements.txt
+++ b/scripts/driver.requirements.txt
@@ -15,4 +15,5 @@
 Jinja2 >= 2.10.3; python_version >= '3.10'
 # Jinja2 >=2.10, <3.0 needs a separate package for type annotations
 types-Jinja2
-
+jsonschema >= 3.2.0
+types-jsonschema
diff --git a/scripts/generate_driver_wrappers.py b/scripts/generate_driver_wrappers.py
index 71b881e..e0c4793 100755
--- a/scripts/generate_driver_wrappers.py
+++ b/scripts/generate_driver_wrappers.py
@@ -22,54 +22,194 @@
 
 import sys
 import os
+import json
+from typing import NewType, Dict, Any
+from traceback import format_tb
 import argparse
+import jsonschema
 import jinja2
 from mbedtls_dev import build_tree
 
-def render(template_path: str) -> str:
+JSONSchema = NewType('JSONSchema', object)
+# The Driver is an Object, but practically it's indexable and can called a dictionary to
+# keep MyPy happy till MyPy comes with a more composite type for JsonObjects.
+Driver = NewType('Driver', dict)
+
+
+class JsonValidationException(Exception):
+    def __init__(self, message="Json Validation Failed"):
+        self.message = message
+        super().__init__(self.message)
+
+
+class DriverReaderException(Exception):
+    def __init__(self, message="Driver Reader Failed"):
+        self.message = message
+        super().__init__(self.message)
+
+
+def render(template_path: str, driver_jsoncontext: list) -> str:
     """
-    Render template from the input file.
+    Render template from the input file and driver JSON.
     """
     environment = jinja2.Environment(
         loader=jinja2.FileSystemLoader(os.path.dirname(template_path)),
         keep_trailing_newline=True)
     template = environment.get_template(os.path.basename(template_path))
 
-    return template.render()
+    return template.render(drivers=driver_jsoncontext)
 
-def generate_driver_wrapper_file(mbedtls_root: str, output_dir: str) -> None:
+
+def generate_driver_wrapper_file(template_dir: str,
+                                 output_dir: str,
+                                 driver_jsoncontext: list) -> None:
     """
     Generate the file psa_crypto_driver_wrapper.c.
     """
     driver_wrapper_template_filename = \
-        os.path.join(mbedtls_root, \
-        "scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja")
+        os.path.join(template_dir, "psa_crypto_driver_wrappers.c.jinja")
 
-    result = render(driver_wrapper_template_filename)
+    result = render(driver_wrapper_template_filename, driver_jsoncontext)
 
-    with open(os.path.join(output_dir, "psa_crypto_driver_wrappers.c"), 'w') as out_file:
+    with open(file=os.path.join(output_dir, "psa_crypto_driver_wrappers.c"),
+              mode='w',
+              encoding='UTF-8') as out_file:
         out_file.write(result)
 
+
+def validate_json(driverjson_data: Driver, driverschema_list: dict) -> None:
+    """
+    Validate the Driver JSON against an appropriate schema
+    the schema passed could be that matching an opaque/ transparent driver.
+    """
+    driver_type = driverjson_data["type"]
+    driver_prefix = driverjson_data["prefix"]
+    try:
+        _schema = driverschema_list[driver_type]
+        jsonschema.validate(instance=driverjson_data, schema=_schema)
+    except KeyError as err:
+        # This could happen if the driverjson_data.type does not exist in the provided schema list
+        # schemas = {'transparent': transparent_driver_schema, 'opaque': opaque_driver_schema}
+        # Print onto stdout and stderr.
+        print("Unknown Driver type " + driver_type +
+              " for driver " + driver_prefix, str(err))
+        print("Unknown Driver type " + driver_type +
+              " for driver " + driver_prefix, str(err), file=sys.stderr)
+        raise JsonValidationException() from err
+
+    except jsonschema.exceptions.ValidationError as err:
+        # Print onto stdout and stderr.
+        print("Error: Failed to validate data file: {} using schema: {}."
+              "\n Exception Message: \"{}\""
+              " ".format(driverjson_data, _schema, str(err)))
+        print("Error: Failed to validate data file: {} using schema: {}."
+              "\n Exception Message: \"{}\""
+              " ".format(driverjson_data, _schema, str(err)), file=sys.stderr)
+        raise JsonValidationException() from err
+
+
+def load_driver(schemas: Dict[str, Any], driver_file: str) -> Any:
+    """loads validated json driver"""
+    with open(file=driver_file, mode='r', encoding='UTF-8') as f:
+        json_data = json.load(f)
+        try:
+            validate_json(json_data, schemas)
+        except JsonValidationException as e:
+            raise DriverReaderException from e
+        return json_data
+
+
+def load_schemas(mbedtls_root: str) -> Dict[str, Any]:
+    """
+    Load schemas map
+    """
+    schema_file_paths = {
+        'transparent': os.path.join(mbedtls_root,
+                                    'scripts',
+                                    'data_files',
+                                    'driver_jsons',
+                                    'driver_transparent_schema.json'),
+        'opaque': os.path.join(mbedtls_root,
+                               'scripts',
+                               'data_files',
+                               'driver_jsons',
+                               'driver_opaque_schema.json')
+    }
+    driver_schema = {}
+    for key, file_path in schema_file_paths.items():
+        with open(file=file_path, mode='r', encoding='UTF-8') as file:
+            driver_schema[key] = json.load(file)
+    return driver_schema
+
+
+def read_driver_descriptions(mbedtls_root: str,
+                             json_directory: str,
+                             jsondriver_list: str) -> list:
+    """
+    Merge driver JSON files into a single ordered JSON after validation.
+    """
+    driver_schema = load_schemas(mbedtls_root)
+
+    with open(file=os.path.join(json_directory, jsondriver_list),
+              mode='r',
+              encoding='UTF-8') as driver_list_file:
+        driver_list = json.load(driver_list_file)
+
+    return [load_driver(schemas=driver_schema,
+                        driver_file=os.path.join(json_directory, driver_file_name))
+            for driver_file_name in driver_list]
+
+
+def trace_exception(e: Exception, file=sys.stderr) -> None:
+    """Prints exception trace to the given TextIO handle"""
+    print("Exception: type: %s, message: %s, trace: %s" % (
+        e.__class__, str(e), format_tb(e.__traceback__)
+    ), file)
+
+
 def main() -> int:
     """
     Main with command line arguments.
     """
     def_arg_mbedtls_root = build_tree.guess_mbedtls_root()
-    def_arg_output_dir = os.path.join(def_arg_mbedtls_root, 'library')
 
     parser = argparse.ArgumentParser()
-    parser.add_argument('--mbedtls-root', nargs='?', default=def_arg_mbedtls_root,
+    parser.add_argument('--mbedtls-root', default=def_arg_mbedtls_root,
                         help='root directory of mbedtls source code')
+    parser.add_argument('--template-dir',
+                        help='directory holding the driver templates')
+    parser.add_argument('--json-dir',
+                        help='directory holding the driver JSONs')
     parser.add_argument('output_directory', nargs='?',
-                        default=def_arg_output_dir, help='output file\'s location')
+                        help='output file\'s location')
     args = parser.parse_args()
 
     mbedtls_root = os.path.abspath(args.mbedtls_root)
-    output_directory = args.output_directory
 
-    generate_driver_wrapper_file(mbedtls_root, output_directory)
+    output_directory = args.output_directory if args.output_directory is not None else \
+        os.path.join(mbedtls_root, 'library')
+    template_directory = args.template_dir if args.template_dir is not None else \
+        os.path.join(mbedtls_root,
+                     'scripts',
+                     'data_files',
+                     'driver_templates')
+    json_directory = args.json_dir if args.json_dir is not None else \
+        os.path.join(mbedtls_root,
+                     'scripts',
+                     'data_files',
+                     'driver_jsons')
 
+    try:
+        # Read and validate list of driver jsons from driverlist.json
+        merged_driver_json = read_driver_descriptions(mbedtls_root,
+                                                      json_directory,
+                                                      'driverlist.json')
+    except DriverReaderException as e:
+        trace_exception(e)
+        return 1
+    generate_driver_wrapper_file(template_directory, output_directory, merged_driver_json)
     return 0
 
+
 if __name__ == '__main__':
     sys.exit(main())
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 6187d17..09a0689 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -276,6 +276,9 @@
 server5-othername.crt: server5.key
 	$(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions othername_san -days 3650 -sha256 -key $< -out $@
 
+server5-nonprintable_othername.crt: server5.key
+	$(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS non-printable othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions nonprintable_othername_san -days 3650 -sha256 -key $< -out $@
+
 server5-unsupported_othername.crt: server5.key
 	$(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS unsupported othername SAN" -set_serial 77 -config $(test_ca_config_file) -extensions unsupoported_othername_san -days 3650 -sha256 -key $< -out $@
 
diff --git a/tests/data_files/server5-nonprintable_othername.crt b/tests/data_files/server5-nonprintable_othername.crt
new file mode 100644
index 0000000..9470bbe
--- /dev/null
+++ b/tests/data_files/server5-nonprintable_othername.crt
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBwTCCAWagAwIBAgIBTTAKBggqhkjOPQQDAjBPMQswCQYDVQQGEwJVSzERMA8G
+A1UECgwITWJlZCBUTFMxLTArBgNVBAMMJE1iZWQgVExTIG5vbi1wcmludGFibGUg
+b3RoZXJuYW1lIFNBTjAeFw0yMjA5MDYxNTU2NDdaFw0zMjA5MDMxNTU2NDdaME8x
+CzAJBgNVBAYTAlVLMREwDwYDVQQKDAhNYmVkIFRMUzEtMCsGA1UEAwwkTWJlZCBU
+TFMgbm9uLXByaW50YWJsZSBvdGhlcm5hbWUgU0FOMFkwEwYHKoZIzj0CAQYIKoZI
+zj0DAQcDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/
+6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/6MzMDEwLwYDVR0RBCgwJqAkBggrBgEF
+BQcIBKAYMBYGBysGAQQBEQMECzEyM4CBAIGAMzIxMAoGCCqGSM49BAMCA0kAMEYC
+IQDATir07PTj5gtf+HAyI+nd27AH9+bdaWdOI2t2bAwUWgIhAO7kvdcsa++yfJdT
+3vnWdvcHRIAdXA0kh+mcBMaXk9B0
+-----END CERTIFICATE-----
diff --git a/tests/data_files/test-ca.opensslconf b/tests/data_files/test-ca.opensslconf
index 64347de..3bb2379 100644
--- a/tests/data_files/test-ca.opensslconf
+++ b/tests/data_files/test-ca.opensslconf
@@ -15,6 +15,9 @@
 [othername_san]
 subjectAltName=otherName:1.3.6.1.5.5.7.8.4;SEQ:hw_module_name
 
+[nonprintable_othername_san]
+subjectAltName=otherName:1.3.6.1.5.5.7.8.4;SEQ:nonprintable_hw_module_name
+
 [unsupoported_othername_san]
 subjectAltName=otherName:1.2.3.4;UTF8:some other identifier
 
@@ -34,6 +37,10 @@
 hwtype = OID:1.3.6.1.4.1.17.3
 hwserial = OCT:123456
 
+[nonprintable_hw_module_name]
+hwtype = OID:1.3.6.1.4.1.17.3
+hwserial = FORMAT:HEX, OCT:3132338081008180333231
+
 [v3_any_policy_ca]
 basicConstraints = CA:true
 certificatePolicies = 2.5.29.32.0
diff --git a/tests/include/test/drivers/test_driver.h b/tests/include/test/drivers/test_driver.h
index 098b21a..b3c29e4 100644
--- a/tests/include/test/drivers/test_driver.h
+++ b/tests/include/test/drivers/test_driver.h
@@ -20,6 +20,14 @@
 #ifndef PSA_CRYPTO_TEST_DRIVER_H
 #define PSA_CRYPTO_TEST_DRIVER_H
 
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+#ifndef PSA_CRYPTO_DRIVER_PRESENT
+#define PSA_CRYPTO_DRIVER_PRESENT
+#endif
+#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
+#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
+#endif
+
 #define PSA_CRYPTO_TEST_DRIVER_LOCATION 0x7fffff
 
 #include "test/drivers/aead.h"
@@ -30,4 +38,5 @@
 #include "test/drivers/signature.h"
 #include "test/drivers/asymmetric_encryption.h"
 
+#endif /* PSA_CRYPTO_DRIVER_TEST */
 #endif /* PSA_CRYPTO_TEST_DRIVER_H */
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
index aece1ef..396ab74 100755
--- a/tests/scripts/check_names.py
+++ b/tests/scripts/check_names.py
@@ -278,7 +278,7 @@
             "library/*.c",
             "3rdparty/everest/library/everest.c",
             "3rdparty/everest/library/x25519.c"
-        ])
+        ], ["library/psa_crypto_driver_wrappers.c"])
         symbols = self.parse_symbols()
 
         # Remove identifier macros like mbedtls_printf or mbedtls_calloc
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index b7c8364..cc23fd7 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -357,8 +357,12 @@
     size_t hex_len = strlen( input );
     size_t byte_len = ( hex_len + 1 ) / 2;
     *plimbs = CHARS_TO_LIMBS( byte_len );
+
+    /* A core bignum is not allowed to be empty. Forbid it as test data,
+     * this way static analyzers have a chance of knowing we don't expect
+     * the bignum functions to support empty inputs. */
     if( *plimbs == 0 )
-        return( 0 );
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
     *pX = mbedtls_calloc( *plimbs, sizeof( **pX ) );
     if( *pX == NULL )
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index a75b3f5..fc892a1 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -13018,7 +13018,7 @@
 run_test    "TLS 1.3: NewSessionTicket: servername negative check, m->m" \
             "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4 \
             sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
-            "$P_CLI debug_level=4 server_name=localhost rec_server_name=remote reco_mode=1 reconnect=1" \
+            "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \
             1 \
             -c "Protocol is TLSv1.3" \
             -c "got new session ticket." \
diff --git a/tests/suites/test_suite_asn1parse.data b/tests/suites/test_suite_asn1parse.data
index 36ab1e4..c129e3c 100644
--- a/tests/suites/test_suite_asn1parse.data
+++ b/tests/suites/test_suite_asn1parse.data
@@ -608,18 +608,23 @@
 find_named_data:"414141":"414141":"434343":"444444":"414141":0:0
 
 Free named data: null pointer
+depends_on:MBEDTLS_TEST_DEPRECATED
 free_named_data_null:
 
 Free named data: all null
+depends_on:MBEDTLS_TEST_DEPRECATED
 free_named_data:0:0:0
 
 Free named data: with oid
+depends_on:MBEDTLS_TEST_DEPRECATED
 free_named_data:1:0:0
 
 Free named data: with val
+depends_on:MBEDTLS_TEST_DEPRECATED
 free_named_data:0:1:0
 
 Free named data: with next
+depends_on:MBEDTLS_TEST_DEPRECATED
 free_named_data:0:0:1
 
 Free named data list (empty)
diff --git a/tests/suites/test_suite_asn1parse.function b/tests/suites/test_suite_asn1parse.function
index 002d8c4..62669b3 100644
--- a/tests/suites/test_suite_asn1parse.function
+++ b/tests/suites/test_suite_asn1parse.function
@@ -735,7 +735,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:!MBEDTLS_DEPRECATED_REMOVED:!MBEDTLS_DEPRECATED_WARNING */
 void free_named_data_null( )
 {
     mbedtls_asn1_free_named_data( NULL );
@@ -743,7 +743,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:!MBEDTLS_DEPRECATED_REMOVED:!MBEDTLS_DEPRECATED_WARNING */
 void free_named_data( int with_oid, int with_val, int with_next )
 {
     mbedtls_asn1_named_data next =
diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function
index f50fd07..612a7c6 100644
--- a/tests/suites/test_suite_bignum_core.function
+++ b/tests/suites/test_suite_bignum_core.function
@@ -345,14 +345,18 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mpi_core_cond_assign( data_t * input_X,
-                           data_t * input_Y,
+void mpi_core_cond_assign( char * input_X,
+                           char * input_Y,
                            int input_bytes )
 {
     mbedtls_mpi_uint *X = NULL;
     mbedtls_mpi_uint *Y = NULL;
-    size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
-    size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
+    size_t limbs_X;
+    size_t limbs_Y;
+
+    TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs_X, input_X ), 0 );
+    TEST_EQUAL( mbedtls_test_read_mpi_core( &Y, &limbs_Y, input_Y ), 0 );
+
     size_t limbs = limbs_X;
     size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
     size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
@@ -361,15 +365,6 @@
     TEST_EQUAL( limbs_X, limbs_Y );
     TEST_ASSERT( copy_limbs <= limbs );
 
-    ASSERT_ALLOC( X, limbs );
-    ASSERT_ALLOC( Y, limbs );
-
-    TEST_ASSERT( mbedtls_mpi_core_read_be( X, limbs, input_X->x, input_X->len )
-                 == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_core_read_be( Y, limbs, input_Y->x, input_Y->len )
-                 == 0 );
-
     /* condition is false */
     TEST_CF_SECRET( X, bytes );
     TEST_CF_SECRET( Y, bytes );
@@ -394,6 +389,9 @@
        than the length of the given MPIs. */
     if( copy_limbs < limbs )
     {
+        TEST_CF_PUBLIC( X, bytes );
+        TEST_CF_PUBLIC( Y, bytes );
+
         ASSERT_COMPARE( X, copy_bytes, Y, copy_bytes );
         TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
     }
@@ -407,16 +405,20 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mpi_core_cond_swap( data_t * input_X,
-                         data_t * input_Y,
+void mpi_core_cond_swap( char * input_X,
+                         char * input_Y,
                          int input_bytes )
 {
     mbedtls_mpi_uint *tmp_X = NULL;
     mbedtls_mpi_uint *tmp_Y = NULL;
     mbedtls_mpi_uint *X = NULL;
     mbedtls_mpi_uint *Y = NULL;
-    size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
-    size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
+    size_t limbs_X;
+    size_t limbs_Y;
+
+    TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_X, &limbs_X, input_X ), 0 );
+    TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_Y, &limbs_Y, input_Y ), 0 );
+
     size_t limbs = limbs_X;
     size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
     size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
@@ -425,18 +427,9 @@
     TEST_EQUAL( limbs_X, limbs_Y );
     TEST_ASSERT( copy_limbs <= limbs );
 
-    ASSERT_ALLOC( tmp_X, limbs );
-    ASSERT_ALLOC( tmp_Y, limbs );
-
-    TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_X, limbs,
-                                           input_X->x, input_X->len )
-                 == 0 );
     ASSERT_ALLOC( X, limbs );
     memcpy( X, tmp_X, bytes );
 
-    TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_Y, limbs,
-                                           input_Y->x, input_Y->len )
-                 == 0 );
     ASSERT_ALLOC( Y, limbs );
     memcpy( Y, tmp_Y, bytes );
 
diff --git a/tests/suites/test_suite_bignum_core.misc.data b/tests/suites/test_suite_bignum_core.misc.data
index 30c767c..62480e4 100644
--- a/tests/suites/test_suite_bignum_core.misc.data
+++ b/tests/suites/test_suite_bignum_core.misc.data
@@ -167,9 +167,6 @@
 mbedtls_mpi_core_lt_ct: x<y (1 limb)
 mpi_core_lt_ct:"2B5":"2B6":1
 
-mbedtls_mpi_core_lt_ct: x=y (0 limbs)
-mpi_core_lt_ct:"":"":0
-
 mbedtls_mpi_core_lt_ct: x>y (63 bit x, y first byte greater)
 mpi_core_lt_ct:"7FFFFFFFFFFFFFFF":"00000000000000FF":0
 
diff --git a/tests/suites/test_suite_bignum_mod_raw.function b/tests/suites/test_suite_bignum_mod_raw.function
index 8ac1ef4..4b90675 100644
--- a/tests/suites/test_suite_bignum_mod_raw.function
+++ b/tests/suites/test_suite_bignum_mod_raw.function
@@ -110,16 +110,20 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mpi_mod_raw_cond_assign( data_t * input_X,
-                              data_t * input_Y,
+void mpi_mod_raw_cond_assign( char * input_X,
+                              char * input_Y,
                               int input_bytes )
 {
     mbedtls_mpi_uint *X = NULL;
     mbedtls_mpi_uint *Y = NULL;
     mbedtls_mpi_uint *buff_m = NULL;
     mbedtls_mpi_mod_modulus m;
-    size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
-    size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
+    size_t limbs_X;
+    size_t limbs_Y;
+
+    TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs_X, input_X ), 0 );
+    TEST_EQUAL( mbedtls_test_read_mpi_core( &Y, &limbs_Y, input_Y ), 0 );
+
     size_t limbs = limbs_X;
     size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
     size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
@@ -130,24 +134,12 @@
     TEST_EQUAL( limbs_X, limbs_Y );
     TEST_ASSERT( copy_limbs <= limbs );
 
-    ASSERT_ALLOC( X, limbs );
-    ASSERT_ALLOC( Y, limbs );
-
-    ASSERT_ALLOC( buff_m, limbs );
-    memset( buff_m, 0xFF, copy_bytes );
-    TEST_ASSERT( mbedtls_mpi_mod_modulus_setup(
+    ASSERT_ALLOC( buff_m, copy_limbs );
+    memset( buff_m, 0xFF, copy_limbs );
+    TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
                         &m, buff_m, copy_limbs,
                         MBEDTLS_MPI_MOD_EXT_REP_BE,
-                        MBEDTLS_MPI_MOD_REP_MONTGOMERY )
-                 == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_core_read_be( X, limbs,
-                                           input_X->x, input_X->len )
-                 == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_core_read_be( Y, limbs,
-                                           input_Y->x, input_Y->len )
-                 == 0 );
+                        MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
 
     /* condition is false */
     TEST_CF_SECRET( X, bytes );
@@ -189,8 +181,8 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mpi_mod_raw_cond_swap( data_t * input_X,
-                            data_t * input_Y,
+void mpi_mod_raw_cond_swap( char * input_X,
+                            char * input_Y,
                             int input_bytes )
 {
     mbedtls_mpi_uint *tmp_X = NULL;
@@ -199,8 +191,12 @@
     mbedtls_mpi_uint *Y = NULL;
     mbedtls_mpi_uint *buff_m = NULL;
     mbedtls_mpi_mod_modulus m;
-    size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
-    size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
+    size_t limbs_X;
+    size_t limbs_Y;
+
+    TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_X, &limbs_X, input_X ), 0 );
+    TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_Y, &limbs_Y, input_Y ), 0 );
+
     size_t limbs = limbs_X;
     size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
     size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
@@ -211,24 +207,16 @@
     TEST_EQUAL( limbs_X, limbs_Y );
     TEST_ASSERT( copy_limbs <= limbs );
 
-    ASSERT_ALLOC( tmp_X, limbs );
-    ASSERT_ALLOC( tmp_Y, limbs );
-
     ASSERT_ALLOC( buff_m, copy_limbs );
-    memset( buff_m, 0xFF, copy_bytes );
-    TEST_ASSERT( mbedtls_mpi_mod_modulus_setup(
+    memset( buff_m, 0xFF, copy_limbs );
+    TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
                         &m, buff_m, copy_limbs,
                         MBEDTLS_MPI_MOD_EXT_REP_BE,
-                        MBEDTLS_MPI_MOD_REP_MONTGOMERY )
-                 == 0 );
+                        MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
 
-    TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_X, limbs, input_X->x, input_X->len )
-                 == 0 );
     ASSERT_ALLOC( X, limbs );
     memcpy( X, tmp_X, bytes );
 
-    TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_Y, limbs, input_Y->x, input_Y->len )
-                 == 0 );
     ASSERT_ALLOC( Y, bytes );
     memcpy( Y, tmp_Y, bytes );
 
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 4448bc4..cce3fd0 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -6594,3 +6594,7 @@
 PSA PAKE: ecjpake inject input errors, second round server, client input first
 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
 ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:4:"abcdef"
+
+PSA PAKE: ecjpake size macros
+depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+ecjpake_size_macros:
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 6c95c2a..779f594 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -718,6 +718,15 @@
         PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_KEY_SHARE) +
         PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PUBLIC) +
         PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PROOF)) * 2;
+    /* The output should be exactly this size according to the spec */
+    const size_t expected_size_key_share =
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_KEY_SHARE);
+    /* The output should be exactly this size according to the spec */
+    const size_t expected_size_zk_public =
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PUBLIC);
+    /* The output can be smaller: the spec allows stripping leading zeroes */
+    const size_t max_expected_size_zk_proof =
+        PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PROOF);
     size_t buffer0_off = 0;
     size_t buffer1_off = 0;
     size_t s_g1_len, s_g2_len, s_a_len;
@@ -745,38 +754,44 @@
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_KEY_SHARE,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_g1_len ) );
+            TEST_EQUAL( s_g1_len, expected_size_key_share );
             s_g1_off = buffer0_off;
             buffer0_off += s_g1_len;
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PUBLIC,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_x1_pk_len ) );
+            TEST_EQUAL( s_x1_pk_len, expected_size_zk_public );
             s_x1_pk_off = buffer0_off;
             buffer0_off += s_x1_pk_len;
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PROOF,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_x1_pr_len ) );
+            TEST_LE_U( s_x1_pr_len, max_expected_size_zk_proof );
             s_x1_pr_off = buffer0_off;
             buffer0_off += s_x1_pr_len;
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_KEY_SHARE,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_g2_len ) );
+            TEST_EQUAL( s_g2_len, expected_size_key_share );
             s_g2_off = buffer0_off;
             buffer0_off += s_g2_len;
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PUBLIC,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_x2_pk_len ) );
+            TEST_EQUAL( s_x2_pk_len, expected_size_zk_public );
             s_x2_pk_off = buffer0_off;
             buffer0_off += s_x2_pk_len;
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PROOF,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_x2_pr_len ) );
+            TEST_LE_U( s_x2_pr_len, max_expected_size_zk_proof );
             s_x2_pr_off = buffer0_off;
             buffer0_off += s_x2_pr_len;
 
             if( inject_error == 1 )
             {
-                buffer0[s_x1_pk_off + 8] >>= 4;
-                buffer0[s_x2_pk_off + 7] <<= 4;
+                buffer0[s_x1_pr_off + 8] ^= 1;
+                buffer0[s_x2_pr_off + 7] ^= 1;
                 expected_status = PSA_ERROR_DATA_INVALID;
             }
 
@@ -877,31 +892,37 @@
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_KEY_SHARE,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_g1_len ) );
+            TEST_EQUAL( c_g1_len, expected_size_key_share );
             c_g1_off = buffer1_off;
             buffer1_off += c_g1_len;
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PUBLIC,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_x1_pk_len ) );
+            TEST_EQUAL( c_x1_pk_len, expected_size_zk_public );
             c_x1_pk_off = buffer1_off;
             buffer1_off += c_x1_pk_len;
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PROOF,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_x1_pr_len ) );
+            TEST_LE_U( c_x1_pr_len, max_expected_size_zk_proof );
             c_x1_pr_off = buffer1_off;
             buffer1_off += c_x1_pr_len;
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_KEY_SHARE,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_g2_len ) );
+            TEST_EQUAL( c_g2_len, expected_size_key_share );
             c_g2_off = buffer1_off;
             buffer1_off += c_g2_len;
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PUBLIC,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_x2_pk_len ) );
+            TEST_EQUAL( c_x2_pk_len, expected_size_zk_public );
             c_x2_pk_off = buffer1_off;
             buffer1_off += c_x2_pk_len;
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PROOF,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_x2_pr_len ) );
+            TEST_LE_U( c_x2_pr_len, max_expected_size_zk_proof );
             c_x2_pr_off = buffer1_off;
             buffer1_off += c_x2_pr_len;
 
@@ -992,8 +1013,8 @@
 
             if( inject_error == 2 )
             {
-                buffer1[c_x1_pk_off + 12] >>= 4;
-                buffer1[c_x2_pk_off + 7] <<= 4;
+                buffer1[c_x1_pr_off + 12] ^= 1;
+                buffer1[c_x2_pr_off + 7] ^= 1;
                 expected_status = PSA_ERROR_DATA_INVALID;
             }
 
@@ -1083,16 +1104,19 @@
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_KEY_SHARE,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_a_len ) );
+            TEST_EQUAL( s_a_len, expected_size_key_share );
             s_a_off = buffer0_off;
             buffer0_off += s_a_len;
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PUBLIC,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_x2s_pk_len ) );
+            TEST_EQUAL( s_x2s_pk_len, expected_size_zk_public );
             s_x2s_pk_off = buffer0_off;
             buffer0_off += s_x2s_pk_len;
             PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PROOF,
                                          buffer0 + buffer0_off,
                                          512 - buffer0_off, &s_x2s_pr_len ) );
+            TEST_LE_U( s_x2s_pr_len, max_expected_size_zk_proof );
             s_x2s_pr_off = buffer0_off;
             buffer0_off += s_x2s_pr_len;
 
@@ -1154,16 +1178,19 @@
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_KEY_SHARE,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_a_len ) );
+            TEST_EQUAL( c_a_len, expected_size_key_share );
             c_a_off = buffer1_off;
             buffer1_off += c_a_len;
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PUBLIC,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_x2s_pk_len ) );
+            TEST_EQUAL( c_x2s_pk_len, expected_size_zk_public );
             c_x2s_pk_off = buffer1_off;
             buffer1_off += c_x2s_pk_len;
             PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PROOF,
                                          buffer1 + buffer1_off,
                                          512 - buffer1_off, &c_x2s_pr_len ) );
+            TEST_LE_U( c_x2s_pr_len, max_expected_size_zk_proof );
             c_x2s_pr_off = buffer1_off;
             buffer1_off += c_x2s_pr_len;
 
@@ -8713,7 +8740,9 @@
 {
     psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
     psa_pake_operation_t operation = psa_pake_operation_init();
+    psa_pake_operation_t op_copy = psa_pake_operation_init();
     psa_algorithm_t alg = alg_arg;
+    psa_pake_primitive_t primitive = primitive_arg;
     psa_key_type_t key_type_pw = key_type_pw_arg;
     psa_key_usage_t key_usage_pw = key_usage_pw_arg;
     psa_algorithm_t hash_alg = hash_arg;
@@ -8731,9 +8760,9 @@
 
     PSA_INIT( );
 
-    ASSERT_ALLOC( output_buffer,
-                  PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg,
-                                       PSA_PAKE_STEP_KEY_SHARE) );
+    size_t buf_size = PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg,
+                                       PSA_PAKE_STEP_KEY_SHARE);
+    ASSERT_ALLOC( output_buffer, buf_size );
 
     if( pw_data->len > 0 )
     {
@@ -8745,7 +8774,7 @@
     }
 
     psa_pake_cs_set_algorithm( &cipher_suite, alg );
-    psa_pake_cs_set_primitive( &cipher_suite, primitive_arg );
+    psa_pake_cs_set_primitive( &cipher_suite, primitive );
     psa_pake_cs_set_hash( &cipher_suite, hash_alg );
 
     PSA_ASSERT( psa_pake_abort( &operation ) );
@@ -8799,54 +8828,71 @@
     TEST_EQUAL( psa_pake_set_peer( &operation, unsupported_id, 4 ),
                 PSA_ERROR_NOT_SUPPORTED );
 
+    const size_t size_key_share = PSA_PAKE_INPUT_SIZE( alg, primitive,
+                                                PSA_PAKE_STEP_KEY_SHARE );
+    const size_t size_zk_public = PSA_PAKE_INPUT_SIZE( alg, primitive,
+                                                PSA_PAKE_STEP_ZK_PUBLIC );
+    const size_t size_zk_proof = PSA_PAKE_INPUT_SIZE( alg, primitive,
+                                                PSA_PAKE_STEP_ZK_PROOF );
+
     /* First round */
     if( input_first )
     {
-        /* Invalid parameters */
-        TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF,
+        /* Invalid parameters (input) */
+        op_copy = operation;
+        TEST_EQUAL( psa_pake_input( &op_copy, PSA_PAKE_STEP_ZK_PROOF,
                                     NULL, 0 ),
                     PSA_ERROR_INVALID_ARGUMENT );
-        TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF + 10,
-                                    output_buffer, 66 ),
+        /* Invalid parameters (step) */
+        op_copy = operation;
+        TEST_EQUAL( psa_pake_input( &op_copy, PSA_PAKE_STEP_ZK_PROOF + 10,
+                                    output_buffer, size_zk_proof ),
                     PSA_ERROR_INVALID_ARGUMENT );
         /* Invalid first step */
-        TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF,
-                                    output_buffer, 66 ),
+        op_copy = operation;
+        TEST_EQUAL( psa_pake_input( &op_copy, PSA_PAKE_STEP_ZK_PROOF,
+                                    output_buffer, size_zk_proof ),
                     PSA_ERROR_BAD_STATE );
 
+        /* Possibly valid */
         TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_KEY_SHARE,
-                                    output_buffer, 66 ),
+                                    output_buffer, size_key_share ),
                     expected_status_input_output);
 
         if( expected_status_input_output == PSA_SUCCESS )
         {
             /* Buffer too large */
             TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PUBLIC,
-                                    output_buffer, 512 ),
-                        PSA_ERROR_INSUFFICIENT_MEMORY );
+                                    output_buffer, size_zk_public + 1 ),
+                        PSA_ERROR_INVALID_ARGUMENT );
 
-            /* The operation should be aborted at this point */
+            /* The operation's state should be invalidated at this point */
             TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PUBLIC,
-                                        output_buffer, 66 ),
+                                        output_buffer, size_zk_public ),
                         PSA_ERROR_BAD_STATE );
         }
     }
     else
     {
-        /* Invalid parameters */
-        TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF,
+        /* Invalid parameters (output) */
+        op_copy = operation;
+        TEST_EQUAL( psa_pake_output( &op_copy, PSA_PAKE_STEP_ZK_PROOF,
                                      NULL, 0, NULL ),
                     PSA_ERROR_INVALID_ARGUMENT );
-        TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF + 10,
-                                     output_buffer, 512, &output_len ),
+        op_copy = operation;
+        /* Invalid parameters (step) */
+        TEST_EQUAL( psa_pake_output( &op_copy, PSA_PAKE_STEP_ZK_PROOF + 10,
+                                     output_buffer, buf_size, &output_len ),
                     PSA_ERROR_INVALID_ARGUMENT );
         /* Invalid first step */
-        TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF,
-                                     output_buffer, 512, &output_len ),
+        op_copy = operation;
+        TEST_EQUAL( psa_pake_output( &op_copy, PSA_PAKE_STEP_ZK_PROOF,
+                                     output_buffer, buf_size, &output_len ),
                     PSA_ERROR_BAD_STATE );
 
+        /* Possibly valid */
         TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_KEY_SHARE,
-                                     output_buffer, 512, &output_len ),
+                                     output_buffer, buf_size, &output_len ),
                     expected_status_input_output );
 
         if( expected_status_input_output == PSA_SUCCESS )
@@ -8855,12 +8901,12 @@
 
             /* Buffer too small */
             TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PUBLIC,
-                                         output_buffer, 5, &output_len ),
+                                         output_buffer, size_zk_public - 1, &output_len ),
                         PSA_ERROR_BUFFER_TOO_SMALL );
 
-            /* The operation should be aborted at this point */
+            /* The operation's state should be invalidated at this point */
             TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PUBLIC,
-                                         output_buffer, 512, &output_len ),
+                                         output_buffer, buf_size, &output_len ),
                         PSA_ERROR_BAD_STATE );
         }
     }
@@ -9009,3 +9055,47 @@
     PSA_DONE( );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void ecjpake_size_macros( )
+{
+    const psa_algorithm_t alg = PSA_ALG_JPAKE;
+    const size_t bits = 256;
+    const psa_pake_primitive_t prim = PSA_PAKE_PRIMITIVE(
+            PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, bits );
+    const psa_key_type_t key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(
+            PSA_ECC_FAMILY_SECP_R1 );
+
+    // https://armmbed.github.io/mbed-crypto/1.1_PAKE_Extension.0-bet.0/html/pake.html#pake-step-types
+    /* The output for KEY_SHARE and ZK_PUBLIC is the same as a public key */
+    TEST_EQUAL( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_KEY_SHARE),
+                PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( key_type, bits ) );
+    TEST_EQUAL( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PUBLIC),
+                PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( key_type, bits ) );
+    /* The output for ZK_PROOF is the same bitsize as the curve */
+    TEST_EQUAL( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PROOF),
+                PSA_BITS_TO_BYTES( bits ) );
+
+    /* Input sizes are the same as output sizes */
+    TEST_EQUAL( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_KEY_SHARE),
+                PSA_PAKE_INPUT_SIZE(alg, prim, PSA_PAKE_STEP_KEY_SHARE) );
+    TEST_EQUAL( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PUBLIC),
+                PSA_PAKE_INPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PUBLIC) );
+    TEST_EQUAL( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PROOF),
+                PSA_PAKE_INPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PROOF) );
+
+    /* These inequalities will always hold even when other PAKEs are added */
+    TEST_LE_U( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_KEY_SHARE),
+               PSA_PAKE_OUTPUT_MAX_SIZE );
+    TEST_LE_U( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PUBLIC),
+               PSA_PAKE_OUTPUT_MAX_SIZE );
+    TEST_LE_U( PSA_PAKE_OUTPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PROOF),
+               PSA_PAKE_OUTPUT_MAX_SIZE );
+    TEST_LE_U( PSA_PAKE_INPUT_SIZE(alg, prim, PSA_PAKE_STEP_KEY_SHARE),
+               PSA_PAKE_INPUT_MAX_SIZE );
+    TEST_LE_U( PSA_PAKE_INPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PUBLIC),
+               PSA_PAKE_INPUT_MAX_SIZE );
+    TEST_LE_U( PSA_PAKE_INPUT_SIZE(alg, prim, PSA_PAKE_STEP_ZK_PROOF),
+               PSA_PAKE_INPUT_MAX_SIZE );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 8dd3379..bd03016 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -88,7 +88,11 @@
 
 X509 CRT information EC, SHA256 Digest, hardware module name SAN
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_cert_info:"data_files/server5-othername.crt":"cert. version     \: 3\nserial number     \: 4D\nissuer name       \: C=UK, O=Mbed TLS, CN=Mbed TLS othername SAN\nsubject name      \: C=UK, O=Mbed TLS, CN=Mbed TLS othername SAN\nissued  on        \: 2019-03-24 09\:06\:02\nexpires on        \: 2029-03-21 09\:06\:02\nsigned using      \: ECDSA with SHA256\nEC key size       \: 256 bits\nsubject alt name  \:\n    otherName \:\n        hardware module name \:\n            hardware type          \: 1.3.6.1.4.1.17.3\n            hardware serial number \: 123456\n"
+x509_cert_info:"data_files/server5-othername.crt":"cert. version     \: 3\nserial number     \: 4D\nissuer name       \: C=UK, O=Mbed TLS, CN=Mbed TLS othername SAN\nsubject name      \: C=UK, O=Mbed TLS, CN=Mbed TLS othername SAN\nissued  on        \: 2019-03-24 09\:06\:02\nexpires on        \: 2029-03-21 09\:06\:02\nsigned using      \: ECDSA with SHA256\nEC key size       \: 256 bits\nsubject alt name  \:\n    otherName \:\n        hardware module name \:\n            hardware type          \: 1.3.6.1.4.1.17.3\n            hardware serial number \: 313233343536\n"
+
+X509 CRT information EC, SHA256 Digest, binary hardware module name SAN
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+x509_cert_info:"data_files/server5-nonprintable_othername.crt":"cert. version     \: 3\nserial number     \: 4D\nissuer name       \: C=UK, O=Mbed TLS, CN=Mbed TLS non-printable othername SAN\nsubject name      \: C=UK, O=Mbed TLS, CN=Mbed TLS non-printable othername SAN\nissued  on        \: 2022-09-06 15\:56\:47\nexpires on        \: 2032-09-03 15\:56\:47\nsigned using      \: ECDSA with SHA256\nEC key size       \: 256 bits\nsubject alt name  \:\n    otherName \:\n        hardware module name \:\n            hardware type          \: 1.3.6.1.4.1.17.3\n            hardware serial number \: 3132338081008180333231\n"
 
 X509 CRT information EC, SHA256 Digest, Wisun Fan device
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
@@ -112,7 +116,7 @@
 
 X509 CRT information, Multiple different Subject Alt Name
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_cert_info:"data_files/multiple_san.crt":"cert. version     \: 3\nserial number     \: 04\nissuer name       \: C=UK, O=Mbed TLS, CN=Mbed TLS multiple othername SAN\nsubject name      \: C=UK, O=Mbed TLS, CN=Mbed TLS multiple othername SAN\nissued  on        \: 2019-04-22 16\:10\:48\nexpires on        \: 2029-04-19 16\:10\:48\nsigned using      \: ECDSA with SHA256\nEC key size       \: 256 bits\nsubject alt name  \:\n    dNSName \: example.com\n    otherName \:\n        hardware module name \:\n            hardware type          \: 1.3.6.1.4.1.17.3\n            hardware serial number \: 123456\n    dNSName \: example.net\n    dNSName \: *.example.org\n"
+x509_cert_info:"data_files/multiple_san.crt":"cert. version     \: 3\nserial number     \: 04\nissuer name       \: C=UK, O=Mbed TLS, CN=Mbed TLS multiple othername SAN\nsubject name      \: C=UK, O=Mbed TLS, CN=Mbed TLS multiple othername SAN\nissued  on        \: 2019-04-22 16\:10\:48\nexpires on        \: 2029-04-19 16\:10\:48\nsigned using      \: ECDSA with SHA256\nEC key size       \: 256 bits\nsubject alt name  \:\n    dNSName \: example.com\n    otherName \:\n        hardware module name \:\n            hardware type          \: 1.3.6.1.4.1.17.3\n            hardware serial number \: 313233343536\n    dNSName \: example.net\n    dNSName \: *.example.org\n"
 
 X509 CRT information, Subject Alt Name + Key Usage
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA
@@ -172,7 +176,11 @@
 
 X509 SAN parsing otherName
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_parse_san:"data_files/server5-othername.crt":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 123456\n"
+x509_parse_san:"data_files/server5-othername.crt":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 313233343536\n"
+
+X509 SAN parsing binary otherName
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+x509_parse_san:"data_files/server5-nonprintable_othername.crt":"type \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 3132338081008180333231\n"
 
 X509 SAN parsing dNSName
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
@@ -180,7 +188,7 @@
 
 X509 SAN parsing  Multiple different types
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_parse_san:"data_files/multiple_san.crt":"type \: 2\ndNSName \: example.com\ntype \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 123456\ntype \: 2\ndNSName \: example.net\ntype \: 2\ndNSName \: *.example.org\n"
+x509_parse_san:"data_files/multiple_san.crt":"type \: 2\ndNSName \: example.com\ntype \: 0\notherName \: hardware module name \: hardware type \: 1.3.6.1.4.1.17.3, hardware serial number \: 313233343536\ntype \: 2\ndNSName \: example.net\ntype \: 2\ndNSName \: *.example.org\n"
 
 X509 SAN parsing, no subject alt name
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECDSA_C
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index a3606f2..2585720 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -246,36 +246,30 @@
 
     switch( san->type )
     {
-       case( MBEDTLS_X509_SAN_OTHER_NAME ):
-           ret = mbedtls_snprintf( p, n, "\notherName :");
-           MBEDTLS_X509_SAFE_SNPRINTF;
+        case( MBEDTLS_X509_SAN_OTHER_NAME ):
+            ret = mbedtls_snprintf( p, n, "\notherName :");
+            MBEDTLS_X509_SAFE_SNPRINTF;
 
-           if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME,
-                    &san->san.other_name.value.hardware_module_name.oid ) != 0 )
-           {
-               ret = mbedtls_snprintf( p, n, " hardware module name :" );
-               MBEDTLS_X509_SAFE_SNPRINTF;
-               ret = mbedtls_snprintf( p, n, " hardware type : " );
-               MBEDTLS_X509_SAFE_SNPRINTF;
+            if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME,
+                     &san->san.other_name.value.hardware_module_name.oid ) != 0 )
+            {
+                ret = mbedtls_snprintf( p, n, " hardware module name :" );
+                MBEDTLS_X509_SAFE_SNPRINTF;
+                ret = mbedtls_snprintf( p, n, " hardware type : " );
+                MBEDTLS_X509_SAFE_SNPRINTF;
 
-               ret = mbedtls_oid_get_numeric_string( p, n,
-                          &san->san.other_name.value.hardware_module_name.oid );
-               MBEDTLS_X509_SAFE_SNPRINTF;
+                ret = mbedtls_oid_get_numeric_string( p, n,
+                           &san->san.other_name.value.hardware_module_name.oid );
+                MBEDTLS_X509_SAFE_SNPRINTF;
 
-               ret = mbedtls_snprintf( p, n, ", hardware serial number : " );
-               MBEDTLS_X509_SAFE_SNPRINTF;
+                ret = mbedtls_snprintf( p, n, ", hardware serial number : " );
+                MBEDTLS_X509_SAFE_SNPRINTF;
 
-               if( san->san.other_name.value.hardware_module_name.val.len >= n )
-               {
-                   *p = '\0';
-                   return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
-               }
-
-               for( i=0; i < san->san.other_name.value.hardware_module_name.val.len; i++ )
-               {
-                   *p++ = san->san.other_name.value.hardware_module_name.val.p[i];
-               }
-               n -= san->san.other_name.value.hardware_module_name.val.len;
+                for( i = 0; i < san->san.other_name.value.hardware_module_name.val.len; i++ )
+                {
+                    ret = mbedtls_snprintf( p, n, "%02X", san->san.other_name.value.hardware_module_name.val.p[i] );
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+                }
             }
         break;/* MBEDTLS_OID_ON_HW_MODULE_NAME */
         case(  MBEDTLS_X509_SAN_DNS_NAME ):
@@ -825,7 +819,6 @@
     unsigned char *p;
     size_t name_len;
     mbedtls_x509_name head;
-    mbedtls_x509_name *allocated, *prev;
     int ret;
 
     memset( &head, 0, sizeof( head ) );
@@ -835,17 +828,7 @@
 
     ret = mbedtls_x509_get_name( &p, ( name + name_len ), &head );
     if( ret == 0 )
-    {
-        allocated = head.next;
-
-        while( allocated != NULL )
-        {
-            prev = allocated;
-            allocated = allocated->next;
-
-            mbedtls_free( prev );
-        }
-    }
+        mbedtls_asn1_free_named_data_list_shallow( head.next );
 
     TEST_EQUAL( ret, exp_ret );
 
@@ -859,7 +842,7 @@
     int ret = 0, i;
     size_t len = 0, out_size;
     mbedtls_asn1_named_data *names = NULL;
-    mbedtls_x509_name parsed, *parsed_cur, *parsed_prv;
+    mbedtls_x509_name parsed, *parsed_cur;
     // Size of buf is maximum required for test cases
     unsigned char buf[80], *out = NULL, *c;
     const char *short_name;
@@ -913,14 +896,7 @@
 exit:
     mbedtls_free( out );
     mbedtls_asn1_free_named_data_list( &names );
-
-    parsed_cur = parsed.next;
-    while( parsed_cur != 0 )
-    {
-        parsed_prv = parsed_cur;
-        parsed_cur = parsed_cur->next;
-        mbedtls_free( parsed_prv );
-    }
+    mbedtls_asn1_free_named_data_list_shallow( parsed.next );
 }
 /* END_CASE */