Merge pull request #6964 from davidhorstmann-arm/code-style-improvements

Improvements to code style script
diff --git a/ChangeLog.d/crypto_config_ccm_star.txt b/ChangeLog.d/crypto_config_ccm_star.txt
new file mode 100644
index 0000000..947014a
--- /dev/null
+++ b/ChangeLog.d/crypto_config_ccm_star.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * List PSA_WANT_ALG_CCM_STAR_NO_TAG in psa/crypto_config.h so that it can
+     be toggled with config.py.
diff --git a/ChangeLog.d/improve_x509_cert_writing_serial_number_management.txt b/ChangeLog.d/improve_x509_cert_writing_serial_number_management.txt
new file mode 100644
index 0000000..1764c2f
--- /dev/null
+++ b/ChangeLog.d/improve_x509_cert_writing_serial_number_management.txt
@@ -0,0 +1,19 @@
+Bugfix
+   * mbedtls_x509write_crt_set_serial() now explicitly rejects serial numbers
+     whose binary representation is longer than 20 bytes. This was already
+     forbidden by the standard (RFC5280 - section 4.1.2.2) and now it's being
+     enforced also at code level.
+
+New deprecations
+   * mbedtls_x509write_crt_set_serial() is now being deprecated in favor of
+     mbedtls_x509write_crt_set_serial_raw(). The goal here is to remove any
+     direct dependency of X509 on BIGNUM_C.
+
+Changes
+   * programs/x509/cert_write:
+     - now it accepts the serial number in 2 different formats: decimal and
+       hex. They cannot be used simultaneously
+     - "serial" is used for the decimal format and it's limted in size to
+       unsigned long long int
+     - "serial_hex" is used for the hex format; max length here is
+       MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN*2
diff --git a/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt b/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt
new file mode 100644
index 0000000..cfea661
--- /dev/null
+++ b/ChangeLog.d/psa_alg_tls12_ecjpake_to_pms-reject_ka.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * The key derivation algorithm PSA_ALG_TLS12_ECJPAKE_TO_PMS cannot be
+     used on a shared secret from a key agreement since its input must be
+     an ECC public key. Reject this properly.
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index 09bc32c..48b2d32 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -843,6 +843,8 @@
 
 /* These features are always enabled. */
 #define PSA_WANT_KEY_TYPE_DERIVE 1
+#define PSA_WANT_KEY_TYPE_PASSWORD 1
+#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1
 #define PSA_WANT_KEY_TYPE_RAW_DATA 1
 
 #ifdef __cplusplus
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 661f8aa..7c3a625 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -197,7 +197,7 @@
 #define MBEDTLS_X509_CRT_VERSION_2              1
 #define MBEDTLS_X509_CRT_VERSION_3              2
 
-#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32
+#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 20
 #define MBEDTLS_X509_RFC5280_UTC_TIME_LEN   15
 
 #if !defined(MBEDTLS_X509_MAX_FILE_PATH_LEN)
@@ -277,7 +277,8 @@
  */
 typedef struct mbedtls_x509write_cert {
     int MBEDTLS_PRIVATE(version);
-    mbedtls_mpi MBEDTLS_PRIVATE(serial);
+    unsigned char MBEDTLS_PRIVATE(serial)[MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN];
+    size_t MBEDTLS_PRIVATE(serial_len);
     mbedtls_pk_context *MBEDTLS_PRIVATE(subject_key);
     mbedtls_pk_context *MBEDTLS_PRIVATE(issuer_key);
     mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject);
@@ -986,15 +987,43 @@
  */
 void mbedtls_x509write_crt_set_version(mbedtls_x509write_cert *ctx, int version);
 
+#if defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
 /**
  * \brief           Set the serial number for a Certificate.
  *
+ * \deprecated      This function is deprecated and will be removed in a
+ *                  future version of the library. Please use
+ *                  mbedtls_x509write_crt_set_serial_raw() instead.
+ *
+ * \note            Even though the MBEDTLS_BIGNUM_C guard looks redundant since
+ *                  X509 depends on PK and PK depends on BIGNUM, this emphasizes
+ *                  a direct dependency between X509 and BIGNUM which is going
+ *                  to be deprecated in the future.
+ *
  * \param ctx       CRT context to use
  * \param serial    serial number to set
  *
  * \return          0 if successful
  */
-int mbedtls_x509write_crt_set_serial(mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial);
+int MBEDTLS_DEPRECATED mbedtls_x509write_crt_set_serial(
+    mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial);
+#endif // MBEDTLS_BIGNUM_C && !MBEDTLS_DEPRECATED_REMOVED
+
+/**
+ * \brief           Set the serial number for a Certificate.
+ *
+ * \param ctx          CRT context to use
+ * \param serial       A raw array of bytes containing the serial number in big
+ *                     endian format
+ * \param serial_len   Length of valid bytes (expressed in bytes) in \p serial
+ *                     input buffer
+ *
+ * \return          0 if successful, or
+ *                  MBEDTLS_ERR_X509_BAD_INPUT_DATA if the provided input buffer
+ *                  is too big (longer than MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN)
+ */
+int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx,
+                                         unsigned char *serial, size_t serial_len);
 
 /**
  * \brief           Set the validity period for a Certificate
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index 5ab4fde..e68fac8 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -57,6 +57,7 @@
 #define PSA_WANT_ALG_CBC_NO_PADDING             1
 #define PSA_WANT_ALG_CBC_PKCS7                  1
 #define PSA_WANT_ALG_CCM                        1
+#define PSA_WANT_ALG_CCM_STAR_NO_TAG            1
 #define PSA_WANT_ALG_CMAC                       1
 #define PSA_WANT_ALG_CFB                        1
 #define PSA_WANT_ALG_CHACHA20_POLY1305          1
@@ -115,6 +116,8 @@
 #define PSA_WANT_ECC_SECP_R1_521                1
 
 #define PSA_WANT_KEY_TYPE_DERIVE                1
+#define PSA_WANT_KEY_TYPE_PASSWORD              1
+#define PSA_WANT_KEY_TYPE_PASSWORD_HASH         1
 #define PSA_WANT_KEY_TYPE_HMAC                  1
 #define PSA_WANT_KEY_TYPE_AES                   1
 #define PSA_WANT_KEY_TYPE_ARIA                  1
diff --git a/library/bignum_mod.c b/library/bignum_mod.c
index e701a68..e986865 100644
--- a/library/bignum_mod.c
+++ b/library/bignum_mod.c
@@ -35,15 +35,15 @@
 #include "constant_time_internal.h"
 
 int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
-                                  const mbedtls_mpi_mod_modulus *m,
+                                  const mbedtls_mpi_mod_modulus *N,
                                   mbedtls_mpi_uint *p,
                                   size_t p_limbs)
 {
-    if (p_limbs != m->limbs || !mbedtls_mpi_core_lt_ct(p, m->p, m->limbs)) {
+    if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) {
         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     }
 
-    r->limbs = m->limbs;
+    r->limbs = N->limbs;
     r->p = p;
 
     return 0;
@@ -59,45 +59,45 @@
     r->p = NULL;
 }
 
-void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *m)
+void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N)
 {
-    if (m == NULL) {
+    if (N == NULL) {
         return;
     }
 
-    m->p = NULL;
-    m->limbs = 0;
-    m->bits = 0;
-    m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
+    N->p = NULL;
+    N->limbs = 0;
+    N->bits = 0;
+    N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
 }
 
-void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *m)
+void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
 {
-    if (m == NULL) {
+    if (N == NULL) {
         return;
     }
 
-    switch (m->int_rep) {
+    switch (N->int_rep) {
         case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
-            if (m->rep.mont.rr != NULL) {
-                mbedtls_platform_zeroize((mbedtls_mpi_uint *) m->rep.mont.rr,
-                                         m->limbs * sizeof(mbedtls_mpi_uint));
-                mbedtls_free((mbedtls_mpi_uint *) m->rep.mont.rr);
-                m->rep.mont.rr = NULL;
+            if (N->rep.mont.rr != NULL) {
+                mbedtls_platform_zeroize((mbedtls_mpi_uint *) N->rep.mont.rr,
+                                         N->limbs * sizeof(mbedtls_mpi_uint));
+                mbedtls_free((mbedtls_mpi_uint *) N->rep.mont.rr);
+                N->rep.mont.rr = NULL;
             }
-            m->rep.mont.mm = 0;
+            N->rep.mont.mm = 0;
             break;
         case MBEDTLS_MPI_MOD_REP_OPT_RED:
-            mbedtls_free(m->rep.ored);
+            mbedtls_free(N->rep.ored);
             break;
         case MBEDTLS_MPI_MOD_REP_INVALID:
             break;
     }
 
-    m->p = NULL;
-    m->limbs = 0;
-    m->bits = 0;
-    m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
+    N->p = NULL;
+    N->limbs = 0;
+    N->bits = 0;
+    N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
 }
 
 static int set_mont_const_square(const mbedtls_mpi_uint **X,
@@ -136,26 +136,26 @@
     return ret;
 }
 
-int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *m,
+int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
                                   const mbedtls_mpi_uint *p,
                                   size_t p_limbs,
                                   mbedtls_mpi_mod_rep_selector int_rep)
 {
     int ret = 0;
 
-    m->p = p;
-    m->limbs = p_limbs;
-    m->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
+    N->p = p;
+    N->limbs = p_limbs;
+    N->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
 
     switch (int_rep) {
         case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
-            m->int_rep = int_rep;
-            m->rep.mont.mm = mbedtls_mpi_core_montmul_init(m->p);
-            ret = set_mont_const_square(&m->rep.mont.rr, m->p, m->limbs);
+            N->int_rep = int_rep;
+            N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p);
+            ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs);
             break;
         case MBEDTLS_MPI_MOD_REP_OPT_RED:
-            m->int_rep = int_rep;
-            m->rep.ored = NULL;
+            N->int_rep = int_rep;
+            N->rep.ored = NULL;
             break;
         default:
             ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@@ -165,7 +165,7 @@
 exit:
 
     if (ret != 0) {
-        mbedtls_mpi_mod_modulus_free(m);
+        mbedtls_mpi_mod_modulus_free(N);
     }
 
     return ret;
@@ -349,7 +349,7 @@
 
 /* BEGIN MERGE SLOT 7 */
 int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
-                         const mbedtls_mpi_mod_modulus *m,
+                         const mbedtls_mpi_mod_modulus *N,
                          const unsigned char *buf,
                          size_t buflen,
                          mbedtls_mpi_mod_ext_rep ext_rep)
@@ -357,28 +357,28 @@
     int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
 
     /* Do our best to check if r and m have been set up */
-    if (r->limbs == 0 || m->limbs == 0) {
+    if (r->limbs == 0 || N->limbs == 0) {
         goto cleanup;
     }
-    if (r->limbs != m->limbs) {
+    if (r->limbs != N->limbs) {
         goto cleanup;
     }
 
-    ret = mbedtls_mpi_mod_raw_read(r->p, m, buf, buflen, ext_rep);
+    ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep);
     if (ret != 0) {
         goto cleanup;
     }
 
-    r->limbs = m->limbs;
+    r->limbs = N->limbs;
 
-    ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, m);
+    ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N);
 
 cleanup:
     return ret;
 }
 
 int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
-                          const mbedtls_mpi_mod_modulus *m,
+                          const mbedtls_mpi_mod_modulus *N,
                           unsigned char *buf,
                           size_t buflen,
                           mbedtls_mpi_mod_ext_rep ext_rep)
@@ -386,28 +386,28 @@
     int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
 
     /* Do our best to check if r and m have been set up */
-    if (r->limbs == 0 || m->limbs == 0) {
+    if (r->limbs == 0 || N->limbs == 0) {
         goto cleanup;
     }
-    if (r->limbs != m->limbs) {
+    if (r->limbs != N->limbs) {
         goto cleanup;
     }
 
-    if (m->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
-        ret = mbedtls_mpi_mod_raw_from_mont_rep(r->p, m);
+    if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
+        ret = mbedtls_mpi_mod_raw_from_mont_rep(r->p, N);
         if (ret != 0) {
             goto cleanup;
         }
     }
 
-    ret = mbedtls_mpi_mod_raw_write(r->p, m, buf, buflen, ext_rep);
+    ret = mbedtls_mpi_mod_raw_write(r->p, N, buf, buflen, ext_rep);
 
-    if (m->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
+    if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
         /* If this fails, the value of r is corrupted and we want to return
          * this error (as opposed to the error code from the write above) to
          * let the caller know. If it succeeds, we want to return the error
          * code from write above. */
-        int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep(r->p, m);
+        int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep(r->p, N);
         if (ret == 0) {
             ret = conv_ret;
         }
diff --git a/library/bignum_mod.h b/library/bignum_mod.h
index 0a22e71..d8c8b7d 100644
--- a/library/bignum_mod.h
+++ b/library/bignum_mod.h
@@ -140,34 +140,34 @@
 
 /** Setup a residue structure.
  *
- * The residue will be set up with the buffer \p p and modulus \p m.
+ * The residue will be set up with the buffer \p p and modulus \p N.
  *
  * The memory pointed to by \p p will be used by the resulting residue structure.
  * The value at the pointed-to memory will be the initial value of \p r and must
  * hold a value that is less than the modulus. This value will be used as-is
- * and interpreted according to the value of the `m->int_rep` field.
+ * and interpreted according to the value of the `N->int_rep` field.
  *
- * The modulus \p m will be the modulus associated with \p r. The residue \p r
- * should only be used in operations where the modulus is \p m.
+ * The modulus \p N will be the modulus associated with \p r. The residue \p r
+ * should only be used in operations where the modulus is \p N.
  *
  * \param[out] r    The address of the residue to setup.
- * \param[in] m     The address of the modulus related to \p r.
+ * \param[in] N     The address of the modulus related to \p r.
  * \param[in] p     The address of the limb array containing the value of \p r.
  *                  The memory pointed to by \p p will be used by \p r and must
  *                  not be modified in any way until after
  *                  mbedtls_mpi_mod_residue_release() is called. The data
  *                  pointed to by \p p must be less than the modulus (the value
- *                  pointed to by `m->p`) and already in the representation
- *                  indicated by `m->int_rep`.
+ *                  pointed to by `N->p`) and already in the representation
+ *                  indicated by `N->int_rep`.
  * \param p_limbs   The number of limbs of \p p. Must be the same as the number
- *                  of limbs in the modulus \p m.
+ *                  of limbs in the modulus \p N.
  *
  * \return      \c 0 if successful.
  * \return      #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p p_limbs is less than the
- *              limbs in \p m or if \p p is not less than \p m.
+ *              limbs in \p N or if \p p is not less than \p N.
  */
 int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
-                                  const mbedtls_mpi_mod_modulus *m,
+                                  const mbedtls_mpi_mod_modulus *N,
                                   mbedtls_mpi_uint *p,
                                   size_t p_limbs);
 
@@ -185,25 +185,25 @@
 
 /** Initialize a modulus structure.
  *
- * \param[out] m     The address of the modulus structure to initialize.
+ * \param[out] N     The address of the modulus structure to initialize.
  */
-void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *m);
+void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N);
 
 /** Setup a modulus structure.
  *
- * \param[out] m    The address of the modulus structure to populate.
- * \param[in] p     The address of the limb array storing the value of \p m.
- *                  The memory pointed to by \p p will be used by \p m and must
+ * \param[out] N    The address of the modulus structure to populate.
+ * \param[in] p     The address of the limb array storing the value of \p N.
+ *                  The memory pointed to by \p p will be used by \p N and must
  *                  not be modified in any way until after
  *                  mbedtls_mpi_mod_modulus_free() is called.
  * \param p_limbs   The number of limbs of \p p.
  * \param int_rep   The internal representation to be used for residues
- *                  associated with \p m (see #mbedtls_mpi_mod_rep_selector).
+ *                  associated with \p N (see #mbedtls_mpi_mod_rep_selector).
  *
  * \return      \c 0 if successful.
  * \return      #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p int_rep is invalid.
  */
-int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *m,
+int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
                                   const mbedtls_mpi_uint *p,
                                   size_t p_limbs,
                                   mbedtls_mpi_mod_rep_selector int_rep);
@@ -216,9 +216,9 @@
  *          mbedtls_mpi_mod_modulus_setup() only removes the reference to it,
  *          making it safe to free or to use it again.
  *
- * \param[in,out] m     The address of the modulus structure to free.
+ * \param[in,out] N     The address of the modulus structure to free.
  */
-void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *m);
+void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N);
 
 /* BEGIN MERGE SLOT 1 */
 
@@ -401,16 +401,16 @@
 /** Read a residue from a byte buffer.
  *
  * The residue will be automatically converted to the internal representation
- * based on the value of the `m->int_rep` field.
+ * based on the value of the `N->int_rep` field.
  *
- * The modulus \p m will be the modulus associated with \p r. The residue \p r
- * should only be used in operations where the modulus is \p m or a modulus
- * equivalent to \p m (in the sense that all their fields or memory pointed by
+ * The modulus \p N will be the modulus associated with \p r. The residue \p r
+ * should only be used in operations where the modulus is \p N or a modulus
+ * equivalent to \p N (in the sense that all their fields or memory pointed by
  * their fields hold the same value).
  *
  * \param[out] r    The address of the residue. It must have exactly the same
- *                  number of limbs as the modulus \p m.
- * \param[in] m     The address of the modulus.
+ *                  number of limbs as the modulus \p N.
+ * \param[in] N     The address of the modulus.
  * \param[in] buf   The input buffer to import from.
  * \param buflen    The length in bytes of \p buf.
  * \param ext_rep   The endianness of the number in the input buffer.
@@ -419,32 +419,32 @@
  * \return       #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p r isn't
  *               large enough to hold the value in \p buf.
  * \return       #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep
- *               is invalid or the value in the buffer is not less than \p m.
+ *               is invalid or the value in the buffer is not less than \p N.
  */
 int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
-                         const mbedtls_mpi_mod_modulus *m,
+                         const mbedtls_mpi_mod_modulus *N,
                          const unsigned char *buf,
                          size_t buflen,
                          mbedtls_mpi_mod_ext_rep ext_rep);
 
 /** Write a residue into a byte buffer.
  *
- * The modulus \p m must be the modulus associated with \p r (see
+ * The modulus \p N must be the modulus associated with \p r (see
  * mbedtls_mpi_mod_residue_setup() and mbedtls_mpi_mod_read()).
  *
  * The residue will be automatically converted from the internal representation
- * based on the value of `m->int_rep` field.
+ * based on the value of `N->int_rep` field.
  *
- * \warning     If the buffer is smaller than `m->bits`, the number of
+ * \warning     If the buffer is smaller than `N->bits`, the number of
  *              leading zeroes is leaked through timing. If \p r is
  *              secret, the caller must ensure that \p buflen is at least
- *              (`m->bits`+7)/8.
+ *              (`N->bits`+7)/8.
  *
  * \param[in] r     The address of the residue. It must have the same number of
- *                  limbs as the modulus \p m. (\p r is an input parameter, but
+ *                  limbs as the modulus \p N. (\p r is an input parameter, but
  *                  its value will be modified during execution and restored
  *                  before the function returns.)
- * \param[in] m     The address of the modulus associated with \r.
+ * \param[in] N     The address of the modulus associated with \r.
  * \param[out] buf  The output buffer to export to.
  * \param buflen    The length in bytes of \p buf.
  * \param ext_rep   The endianness in which the number should be written into
@@ -460,7 +460,7 @@
  *               MBEDTLS_MPI_MOD_REP_MONTGOMERY.
  */
 int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
-                          const mbedtls_mpi_mod_modulus *m,
+                          const mbedtls_mpi_mod_modulus *N,
                           unsigned char *buf,
                           size_t buflen,
                           mbedtls_mpi_mod_ext_rep ext_rep);
diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c
index aa2bd46..bf0cb25 100644
--- a/library/bignum_mod_raw.c
+++ b/library/bignum_mod_raw.c
@@ -33,6 +33,8 @@
 #include "bignum_mod.h"
 #include "constant_time_internal.h"
 
+#include "bignum_mod_raw_invasive.h"
+
 void mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint *X,
                                      const mbedtls_mpi_uint *A,
                                      const mbedtls_mpi_mod_modulus *N,
@@ -50,7 +52,7 @@
 }
 
 int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X,
-                             const mbedtls_mpi_mod_modulus *m,
+                             const mbedtls_mpi_mod_modulus *N,
                              const unsigned char *input,
                              size_t input_length,
                              mbedtls_mpi_mod_ext_rep ext_rep)
@@ -59,11 +61,11 @@
 
     switch (ext_rep) {
         case MBEDTLS_MPI_MOD_EXT_REP_LE:
-            ret = mbedtls_mpi_core_read_le(X, m->limbs,
+            ret = mbedtls_mpi_core_read_le(X, N->limbs,
                                            input, input_length);
             break;
         case MBEDTLS_MPI_MOD_EXT_REP_BE:
-            ret = mbedtls_mpi_core_read_be(X, m->limbs,
+            ret = mbedtls_mpi_core_read_be(X, N->limbs,
                                            input, input_length);
             break;
         default:
@@ -74,7 +76,7 @@
         goto cleanup;
     }
 
-    if (!mbedtls_mpi_core_lt_ct(X, m->p, m->limbs)) {
+    if (!mbedtls_mpi_core_lt_ct(X, N->p, N->limbs)) {
         ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
         goto cleanup;
     }
@@ -85,17 +87,17 @@
 }
 
 int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A,
-                              const mbedtls_mpi_mod_modulus *m,
+                              const mbedtls_mpi_mod_modulus *N,
                               unsigned char *output,
                               size_t output_length,
                               mbedtls_mpi_mod_ext_rep ext_rep)
 {
     switch (ext_rep) {
         case MBEDTLS_MPI_MOD_EXT_REP_LE:
-            return mbedtls_mpi_core_write_le(A, m->limbs,
+            return mbedtls_mpi_core_write_le(A, N->limbs,
                                              output, output_length);
         case MBEDTLS_MPI_MOD_EXT_REP_BE:
-            return mbedtls_mpi_core_write_be(A, m->limbs,
+            return mbedtls_mpi_core_write_be(A, N->limbs,
                                              output, output_length);
         default:
             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@@ -118,6 +120,19 @@
     (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c);
 }
 
+#if defined(MBEDTLS_TEST_HOOKS)
+
+MBEDTLS_STATIC_TESTABLE
+void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X,
+                                             const mbedtls_mpi_mod_modulus *N)
+{
+    mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
+
+    (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c);
+}
+
+#endif /* MBEDTLS_TEST_HOOKS */
+
 void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X,
                              const mbedtls_mpi_uint *A,
                              const mbedtls_mpi_uint *B,
@@ -229,17 +244,17 @@
 
 /* BEGIN MERGE SLOT 7 */
 int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X,
-                                    const mbedtls_mpi_mod_modulus *m)
+                                    const mbedtls_mpi_mod_modulus *N)
 {
     mbedtls_mpi_uint *T;
-    const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(m->limbs);
+    const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs);
 
     if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) {
         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     }
 
-    mbedtls_mpi_core_to_mont_rep(X, X, m->p, m->limbs,
-                                 m->rep.mont.mm, m->rep.mont.rr, T);
+    mbedtls_mpi_core_to_mont_rep(X, X, N->p, N->limbs,
+                                 N->rep.mont.mm, N->rep.mont.rr, T);
 
     mbedtls_platform_zeroize(T, t_limbs * ciL);
     mbedtls_free(T);
@@ -247,16 +262,16 @@
 }
 
 int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X,
-                                      const mbedtls_mpi_mod_modulus *m)
+                                      const mbedtls_mpi_mod_modulus *N)
 {
-    const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(m->limbs);
+    const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs);
     mbedtls_mpi_uint *T;
 
     if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) {
         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     }
 
-    mbedtls_mpi_core_from_mont_rep(X, X, m->p, m->limbs, m->rep.mont.mm, T);
+    mbedtls_mpi_core_from_mont_rep(X, X, N->p, N->limbs, N->rep.mont.mm, T);
 
     mbedtls_platform_zeroize(T, t_limbs * ciL);
     mbedtls_free(T);
@@ -265,14 +280,14 @@
 
 void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X,
                              const mbedtls_mpi_uint *A,
-                             const mbedtls_mpi_mod_modulus *m)
+                             const mbedtls_mpi_mod_modulus *N)
 {
-    mbedtls_mpi_core_sub(X, m->p, A, m->limbs);
+    mbedtls_mpi_core_sub(X, N->p, A, N->limbs);
 
     /* If A=0 initially, then X=N now. Detect this by
      * subtracting N and catching the carry. */
-    mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, X, m->p, m->limbs);
-    (void) mbedtls_mpi_core_add_if(X, m->p, m->limbs, (unsigned) borrow);
+    mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
+    (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) borrow);
 }
 /* END MERGE SLOT 7 */
 
diff --git a/library/bignum_mod_raw.h b/library/bignum_mod_raw.h
index da8db6f..a32500f 100644
--- a/library/bignum_mod_raw.h
+++ b/library/bignum_mod_raw.h
@@ -145,10 +145,10 @@
  * The MPI needs to have enough limbs to store the full value (including any
  * most significant zero bytes in the input).
  *
- * \param[out] X        The address of the MPI. The size is determined by \p m.
+ * \param[out] X        The address of the MPI. The size is determined by \p N.
  *                      (In particular, it must have at least as many limbs as
- *                      the modulus \p m.)
- * \param[in] m         The address of the modulus related to \p X.
+ *                      the modulus \p N.)
+ * \param[in] N         The address of the modulus related to \p X.
  * \param[in] input     The input buffer to import from.
  * \param input_length  The length in bytes of \p input.
  * \param ext_rep       The endianness of the number in the input buffer.
@@ -157,20 +157,20 @@
  * \return       #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
  *               large enough to hold the value in \p input.
  * \return       #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation
- *               of \p m is invalid or \p X is not less than \p m.
+ *               of \p N is invalid or \p X is not less than \p N.
  */
 int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X,
-                             const mbedtls_mpi_mod_modulus *m,
+                             const mbedtls_mpi_mod_modulus *N,
                              const unsigned char *input,
                              size_t input_length,
                              mbedtls_mpi_mod_ext_rep ext_rep);
 
 /** Export A into unsigned binary data.
  *
- * \param[in] A         The address of the MPI. The size is determined by \p m.
+ * \param[in] A         The address of the MPI. The size is determined by \p N.
  *                      (In particular, it must have at least as many limbs as
- *                      the modulus \p m.)
- * \param[in] m         The address of the modulus related to \p A.
+ *                      the modulus \p N.)
+ * \param[in] N         The address of the modulus related to \p A.
  * \param[out] output   The output buffer to export to.
  * \param output_length The length in bytes of \p output.
  * \param ext_rep       The endianness in which the number should be written into the output buffer.
@@ -179,10 +179,10 @@
  * \return       #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
  *               large enough to hold the value of \p A.
  * \return       #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation
- *               of \p m is invalid.
+ *               of \p N is invalid.
  */
 int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A,
-                              const mbedtls_mpi_mod_modulus *m,
+                              const mbedtls_mpi_mod_modulus *N,
                               unsigned char *output,
                               size_t output_length,
                               mbedtls_mpi_mod_ext_rep ext_rep);
@@ -346,7 +346,7 @@
  *                  is unspecified.
  * \param[in] N     The modulus structure.
  *
- *\ return          \c 0 if successful.
+ * \return          \c 0 if successful.
  *                  Otherwise an \c MBEDTLS_ERR_MPI_xxx error code.
  */
 int mbedtls_mpi_mod_raw_canonical_to_modulus_rep(
@@ -363,7 +363,7 @@
  *                  is unspecified.
  * \param[in] N     The modulus structure.
  *
- *\ return          \c 0 if successful.
+ * \return          \c 0 if successful.
  *                  Otherwise an \c MBEDTLS_ERR_MPI_xxx error code.
  */
 int mbedtls_mpi_mod_raw_modulus_to_canonical_rep(
@@ -410,43 +410,43 @@
 /** Convert an MPI into Montgomery form.
  *
  * \param X      The address of the MPI.
- *               Must have the same number of limbs as \p m.
- * \param m      The address of the modulus, which gives the size of
- *               the base `R` = 2^(biL*m->limbs).
+ *               Must have the same number of limbs as \p N.
+ * \param N      The address of the modulus, which gives the size of
+ *               the base `R` = 2^(biL*N->limbs).
  *
  * \return       \c 0 if successful.
  */
 int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X,
-                                    const mbedtls_mpi_mod_modulus *m);
+                                    const mbedtls_mpi_mod_modulus *N);
 
 /** Convert an MPI back from Montgomery representation.
  *
  * \param X      The address of the MPI.
- *               Must have the same number of limbs as \p m.
- * \param m      The address of the modulus, which gives the size of
- *               the base `R`= 2^(biL*m->limbs).
+ *               Must have the same number of limbs as \p N.
+ * \param N      The address of the modulus, which gives the size of
+ *               the base `R`= 2^(biL*N->limbs).
  *
  * \return       \c 0 if successful.
  */
 int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X,
-                                      const mbedtls_mpi_mod_modulus *m);
+                                      const mbedtls_mpi_mod_modulus *N);
 
 /** \brief  Perform fixed width modular negation.
  *
- * The size of the operation is determined by \p m. \p A must have
- * the same number of limbs as \p m.
+ * The size of the operation is determined by \p N. \p A must have
+ * the same number of limbs as \p N.
  *
  * \p X may be aliased to \p A.
  *
  * \param[out] X        The result of the modular negation.
  *                      This must be initialized.
  * \param[in] A         Little-endian presentation of the input operand. This
- *                      must be less than or equal to \p m.
- * \param[in] m         The modulus to use.
+ *                      must be less than or equal to \p N.
+ * \param[in] N         The modulus to use.
  */
 void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X,
                              const mbedtls_mpi_uint *A,
-                             const mbedtls_mpi_mod_modulus *m);
+                             const mbedtls_mpi_mod_modulus *N);
 /* END MERGE SLOT 7 */
 
 /* BEGIN MERGE SLOT 8 */
diff --git a/library/bignum_mod_raw_invasive.h b/library/bignum_mod_raw_invasive.h
new file mode 100644
index 0000000..ead8394
--- /dev/null
+++ b/library/bignum_mod_raw_invasive.h
@@ -0,0 +1,46 @@
+/**
+ * \file bignum_mod_raw_invasive.h
+ *
+ * \brief Function declarations for invasive functions of Low-level
+ *        modular bignum.
+ */
+/**
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H
+#define MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H
+
+#include "common.h"
+#include "mbedtls/bignum.h"
+#include "bignum_mod.h"
+
+#if defined(MBEDTLS_TEST_HOOKS)
+
+/** Convert the result of a quasi-reduction to its canonical representative.
+ *
+ * \param[in,out] X     The address of the MPI to be converted. Must have the
+ *                      same number of limbs as \p N. The input value must
+ *                      be in range 0 <= X < 2N.
+ * \param[in]     N     The address of the modulus.
+ */
+MBEDTLS_STATIC_TESTABLE
+void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X,
+                                             const mbedtls_mpi_mod_modulus *N);
+
+#endif /* MBEDTLS_TEST_HOOKS */
+
+#endif /* MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H */
diff --git a/library/constant_time.c b/library/constant_time.c
index 7f4d509..b3bf874 100644
--- a/library/constant_time.c
+++ b/library/constant_time.c
@@ -72,9 +72,9 @@
      */
     uint32_t r;
 #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__)
-    asm ("ldr %0, [%1]" : "=r" (r) : "r" (p) :);
+    asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :);
 #elif defined(__aarch64__)
-    asm ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :);
+    asm volatile ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :);
 #endif
     return r;
 }
diff --git a/library/ecp.c b/library/ecp.c
index d9d5425..08fbe86 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -582,11 +582,9 @@
     }
 
     if (grp->h != 1) {
-        mbedtls_mpi_free(&grp->P);
         mbedtls_mpi_free(&grp->A);
         mbedtls_mpi_free(&grp->B);
         mbedtls_ecp_point_free(&grp->G);
-        mbedtls_mpi_free(&grp->N);
     }
 
     if (!ecp_group_is_static_comb_table(grp) && grp->T != NULL) {
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index e62dcea..727283f 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -4502,7 +4502,9 @@
 #endif
 #endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
 
-#if defined(ECP_LOAD_GROUP)
+
+#if defined(ECP_LOAD_GROUP) || defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
 /*
  * Create an MPI from embedded constants
  * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
@@ -4513,7 +4515,9 @@
     X->n = len / sizeof(mbedtls_mpi_uint);
     X->p = (mbedtls_mpi_uint *) p;
 }
+#endif
 
+#if defined(ECP_LOAD_GROUP)
 /*
  * Set an MPI to static value 1
  */
@@ -4627,9 +4631,21 @@
 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
 /* Constants used by ecp_use_curve25519() */
 static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
-static const unsigned char curve25519_part_of_n[] = {
-    0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
-    0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
+
+/* P = 2^255 - 19 */
+static const mbedtls_mpi_uint curve25519_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7F)
+};
+
+/* N = 2^252 + 27742317777372353535851937790883648493 */
+static const mbedtls_mpi_uint curve25519_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8(0XED, 0XD3, 0XF5, 0X5C, 0X1A, 0X63, 0X12, 0X58),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XD6, 0X9C, 0XF7, 0XA2, 0XDE, 0XF9, 0XDE, 0X14),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0x00, 0x00, 0x00, 0x00),
+    MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10)
 };
 
 /*
@@ -4642,16 +4658,11 @@
     /* Actually ( A + 2 ) / 4 */
     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24));
 
-    /* P = 2^255 - 19 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 255));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 19));
+    ecp_mpi_load(&grp->P, curve25519_p, sizeof(curve25519_p));
+
     grp->pbits = mbedtls_mpi_bitlen(&grp->P);
 
-    /* N = 2^252 + 27742317777372353535851937790883648493 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&grp->N,
-                                            curve25519_part_of_n, sizeof(curve25519_part_of_n)));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 252, 1));
+    ecp_mpi_load(&grp->N, curve25519_n, sizeof(curve25519_n));
 
     /* Y intentionally not set, since we use x/z coordinates.
      * This is used as a marker to identify Montgomery curves! */
@@ -4674,11 +4685,29 @@
 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
 /* Constants used by ecp_use_curve448() */
 static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
-static const unsigned char curve448_part_of_n[] = {
-    0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
-    0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
-    0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
-    0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
+
+/* P = 2^448 - 2^224 - 1 */
+static const mbedtls_mpi_uint curve448_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFE, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00)
+};
+
+/* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
+static const mbedtls_mpi_uint curve448_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8(0XF3, 0X44, 0X58, 0XAB, 0X92, 0XC2, 0X78, 0X23),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X55, 0X8F, 0XC5, 0X8D, 0X72, 0XC2, 0X6C, 0X21),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X90, 0X36, 0XD6, 0XAE, 0X49, 0XDB, 0X4E, 0XC4),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XE9, 0X23, 0XCA, 0X7C, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
+    MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3F),
+    MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00)
 };
 
 /*
@@ -4686,20 +4715,12 @@
  */
 static int ecp_use_curve448(mbedtls_ecp_group *grp)
 {
-    mbedtls_mpi Ns;
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    mbedtls_mpi_init(&Ns);
-
     /* Actually ( A + 2 ) / 4 */
     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24));
 
-    /* P = 2^448 - 2^224 - 1 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1));
+    ecp_mpi_load(&grp->P, curve448_p, sizeof(curve448_p));
     grp->pbits = mbedtls_mpi_bitlen(&grp->P);
 
     /* Y intentionally not set, since we use x/z coordinates.
@@ -4708,17 +4729,12 @@
     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1));
     mbedtls_mpi_free(&grp->G.Y);
 
-    /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 446, 1));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&Ns,
-                                            curve448_part_of_n, sizeof(curve448_part_of_n)));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&grp->N, &grp->N, &Ns));
+    ecp_mpi_load(&grp->N, curve448_n, sizeof(curve448_n));
 
     /* Actually, the required msb for private keys */
     grp->nbits = 447;
 
 cleanup:
-    mbedtls_mpi_free(&Ns);
     if (ret != 0) {
         mbedtls_ecp_group_free(grp);
     }
diff --git a/library/pkparse.c b/library/pkparse.c
index 990b554..ccca692 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -429,7 +429,18 @@
     ret = pk_group_id_from_group(&grp, grp_id);
 
 cleanup:
-    mbedtls_ecp_group_free(&grp);
+    /* The API respecting lifecycle for mbedtls_ecp_group struct is
+     * _init(), _load() and _free(). In pk_group_id_from_specified() the
+     * temporary grp breaks that flow and it's members are populated
+     * by pk_group_id_from_group(). As such mbedtls_ecp_group_free()
+     * which is assuming a group populated by _setup() may not clean-up
+     * properly -> Manually free it's members.
+     */
+    mbedtls_mpi_free(&grp.N);
+    mbedtls_mpi_free(&grp.P);
+    mbedtls_mpi_free(&grp.A);
+    mbedtls_mpi_free(&grp.B);
+    mbedtls_ecp_point_free(&grp.G);
 
     return ret;
 }
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 0a8949f..a683fdb 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -5168,6 +5168,18 @@
     (void) alg;
     return PSA_ERROR_NOT_SUPPORTED;
 }
+
+static int psa_key_derivation_allows_free_form_secret_input(
+    psa_algorithm_t kdf_alg)
+{
+#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
+    if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
+        return 0;
+    }
+#endif
+    (void) kdf_alg;
+    return 1;
+}
 #endif /* AT_LEAST_ONE_BUILTIN_KDF */
 
 psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation,
@@ -5189,6 +5201,9 @@
         if (status != PSA_SUCCESS) {
             return status;
         }
+        if (!psa_key_derivation_allows_free_form_secret_input(kdf_alg)) {
+            return PSA_ERROR_INVALID_ARGUMENT;
+        }
         status = psa_key_derivation_setup_kdf(operation, kdf_alg);
 #else
         return PSA_ERROR_NOT_SUPPORTED;
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index febd0e6..4f23395 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -52,14 +52,11 @@
 {
     memset(ctx, 0, sizeof(mbedtls_x509write_cert));
 
-    mbedtls_mpi_init(&ctx->serial);
     ctx->version = MBEDTLS_X509_CRT_VERSION_3;
 }
 
 void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx)
 {
-    mbedtls_mpi_free(&ctx->serial);
-
     mbedtls_asn1_free_named_data_list(&ctx->subject);
     mbedtls_asn1_free_named_data_list(&ctx->issuer);
     mbedtls_asn1_free_named_data_list(&ctx->extensions);
@@ -103,17 +100,42 @@
     return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name);
 }
 
+#if defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
 int mbedtls_x509write_crt_set_serial(mbedtls_x509write_cert *ctx,
                                      const mbedtls_mpi *serial)
 {
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    int ret;
+    size_t tmp_len;
 
-    if ((ret = mbedtls_mpi_copy(&ctx->serial, serial)) != 0) {
+    /* Ensure that the MPI value fits into the buffer */
+    tmp_len = mbedtls_mpi_size(serial);
+    if (tmp_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) {
+        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
+    }
+
+    ctx->serial_len = tmp_len;
+
+    ret = mbedtls_mpi_write_binary(serial, ctx->serial, tmp_len);
+    if (ret < 0) {
         return ret;
     }
 
     return 0;
 }
+#endif // MBEDTLS_BIGNUM_C && !MBEDTLS_DEPRECATED_REMOVED
+
+int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx,
+                                         unsigned char *serial, size_t serial_len)
+{
+    if (serial_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) {
+        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
+    }
+
+    ctx->serial_len = serial_len;
+    memcpy(ctx->serial, serial, serial_len);
+
+    return 0;
+}
 
 int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx,
                                        const char *not_before,
@@ -510,9 +532,29 @@
 
     /*
      *  Serial   ::=  INTEGER
+     *
+     * Written data is:
+     * - "ctx->serial_len" bytes for the raw serial buffer
+     *   - if MSb of "serial" is 1, then prepend an extra 0x00 byte
+     * - 1 byte for the length
+     * - 1 byte for the TAG
      */
-    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&c, buf,
-                                                     &ctx->serial));
+    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf,
+                                                            ctx->serial, ctx->serial_len));
+    if (*c & 0x80) {
+        if (c - buf < 1) {
+            return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
+        }
+        *(--c) = 0x0;
+        len++;
+        MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf,
+                                                         ctx->serial_len + 1));
+    } else {
+        MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf,
+                                                         ctx->serial_len));
+    }
+    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf,
+                                                     MBEDTLS_ASN1_INTEGER));
 
     /*
      *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index 3e134dd..287dd34 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -43,10 +43,12 @@
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/md.h"
 #include "mbedtls/error.h"
+#include "test/helpers.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
 #define SET_OID(x, oid) \
     do { x.len = MBEDTLS_OID_SIZE(oid); x.p = (unsigned char *) oid; } while (0)
@@ -75,6 +77,7 @@
 #define DFL_NOT_BEFORE          "20010101000000"
 #define DFL_NOT_AFTER           "20301231235959"
 #define DFL_SERIAL              "1"
+#define DFL_SERIAL_HEX          "1"
 #define DFL_SELFSIGN            0
 #define DFL_IS_CA               0
 #define DFL_MAX_PATHLEN         -1
@@ -110,6 +113,13 @@
     "    issuer_pwd=%%s           default: (empty)\n"       \
     "    output_file=%%s          default: cert.crt\n"      \
     "    serial=%%s               default: 1\n"             \
+    "                            In decimal format; it can be used as\n"     \
+    "                            alternative to serial_hex, but it's\n"      \
+    "                            limited in max length to\n"                 \
+    "                            unsigned long long int\n"                   \
+    "    serial_hex=%%s           default: 1\n"             \
+    "                            In hex format; it can be used as\n"         \
+    "                            alternative to serial\n"                    \
     "    not_before=%%s           default: 20010101000000\n" \
     "    not_after=%%s            default: 20301231235959\n" \
     "    is_ca=%%d                default: 0 (disabled)\n"  \
@@ -159,6 +169,11 @@
     "   format=pem|der           default: pem\n"         \
     "\n"
 
+typedef enum {
+    SERIAL_FRMT_UNSPEC,
+    SERIAL_FRMT_DEC,
+    SERIAL_FRMT_HEX
+} serial_format_t;
 
 /*
  * global options
@@ -175,7 +190,8 @@
     const char *issuer_name;    /* issuer name for certificate          */
     const char *not_before;     /* validity period not before           */
     const char *not_after;      /* validity period not after            */
-    const char *serial;         /* serial number string                 */
+    const char *serial;         /* serial number string (decimal)       */
+    const char *serial_hex;     /* serial number string (hex)           */
     int selfsign;               /* selfsign the certificate             */
     int is_ca;                  /* is a CA certificate                  */
     int max_pathlen;            /* maximum CA path length               */
@@ -235,6 +251,44 @@
     return 0;
 }
 
+int parse_serial_decimal_format(unsigned char *obuf, size_t obufmax,
+                                const char *ibuf, size_t *len)
+{
+    unsigned long long int dec;
+    unsigned int remaining_bytes = sizeof(dec);
+    unsigned char *p = obuf;
+    unsigned char val;
+    char *end_ptr = NULL;
+
+    errno = 0;
+    dec = strtoull(ibuf, &end_ptr, 10);
+
+    if ((errno != 0) || (end_ptr == ibuf)) {
+        return -1;
+    }
+
+    *len = 0;
+
+    while (remaining_bytes > 0) {
+        if (obufmax < (*len + 1)) {
+            return -1;
+        }
+
+        val = (dec >> ((remaining_bytes - 1) * 8)) & 0xFF;
+
+        /* Skip leading zeros */
+        if ((val != 0) || (*len != 0)) {
+            *p = val;
+            (*len)++;
+            p++;
+        }
+
+        remaining_bytes--;
+    }
+
+    return 0;
+}
+
 int main(int argc, char *argv[])
 {
     int ret = 1;
@@ -252,7 +306,9 @@
     mbedtls_x509_csr csr;
 #endif
     mbedtls_x509write_cert crt;
-    mbedtls_mpi serial;
+    serial_format_t serial_frmt = SERIAL_FRMT_UNSPEC;
+    unsigned char serial[MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN];
+    size_t serial_len;
     mbedtls_asn1_sequence *ext_key_usage;
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
@@ -264,7 +320,6 @@
     mbedtls_x509write_crt_init(&crt);
     mbedtls_pk_init(&loaded_issuer_key);
     mbedtls_pk_init(&loaded_subject_key);
-    mbedtls_mpi_init(&serial);
     mbedtls_ctr_drbg_init(&ctr_drbg);
     mbedtls_entropy_init(&entropy);
 #if defined(MBEDTLS_X509_CSR_PARSE_C)
@@ -272,6 +327,7 @@
 #endif
     mbedtls_x509_crt_init(&issuer_crt);
     memset(buf, 0, sizeof(buf));
+    memset(serial, 0, sizeof(serial));
 
     if (argc == 0) {
 usage:
@@ -291,6 +347,7 @@
     opt.not_before          = DFL_NOT_BEFORE;
     opt.not_after           = DFL_NOT_AFTER;
     opt.serial              = DFL_SERIAL;
+    opt.serial_hex          = DFL_SERIAL_HEX;
     opt.selfsign            = DFL_SELFSIGN;
     opt.is_ca               = DFL_IS_CA;
     opt.max_pathlen         = DFL_MAX_PATHLEN;
@@ -335,7 +392,19 @@
         } else if (strcmp(p, "not_after") == 0) {
             opt.not_after = q;
         } else if (strcmp(p, "serial") == 0) {
+            if (serial_frmt != SERIAL_FRMT_UNSPEC) {
+                mbedtls_printf("Invalid attempt to set the serial more than once\n");
+                goto usage;
+            }
+            serial_frmt = SERIAL_FRMT_DEC;
             opt.serial = q;
+        } else if (strcmp(p, "serial_hex") == 0) {
+            if (serial_frmt != SERIAL_FRMT_UNSPEC) {
+                mbedtls_printf("Invalid attempt to set the serial more than once\n");
+                goto usage;
+            }
+            serial_frmt = SERIAL_FRMT_HEX;
+            opt.serial_hex = q;
         } else if (strcmp(p, "authority_identifier") == 0) {
             opt.authority_identifier = atoi(q);
             if (opt.authority_identifier != 0 &&
@@ -514,10 +583,16 @@
     mbedtls_printf("  . Reading serial number...");
     fflush(stdout);
 
-    if ((ret = mbedtls_mpi_read_string(&serial, 10, opt.serial)) != 0) {
-        mbedtls_strerror(ret, buf, sizeof(buf));
-        mbedtls_printf(" failed\n  !  mbedtls_mpi_read_string "
-                       "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
+    if (serial_frmt == SERIAL_FRMT_HEX) {
+        ret = mbedtls_test_unhexify(serial, sizeof(serial),
+                                    opt.serial_hex, &serial_len);
+    } else { // SERIAL_FRMT_DEC || SERIAL_FRMT_UNSPEC
+        ret = parse_serial_decimal_format(serial, sizeof(serial),
+                                          opt.serial, &serial_len);
+    }
+
+    if (ret != 0) {
+        mbedtls_printf(" failed\n  !  Unable to parse serial\n");
         goto exit;
     }
 
@@ -661,10 +736,10 @@
     mbedtls_x509write_crt_set_version(&crt, opt.version);
     mbedtls_x509write_crt_set_md_alg(&crt, opt.md);
 
-    ret = mbedtls_x509write_crt_set_serial(&crt, &serial);
+    ret = mbedtls_x509write_crt_set_serial_raw(&crt, serial, serial_len);
     if (ret != 0) {
         mbedtls_strerror(ret, buf, sizeof(buf));
-        mbedtls_printf(" failed\n  !  mbedtls_x509write_crt_set_serial "
+        mbedtls_printf(" failed\n  !  mbedtls_x509write_crt_set_serial_raw "
                        "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
         goto exit;
     }
@@ -807,7 +882,6 @@
     mbedtls_x509write_crt_free(&crt);
     mbedtls_pk_free(&loaded_subject_key);
     mbedtls_pk_free(&loaded_issuer_key);
-    mbedtls_mpi_free(&serial);
     mbedtls_ctr_drbg_free(&ctr_drbg);
     mbedtls_entropy_free(&entropy);
 
diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py
index f9d9899..d197b54 100644
--- a/scripts/mbedtls_dev/bignum_mod_raw.py
+++ b/scripts/mbedtls_dev/bignum_mod_raw.py
@@ -51,6 +51,37 @@
         result = (self.int_a - self.int_b) % self.int_n
         return [self.format_result(result)]
 
+class BignumModRawFixQuasiReduction(bignum_common.ModOperationCommon,
+                                    BignumModRawTarget):
+    """Test cases for ecp quasi_reduction()."""
+    symbol = "-"
+    test_function = "mpi_mod_raw_fix_quasi_reduction"
+    test_name = "fix_quasi_reduction"
+    input_style = "fixed"
+    arity = 1
+
+    # Extend the default values with n < x < 2n
+    input_values = bignum_common.ModOperationCommon.input_values + [
+        "73",
+
+        # First number generated by random.getrandbits(1024) - seed(3,2)
+        "ea7b5bf55eb561a4216363698b529b4a97b750923ceb3ffd",
+
+        # First number generated by random.getrandbits(1024) - seed(1,2)
+        ("cd447e35b8b6d8fe442e3d437204e52db2221a58008a05a6c4647159c324c985"
+         "9b810e766ec9d28663ca828dd5f4b3b2e4b06ce60741c7a87ce42c8218072e8c"
+         "35bf992dc9e9c616612e7696a6cecc1b78e510617311d8a3c2ce6f447ed4d57b"
+         "1e2feb89414c343c1027c4d1c386bbc4cd613e30d8f16adf91b7584a2265b1f5")
+    ] # type: List[str]
+
+    def result(self) -> List[str]:
+        result = self.int_a % self.int_n
+        return [self.format_result(result)]
+
+    @property
+    def is_valid(self) -> bool:
+        return bool(self.int_a < 2 * self.int_n)
+
 class BignumModRawMul(bignum_common.ModOperationCommon,
                       BignumModRawTarget):
     """Test cases for bignum mpi_mod_raw_mul()."""
diff --git a/scripts/mbedtls_dev/crypto_knowledge.py b/scripts/mbedtls_dev/crypto_knowledge.py
index 1a03321..819d92a 100644
--- a/scripts/mbedtls_dev/crypto_knowledge.py
+++ b/scripts/mbedtls_dev/crypto_knowledge.py
@@ -20,7 +20,7 @@
 
 import enum
 import re
-from typing import FrozenSet, Iterable, List, Optional, Tuple
+from typing import FrozenSet, Iterable, List, Optional, Tuple, Dict
 
 from .asymmetric_key_data import ASYMMETRIC_KEY_DATA
 
@@ -148,7 +148,7 @@
         'PSA_ECC_FAMILY_BRAINPOOL_P_R1': (160, 192, 224, 256, 320, 384, 512),
         'PSA_ECC_FAMILY_MONTGOMERY': (255, 448),
         'PSA_ECC_FAMILY_TWISTED_EDWARDS': (255, 448),
-    }
+    } # type: Dict[str, Tuple[int, ...]]
     KEY_TYPE_SIZES = {
         'PSA_KEY_TYPE_AES': (128, 192, 256), # exhaustive
         'PSA_KEY_TYPE_ARIA': (128, 192, 256), # exhaustive
@@ -162,7 +162,7 @@
         'PSA_KEY_TYPE_PEPPER': (128, 256), # sample
         'PSA_KEY_TYPE_RAW_DATA': (8, 40, 128), # sample
         'PSA_KEY_TYPE_RSA_KEY_PAIR': (1024, 1536), # small sample
-    }
+    } # type: Dict[str, Tuple[int, ...]]
     def sizes_to_test(self) -> Tuple[int, ...]:
         """Return a tuple of key sizes to test.
 
@@ -214,9 +214,7 @@
         This function does not currently handle key derivation or PAKE.
         """
         #pylint: disable=too-many-branches,too-many-return-statements
-        if alg.is_wildcard:
-            return False
-        if alg.is_invalid_truncation():
+        if not alg.is_valid_for_operation():
             return False
         if self.head == 'HMAC' and alg.head == 'HMAC':
             return True
@@ -248,6 +246,8 @@
             # So a public key object with a key agreement algorithm is not
             # a valid combination.
             return False
+        if alg.is_invalid_key_agreement_with_derivation():
+            return False
         if self.head == 'ECC':
             assert self.params is not None
             eccc = EllipticCurveCategory.from_family(self.params[0])
@@ -414,17 +414,38 @@
         self.category = self.determine_category(self.base_expression, self.head)
         self.is_wildcard = self.determine_wildcard(self.expression)
 
-    def is_key_agreement_with_derivation(self) -> bool:
-        """Whether this is a combined key agreement and key derivation algorithm."""
+    def get_key_agreement_derivation(self) -> Optional[str]:
+        """For a combined key agreement and key derivation algorithm, get the derivation part.
+
+        For anything else, return None.
+        """
         if self.category != AlgorithmCategory.KEY_AGREEMENT:
-            return False
+            return None
         m = re.match(r'PSA_ALG_KEY_AGREEMENT\(\w+,\s*(.*)\)\Z', self.expression)
         if not m:
-            return False
+            return None
         kdf_alg = m.group(1)
         # Assume kdf_alg is either a valid KDF or 0.
-        return not re.match(r'(?:0[Xx])?0+\s*\Z', kdf_alg)
+        if re.match(r'(?:0[Xx])?0+\s*\Z', kdf_alg):
+            return None
+        return kdf_alg
 
+    KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT = frozenset([
+        'PSA_ALG_TLS12_ECJPAKE_TO_PMS', # secret input in specific format
+    ])
+    def is_valid_key_agreement_with_derivation(self) -> bool:
+        """Whether this is a valid combined key agreement and key derivation algorithm."""
+        kdf_alg = self.get_key_agreement_derivation()
+        if kdf_alg is None:
+            return False
+        return kdf_alg not in self.KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT
+
+    def is_invalid_key_agreement_with_derivation(self) -> bool:
+        """Whether this is an invalid combined key agreement and key derivation algorithm."""
+        kdf_alg = self.get_key_agreement_derivation()
+        if kdf_alg is None:
+            return False
+        return kdf_alg in self.KEY_DERIVATIONS_INCOMPATIBLE_WITH_AGREEMENT
 
     def short_expression(self, level: int = 0) -> str:
         """Abbreviate the expression, keeping it human-readable.
@@ -498,13 +519,26 @@
                 return True
         return False
 
+    def is_valid_for_operation(self) -> bool:
+        """Whether this algorithm construction is valid for an operation.
+
+        This function assumes that the algorithm is constructed in a
+        "grammatically" correct way, and only rejects semantically invalid
+        combinations.
+        """
+        if self.is_wildcard:
+            return False
+        if self.is_invalid_truncation():
+            return False
+        return True
+
     def can_do(self, category: AlgorithmCategory) -> bool:
         """Whether this algorithm can perform operations in the given category.
         """
         if category == self.category:
             return True
         if category == AlgorithmCategory.KEY_DERIVATION and \
-           self.is_key_agreement_with_derivation():
+           self.is_valid_key_agreement_with_derivation():
             return True
         return False
 
diff --git a/tests/compat.sh b/tests/compat.sh
index 1454fec..7693400 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -753,15 +753,17 @@
     echo "$SERVER_CMD" > $SRV_OUT
     # for servers without -www or equivalent
     while :; do echo bla; sleep 1; done | $SERVER_CMD >> $SRV_OUT 2>&1 &
-    PROCESS_ID=$!
+    SRV_PID=$!
 
-    wait_server_start "$PORT" "$PROCESS_ID"
+    wait_server_start "$PORT" "$SRV_PID"
 }
 
 # terminate the running server
 stop_server() {
-    kill $PROCESS_ID 2>/dev/null
-    wait $PROCESS_ID 2>/dev/null
+    # For Ubuntu 22.04, `Terminated` message is outputed by wait command.
+    # To remove it from stdout, redirect stdout/stderr to SRV_OUT
+    kill $SRV_PID >/dev/null 2>&1
+    wait $SRV_PID >> $SRV_OUT 2>&1
 
     if [ "$MEMCHECK" -gt 0 ]; then
         if is_mbedtls "$SERVER_CMD" && has_mem_err $SRV_OUT; then
@@ -777,7 +779,7 @@
 # kill the running server (used when killed by signal)
 cleanup() {
     rm -f $SRV_OUT $CLI_OUT
-    kill $PROCESS_ID >/dev/null 2>&1
+    kill $SRV_PID >/dev/null 2>&1
     kill $WATCHDOG_PID >/dev/null 2>&1
     exit 1
 }
@@ -790,11 +792,13 @@
     ( sleep "$DOG_DELAY"; echo "TIMEOUT" >> $CLI_OUT; kill $CLI_PID ) &
     WATCHDOG_PID=$!
 
-    wait $CLI_PID
+    # For Ubuntu 22.04, `Terminated` message is outputed by wait command.
+    # To remove it from stdout, redirect stdout/stderr to CLI_OUT
+    wait $CLI_PID >> $CLI_OUT 2>&1
     EXIT=$?
 
-    kill $WATCHDOG_PID
-    wait $WATCHDOG_PID
+    kill $WATCHDOG_PID >/dev/null 2>&1
+    wait $WATCHDOG_PID >> $CLI_OUT 2>&1
 
     echo "EXIT: $EXIT" >> $CLI_OUT
 }
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 388b0ce..9c7a95d 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -972,6 +972,15 @@
 
 server1.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
 	$(MBEDTLS_CERT_WRITE) request_file=server1.req.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
+server1.long_serial.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+	echo "112233445566778899aabbccddeeff0011223344" > test-ca.server1.tmp.serial
+	$(OPENSSL) ca -in server1.req.sha256 -key PolarSSLTest -config test-ca.server1.test_serial.opensslconf -notext -batch -out $@
+server1.80serial.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+	echo "8011223344" > test-ca.server1.tmp.serial
+	$(OPENSSL) ca -in server1.req.sha256 -key PolarSSLTest -config test-ca.server1.test_serial.opensslconf -notext -batch -out $@
+server1.long_serial_FF.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+	echo "ffffffffffffffffffffffffffffffff" > test-ca.server1.tmp.serial
+	$(OPENSSL) ca -in server1.req.sha256 -key PolarSSLTest -config test-ca.server1.test_serial.opensslconf -notext -batch -out $@
 server1.noauthid.crt: server1.key server1.req.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
 	$(MBEDTLS_CERT_WRITE) request_file=server1.req.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20190210144406 not_after=20290210144406 md=SHA1 authority_identifier=0 version=3 output_file=$@
 server1.crt.der: server1.crt
diff --git a/tests/data_files/server1.80serial.crt b/tests/data_files/server1.80serial.crt
new file mode 100644
index 0000000..3ce8570
--- /dev/null
+++ b/tests/data_files/server1.80serial.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDRDCCAiygAwIBAgIGAIARIjNEMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
+Ak5MMREwDwYDVQQKDAhQb2xhclNTTDEZMBcGA1UEAwwQUG9sYXJTU0wgVGVzdCBD
+QTAeFw0xOTAyMTAxNDQ0MDZaFw0yOTAyMTAxNDQ0MDZaMDwxCzAJBgNVBAYTAk5M
+MREwDwYDVQQKDAhQb2xhclNTTDEaMBgGA1UEAwwRUG9sYXJTU0wgU2VydmVyIDEw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpAh89QGrVVVOL/TbugmUu
+FWFeib+46EWQ2+6IFlLT8UNQR5YSWWSHa/0r4Eb5c77dz5LhkVvtZqBviSl5RYDQ
+g2rVQUN3Xzl8CQRHgrBXOXDto+wVGR6oMwhHwQVCqf1Mw7Tf3QYfTRBRQGdzEw9A
++G2BJV8KsVPGMH4VOaz5Wu5/kp6mBVvnE5eFtSOS2dQkBtUJJYl1B92mGo8/CRm+
+rWUsZOuVm9z+QV4XptpsW2nMAroULBYknErczdD3Umdz8S2gI/1+9DHKLXDKiQsE
+2y6mT3Buns69WIniU1meblqSZeKIPwyUGaPd5eidlRPtKdurcBLcWsprF6tSglSx
+AgMBAAGjTTBLMAkGA1UdEwQCMAAwHQYDVR0OBBYEFB901j8pwXR0RTsFEiw9qL1D
+WQKmMB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEB
+BQUAA4IBAQBJKeTUCctb/wCxBte2AIiaTfATzukTVtGhKkdy3cY6U2DVSXc+s+jr
+Kut8AYnjp1T6bho98RHbbk+hu+0gBWL2ysJd1+slLBUEotUMTkzgA1YdBXy9J/eM
+HJ2a0ydFll/m2rXx7RRJWSbcgPZxQLDfollnNVfhcb75O3GsT3YfEIsjLmon7NHr
+rJmTp773trg0cNJ6j5dKMA/2SQH5PL1cmcFgNfVZ+etNRIhwpIQYySWJ/468Mcg5
+ZKPY6nubIIj+HPB3Mhy8d9U3gAJvc9iEdzbKjrkJdVROONsyMYge4vnbjyKUr7/m
+ZN1O6pZy9Fvgbdhvx4ZHpfgEsa1qfLCH
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server1.long_serial.crt b/tests/data_files/server1.long_serial.crt
new file mode 100644
index 0000000..1bd6955
--- /dev/null
+++ b/tests/data_files/server1.long_serial.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDUjCCAjqgAwIBAgIUESIzRFVmd4iZqrvM3e7/ABEiM0QwDQYJKoZIhvcNAQEF
+BQAwOzELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRkwFwYDVQQDDBBQ
+b2xhclNTTCBUZXN0IENBMB4XDTE5MDIxMDE0NDQwNloXDTI5MDIxMDE0NDQwNlow
+PDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRowGAYDVQQDDBFQb2xh
+clNTTCBTZXJ2ZXIgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkC
+Hz1AatVVU4v9Nu6CZS4VYV6Jv7joRZDb7ogWUtPxQ1BHlhJZZIdr/SvgRvlzvt3P
+kuGRW+1moG+JKXlFgNCDatVBQ3dfOXwJBEeCsFc5cO2j7BUZHqgzCEfBBUKp/UzD
+tN/dBh9NEFFAZ3MTD0D4bYElXwqxU8YwfhU5rPla7n+SnqYFW+cTl4W1I5LZ1CQG
+1QkliXUH3aYajz8JGb6tZSxk65Wb3P5BXhem2mxbacwCuhQsFiScStzN0PdSZ3Px
+LaAj/X70McotcMqJCwTbLqZPcG6ezr1YieJTWZ5uWpJl4og/DJQZo93l6J2VE+0p
+26twEtxaymsXq1KCVLECAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUH3TW
+PynBdHRFOwUSLD2ovUNZAqYwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH
+/f8wDQYJKoZIhvcNAQEFBQADggEBAC9qt4BC8zKb5o00ZVtTX0XYKWchHKYSrHk2
+r+zfW8pRcSaTGRTtMGkF7vozFrCX4Pr4vCKXOYFKQ/UEpWv5WzW7nB0+Ja0g4gnc
+9bLtg51n+IIG93ITGDm5+9YpsX6HsXSBpfY0vo9TwKg3bG1X26WG8j6m+V684hwV
+yveRUIrSvvgVJOBSe5rhn/pLmcpbI0nkPBGlqPd10qWc0RYSrSAa3bq/dpoqR7hY
+BGbbV1/9IgFhr2r44R17bhqevK3VhK4KOPRT5VMXjTh1iG4L13lIxBIuu+Lw0Pc0
+s+gQTGntA/sZkijC7mw0/q3nsRDKhHHXTDf2gjdUhMvFwYzmKBI=
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server1.long_serial_FF.crt b/tests/data_files/server1.long_serial_FF.crt
new file mode 100644
index 0000000..8094fd7
--- /dev/null
+++ b/tests/data_files/server1.long_serial_FF.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDTzCCAjegAwIBAgIRAP////////////////////8wDQYJKoZIhvcNAQEFBQAw
+OzELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRkwFwYDVQQDDBBQb2xh
+clNTTCBUZXN0IENBMB4XDTE5MDIxMDE0NDQwNloXDTI5MDIxMDE0NDQwNlowPDEL
+MAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRowGAYDVQQDDBFQb2xhclNT
+TCBTZXJ2ZXIgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkCHz1A
+atVVU4v9Nu6CZS4VYV6Jv7joRZDb7ogWUtPxQ1BHlhJZZIdr/SvgRvlzvt3PkuGR
+W+1moG+JKXlFgNCDatVBQ3dfOXwJBEeCsFc5cO2j7BUZHqgzCEfBBUKp/UzDtN/d
+Bh9NEFFAZ3MTD0D4bYElXwqxU8YwfhU5rPla7n+SnqYFW+cTl4W1I5LZ1CQG1Qkl
+iXUH3aYajz8JGb6tZSxk65Wb3P5BXhem2mxbacwCuhQsFiScStzN0PdSZ3PxLaAj
+/X70McotcMqJCwTbLqZPcG6ezr1YieJTWZ5uWpJl4og/DJQZo93l6J2VE+0p26tw
+EtxaymsXq1KCVLECAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUH3TWPynB
+dHRFOwUSLD2ovUNZAqYwHwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8w
+DQYJKoZIhvcNAQEFBQADggEBADYfhZU2lWxBamt7m3A4XQj6bZ4BZlabv5IbLI32
+nej6w/6/gsXPI85nfZqpIn6IYwAeDRdJo/eUqYkIdoy5DEP+50pgCGJK5HAoBWVJ
+THKeVJn/vPH3Dz/CaCYQoHTmSi+ChfIhPh84UUdfVpv2qNInII4RxFlSAHUkRMbV
+BX6imMSD5M508G6vWGUUc6G/sx/s7vtVeGGPyNOQPgwMTes60Mewpu9LKKaSwfqQ
+DgEa8WzxPrPEyOUiIp7ClwlXe3JECHIjm445qmENgfY/8tlsyAdYKSkotfiuoUWb
+daylD6QVUXn67loYDPZALghpDxmSm21VE7feTWOUbOpe14U=
+-----END CERTIFICATE-----
diff --git a/tests/data_files/test-ca.server1.test_serial.opensslconf b/tests/data_files/test-ca.server1.test_serial.opensslconf
new file mode 100644
index 0000000..43a520e
--- /dev/null
+++ b/tests/data_files/test-ca.server1.test_serial.opensslconf
@@ -0,0 +1,25 @@
+ [ ca ]
+ default_ca             = test-ca
+
+ [ test-ca ]
+ certificate            = test-ca.crt
+ private_key            = test-ca.key
+ serial                 = test-ca.server1.tmp.serial
+ default_md             = sha1
+ default_startdate      = 20190210144406Z
+ default_enddate        = 20290210144406Z
+ x509_extensions        = v3_ca
+ new_certs_dir          = ./
+ database               = ./test-ca.server1.db
+ policy                 = policy_match
+ unique_subject         = no
+
+ [v3_ca]
+ basicConstraints = CA:false
+ subjectKeyIdentifier=hash
+ authorityKeyIdentifier=keyid:always
+
+ [policy_match]
+ countryName            = supplied
+ organizationName       = supplied
+ commonName             = supplied
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 2221d59..883d58b 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1768,6 +1768,9 @@
 
     msg "test: make, full_no_deprecated config" # ~ 5s
     make test
+
+    msg "test: ensure that X509 has no direct dependency on BIGNUM_C"
+    not grep mbedtls_mpi library/libmbedx509.a
 }
 
 component_test_full_no_deprecated_deprecated_warning () {
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
index 7398f3c..e6a38ba 100755
--- a/tests/scripts/check_names.py
+++ b/tests/scripts/check_names.py
@@ -268,13 +268,13 @@
             "3rdparty/everest/include/everest/everest.h",
             "3rdparty/everest/include/everest/x25519.h"
         ])
-        identifiers = self.parse_identifiers([
+        identifiers, excluded_identifiers = self.parse_identifiers([
             "include/mbedtls/*.h",
             "include/psa/*.h",
             "library/*.h",
             "3rdparty/everest/include/everest/everest.h",
             "3rdparty/everest/include/everest/x25519.h"
-        ])
+        ], ["3rdparty/p256-m/p256-m/p256-m.h"])
         mbed_psa_words = self.parse_mbed_psa_words([
             "include/mbedtls/*.h",
             "include/psa/*.h",
@@ -311,6 +311,7 @@
             "private_macros": all_macros["private"],
             "enum_consts": enum_consts,
             "identifiers": identifiers,
+            "excluded_identifiers": excluded_identifiers,
             "symbols": symbols,
             "mbed_psa_words": mbed_psa_words
         }
@@ -324,12 +325,42 @@
                 return True
         return False
 
-    def get_files(self, include_wildcards, exclude_wildcards):
+    def get_all_files(self, include_wildcards, exclude_wildcards):
         """
-        Get all files that match any of the UNIX-style wildcards. While the
-        check_names script is designed only for use on UNIX/macOS (due to nm),
-        this function alone would work fine on Windows even with forward slashes
-        in the wildcard.
+        Get all files that match any of the included UNIX-style wildcards
+        and filter them into included and excluded lists.
+        While the check_names script is designed only for use on UNIX/macOS
+        (due to nm), this function alone will work fine on Windows even with
+        forward slashes in the wildcard.
+
+        Args:
+        * include_wildcards: a List of shell-style wildcards to match filepaths.
+        * exclude_wildcards: a List of shell-style wildcards to exclude.
+
+        Returns:
+        * inc_files: A List of relative filepaths for included files.
+        * exc_files: A List of relative filepaths for excluded files.
+        """
+        accumulator = set()
+        all_wildcards = include_wildcards + (exclude_wildcards or [])
+        for wildcard in all_wildcards:
+            accumulator = accumulator.union(glob.iglob(wildcard))
+
+        inc_files = []
+        exc_files = []
+        for path in accumulator:
+            if self.is_file_excluded(path, exclude_wildcards):
+                exc_files.append(path)
+            else:
+                inc_files.append(path)
+        return (inc_files, exc_files)
+
+    def get_included_files(self, include_wildcards, exclude_wildcards):
+        """
+        Get all files that match any of the included UNIX-style wildcards.
+        While the check_names script is designed only for use on UNIX/macOS
+        (due to nm), this function alone will work fine on Windows even with
+        forward slashes in the wildcard.
 
         Args:
         * include_wildcards: a List of shell-style wildcards to match filepaths.
@@ -360,7 +391,7 @@
             "asm", "inline", "EMIT", "_CRT_SECURE_NO_DEPRECATE", "MULADDC_"
         )
 
-        files = self.get_files(include, exclude)
+        files = self.get_included_files(include, exclude)
         self.log.debug("Looking for macros in {} files".format(len(files)))
 
         macros = []
@@ -395,7 +426,7 @@
         mbed_regex = re.compile(r"\b(MBED.+?|PSA)_[A-Z0-9_]*")
         exclusions = re.compile(r"// *no-check-names|#error")
 
-        files = self.get_files(include, exclude)
+        files = self.get_included_files(include, exclude)
         self.log.debug(
             "Looking for MBED|PSA words in {} files"
             .format(len(files))
@@ -428,7 +459,7 @@
 
         Returns a List of Match objects for the findings.
         """
-        files = self.get_files(include, exclude)
+        files = self.get_included_files(include, exclude)
         self.log.debug("Looking for enum consts in {} files".format(len(files)))
 
         # Emulate a finite state machine to parse enum declarations.
@@ -611,23 +642,34 @@
         """
         Parse all lines of a header where a function/enum/struct/union/typedef
         identifier is declared, based on some regex and heuristics. Highly
-        dependent on formatting style.
+        dependent on formatting style. Identifiers in excluded files are still
+        parsed
 
         Args:
         * include: A List of glob expressions to look for files through.
         * exclude: A List of glob expressions for excluding files.
 
-        Returns a List of Match objects with identifiers.
+        Returns: a Tuple of two Lists of Match objects with identifiers.
+        * included_identifiers: A List of Match objects with identifiers from
+          included files.
+        * excluded_identifiers: A List of Match objects with identifiers from
+          excluded files.
         """
 
-        files = self.get_files(include, exclude)
-        self.log.debug("Looking for identifiers in {} files".format(len(files)))
+        included_files, excluded_files = \
+            self.get_all_files(include, exclude)
 
-        identifiers = []
-        for header_file in files:
-            self.parse_identifiers_in_file(header_file, identifiers)
+        self.log.debug("Looking for included identifiers in {} files".format \
+            (len(included_files)))
 
-        return identifiers
+        included_identifiers = []
+        excluded_identifiers = []
+        for header_file in included_files:
+            self.parse_identifiers_in_file(header_file, included_identifiers)
+        for header_file in excluded_files:
+            self.parse_identifiers_in_file(header_file, excluded_identifiers)
+
+        return (included_identifiers, excluded_identifiers)
 
     def parse_symbols(self):
         """
@@ -789,10 +831,12 @@
         Returns the number of problems that need fixing.
         """
         problems = []
+        all_identifiers = self.parse_result["identifiers"] +  \
+            self.parse_result["excluded_identifiers"]
 
         for symbol in self.parse_result["symbols"]:
             found_symbol_declared = False
-            for identifier_match in self.parse_result["identifiers"]:
+            for identifier_match in all_identifiers:
                 if symbol == identifier_match.name:
                     found_symbol_declared = True
                     break
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index b271048..752e7ca 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -151,14 +151,16 @@
     tc.set_arguments([key_type] + list(args))
     return tc
 
-class NotSupported:
-    """Generate test cases for when something is not supported."""
+class KeyTypeNotSupported:
+    """Generate test cases for when a key type is not supported."""
 
     def __init__(self, info: Information) -> None:
         self.constructors = info.constructors
 
     ALWAYS_SUPPORTED = frozenset([
         'PSA_KEY_TYPE_DERIVE',
+        'PSA_KEY_TYPE_PASSWORD',
+        'PSA_KEY_TYPE_PASSWORD_HASH',
         'PSA_KEY_TYPE_RAW_DATA',
         'PSA_KEY_TYPE_HMAC'
     ])
@@ -355,7 +357,7 @@
                 dependencies[i] = '!' + dep
         tc.set_dependencies(dependencies)
         tc.set_function(category.name.lower() + '_fail')
-        arguments = []
+        arguments = [] # type: List[str]
         if kt:
             key_material = kt.key_material(kt.sizes_to_test()[0])
             arguments += [key_type, test_case.hex_string(key_material)]
@@ -522,7 +524,7 @@
             key_type: psa_storage.Expr, bits: int,
             alg: psa_storage.Expr
     ) -> bool:
-        """Whether to the given key with the given algorithm.
+        """Whether to exercise the given key with the given algorithm.
 
         Normally only the type and algorithm matter for compatibility, and
         this is handled in crypto_knowledge.KeyType.can_do(). This function
@@ -900,7 +902,7 @@
         'test_suite_psa_crypto_generate_key.generated':
         lambda info: KeyGenerate(info).test_cases_for_key_generation(),
         'test_suite_psa_crypto_not_supported.generated':
-        lambda info: NotSupported(info).test_cases_for_not_supported(),
+        lambda info: KeyTypeNotSupported(info).test_cases_for_not_supported(),
         'test_suite_psa_crypto_op_fail.generated':
         lambda info: OpFail(info).all_test_cases(),
         'test_suite_psa_crypto_storage_format.current':
diff --git a/tests/scripts/list_internal_identifiers.py b/tests/scripts/list_internal_identifiers.py
index 779a16f..6b41607 100755
--- a/tests/scripts/list_internal_identifiers.py
+++ b/tests/scripts/list_internal_identifiers.py
@@ -46,7 +46,7 @@
     result = name_check.parse_identifiers([
         "include/mbedtls/*_internal.h",
         "library/*.h"
-    ])
+    ])[0]
     result.sort(key=lambda x: x.name)
 
     identifiers = ["{}\n".format(match.name) for match in result]
diff --git a/tests/suites/test_suite_bignum_mod_raw.function b/tests/suites/test_suite_bignum_mod_raw.function
index 9310b0e..24ecba3 100644
--- a/tests/suites/test_suite_bignum_mod_raw.function
+++ b/tests/suites/test_suite_bignum_mod_raw.function
@@ -6,6 +6,8 @@
 #include "constant_time_internal.h"
 #include "test/constant_flow.h"
 
+#include "bignum_mod_raw_invasive.h"
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -338,6 +340,56 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
+void mpi_mod_raw_fix_quasi_reduction(char *input_N,
+                                     char *input_X,
+                                     char *result)
+{
+    mbedtls_mpi_uint *X = NULL;
+    mbedtls_mpi_uint *N = NULL;
+    mbedtls_mpi_uint *res = NULL;
+    mbedtls_mpi_uint *tmp = NULL;
+    size_t limbs_X;
+    size_t limbs_N;
+    size_t limbs_res;
+
+    mbedtls_mpi_mod_modulus m;
+    mbedtls_mpi_mod_modulus_init(&m);
+
+    TEST_EQUAL(mbedtls_test_read_mpi_core(&X,   &limbs_X,   input_X), 0);
+    TEST_EQUAL(mbedtls_test_read_mpi_core(&N,   &limbs_N,   input_N), 0);
+    TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result),  0);
+
+    size_t limbs = limbs_N;
+    size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
+
+    TEST_EQUAL(limbs_X,   limbs);
+    TEST_EQUAL(limbs_res, limbs);
+
+    ASSERT_ALLOC(tmp, limbs);
+    memcpy(tmp, X, bytes);
+
+    /* Check that 0 <= X < 2N */
+    mbedtls_mpi_uint c = mbedtls_mpi_core_sub(tmp, X, N, limbs);
+    TEST_ASSERT(c || mbedtls_mpi_core_lt_ct(tmp, N, limbs));
+
+    TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
+                   &m, N, limbs,
+                   MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
+
+    mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
+    ASSERT_COMPARE(X, bytes, res, bytes);
+
+exit:
+    mbedtls_free(X);
+    mbedtls_free(res);
+    mbedtls_free(tmp);
+
+    mbedtls_mpi_mod_modulus_free(&m);
+    mbedtls_free(N);
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void mpi_mod_raw_mul(char *input_A,
                      char *input_B,
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 9311200..9a13793 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -1038,4 +1038,3 @@
 ECP check order for CURVE448
 depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
 ecp_check_order:MBEDTLS_ECP_DP_CURVE448:"3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3"
-
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 9ced77c..c356142 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -5080,6 +5080,22 @@
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
 
+PSA key derivation: TLS12_ECJPAKE_TO_PMS, good input, output too short
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+derive_input:PSA_ALG_TLS12_ECJPAKE_TO_PMS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"04aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_SUCCESS:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_INVALID_ARGUMENT
+
+PSA key derivation: TLS12_ECJPAKE_TO_PMS, input[0]=0x02
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+derive_input:PSA_ALG_TLS12_ECJPAKE_TO_PMS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ERROR_INVALID_ARGUMENT:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS12_ECJPAKE_TO_PMS, input too short
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+derive_input:PSA_ALG_TLS12_ECJPAKE_TO_PMS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"04aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ERROR_INVALID_ARGUMENT:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS12_ECJPAKE_TO_PMS, input too long
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+derive_input:PSA_ALG_TLS12_ECJPAKE_TO_PMS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"04aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ERROR_INVALID_ARGUMENT:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
 PSA key derivation over capacity: HKDF
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 derive_over_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_256)
diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data
index bf5f04e..bbd5017 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.data
+++ b/tests/suites/test_suite_psa_crypto_metadata.data
@@ -118,6 +118,10 @@
 depends_on:PSA_WANT_ALG_XTS:MBEDTLS_CIPHER_C
 cipher_algorithm:PSA_ALG_XTS:0
 
+Cipher: CCM*
+depends_on:PSA_WANT_ALG_CCM_STAR_NO_TAG
+cipher_algorithm:PSA_ALG_CCM_STAR_NO_TAG:ALG_IS_STREAM_CIPHER
+
 AEAD: CCM-AES-128
 depends_on:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_CCM
 aead_algorithm:PSA_ALG_CCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16:PSA_KEY_TYPE_AES:128
@@ -286,6 +290,10 @@
 depends_on:PSA_WANT_ALG_HKDF_EXPAND:PSA_WANT_ALG_SHA_384
 key_derivation_algorithm:PSA_ALG_HKDF_EXPAND( PSA_ALG_SHA_384 ):ALG_IS_HKDF_EXPAND
 
+Key derivation: TLS1.2 ECJPAKE-to-PMS
+depends_on:PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS
+key_derivation_algorithm:PSA_ALG_TLS12_ECJPAKE_TO_PMS:0
+
 Key derivation: TLS 1.2 PRF using SHA-256
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
 key_derivation_algorithm:PSA_ALG_TLS12_PRF( PSA_ALG_SHA_256 ):ALG_IS_TLS12_PRF
@@ -339,6 +347,12 @@
 Key type: secret for key derivation
 key_type:PSA_KEY_TYPE_DERIVE:KEY_TYPE_IS_UNSTRUCTURED
 
+Key type: password
+key_type:PSA_KEY_TYPE_PASSWORD:KEY_TYPE_IS_UNSTRUCTURED
+
+Key type: password hash
+key_type:PSA_KEY_TYPE_PASSWORD_HASH:KEY_TYPE_IS_UNSTRUCTURED
+
 Block cipher key type: AES
 depends_on:PSA_WANT_KEY_TYPE_AES
 block_cipher_key_type:PSA_KEY_TYPE_AES:16
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index c55c9d1..885ba00 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -60,95 +60,107 @@
 
 Certificate write check Server1 SHA1
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.crt":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.crt":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, not before 1970
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"19700210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"19700210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, not after 2050
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20500210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20500210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, not before 1970, not after 2050
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"19700210144406":"20500210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"19700210144406":"20500210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, not before 2050, not after 2059
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20500210144406":"20590210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20500210144406":"20590210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, key_usage
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:"NULL":0:0:1:-1:"data_files/server1.key_usage.crt":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:"NULL":0:0:1:-1:"data_files/server1.key_usage.crt":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, one ext_key_usage
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":MBEDTLS_MD_SHA1:0:0:"serverAuth":0:0:1:-1:"data_files/server1.key_ext_usage.crt":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20110212144406":"20210212144406":MBEDTLS_MD_SHA1:0:0:"serverAuth":0:0:1:-1:"data_files/server1.key_ext_usage.crt":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, two ext_key_usages
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":MBEDTLS_MD_SHA1:0:0:"codeSigning,timeStamping":0:0:1:-1:"data_files/server1.key_ext_usages.crt":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20110212144406":"20210212144406":MBEDTLS_MD_SHA1:0:0:"codeSigning,timeStamping":0:0:1:-1:"data_files/server1.key_ext_usages.crt":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, ns_cert_type
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:1:-1:"data_files/server1.cert_type.crt":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:1:-1:"data_files/server1.cert_type.crt":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, version 1
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":0:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, CA
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.ca.crt":0:1:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.ca.crt":0:1:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, RSA_ALT
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:0:-1:"data_files/server1.noauthid.crt":1:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:0:-1:"data_files/server1.noauthid.crt":1:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, RSA_ALT, key_usage
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:"NULL":0:0:0:-1:"data_files/server1.key_usage_noauthid.crt":1:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:"NULL":0:0:0:-1:"data_files/server1.key_usage_noauthid.crt":1:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, RSA_ALT, ns_cert_type
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:0:-1:"data_files/server1.cert_type_noauthid.crt":1:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:0:-1:"data_files/server1.cert_type_noauthid.crt":1:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, RSA_ALT, version 1
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:0:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":1:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:0:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":1:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, RSA_ALT, CA
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:0:-1:"data_files/server1.ca_noauthid.crt":1:1:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:0:-1:"data_files/server1.ca_noauthid.crt":1:1:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, Opaque
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_USE_PSA_CRYPTO
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.crt":2:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.crt":2:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, Opaque, key_usage
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_USE_PSA_CRYPTO
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:"NULL":0:0:1:-1:"data_files/server1.key_usage.crt":2:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION | MBEDTLS_X509_KU_KEY_ENCIPHERMENT:1:"NULL":0:0:1:-1:"data_files/server1.key_usage.crt":2:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, Opaque, ns_cert_type
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_USE_PSA_CRYPTO
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:1:-1:"data_files/server1.cert_type.crt":2:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER:1:1:-1:"data_files/server1.cert_type.crt":2:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, Opaque, version 1
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_USE_PSA_CRYPTO
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":2:0:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt":2:0:"data_files/test-ca.crt"
 
 Certificate write check Server1 SHA1, Opaque, CA
 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_USE_PSA_CRYPTO
-x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.ca.crt":2:1:"data_files/test-ca.crt"
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.ca.crt":2:1:"data_files/test-ca.crt"
+
+Certificate write check Server1 SHA1, Full length serial
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"112233445566778899aabbccddeeff0011223344":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.long_serial.crt":0:0:"data_files/test-ca.crt"
+
+Certificate write check Server1 SHA1, Serial starting with 0x80
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"8011223344":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.80serial.crt":0:0:"data_files/test-ca.crt"
+
+Certificate write check Server1 SHA1, All 0xFF full length serial
+depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
+x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"ffffffffffffffffffffffffffffffff":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.long_serial_FF.crt":0:0:"data_files/test-ca.crt"
 
 Certificate write check Server5 ECDSA
 depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED
-x509_crt_check:"data_files/server5.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca2.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=Polarssl Test EC CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA256:0:0:"NULL":0:0:1:-1:"data_files/server5.crt":0:0:"data_files/test-ca2.crt"
+x509_crt_check:"data_files/server5.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca2.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=Polarssl Test EC CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA256:0:0:"NULL":0:0:1:-1:"data_files/server5.crt":0:0:"data_files/test-ca2.crt"
 
 Certificate write check Server5 ECDSA, Opaque
 depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_USE_PSA_CRYPTO
-x509_crt_check:"data_files/server5.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca2.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=Polarssl Test EC CA":"1":"20190210144406":"20290210144406":MBEDTLS_MD_SHA256:0:0:"NULL":0:0:1:-1:"":2:0:"data_files/test-ca2.crt"
+x509_crt_check:"data_files/server5.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca2.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=Polarssl Test EC CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA256:0:0:"NULL":0:0:1:-1:"":2:0:"data_files/test-ca2.crt"
 
 X509 String to Names #1
 mbedtls_x509_string_to_names:"C=NL,O=Offspark\, Inc., OU=PolarSSL":"C=NL, O=Offspark\, Inc., OU=PolarSSL":0
@@ -167,3 +179,6 @@
 
 X509 String to Names #6 (Escape at end)
 mbedtls_x509_string_to_names:"C=NL, O=Offspark\":"":MBEDTLS_ERR_X509_INVALID_NAME
+
+Check max serial length
+x509_set_serial_check:
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index 03b9bae..056d26a 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -300,7 +300,7 @@
 void x509_crt_check(char *subject_key_file, char *subject_pwd,
                     char *subject_name, char *issuer_key_file,
                     char *issuer_pwd, char *issuer_name,
-                    char *serial_str, char *not_before, char *not_after,
+                    data_t *serial_arg, char *not_before, char *not_after,
                     int md_type, int key_usage, int set_key_usage,
                     char *ext_key_usage,
                     int cert_type, int set_cert_type, int auth_ident,
@@ -315,7 +315,9 @@
     unsigned char check_buf[5000];
     unsigned char *p, *end;
     unsigned char tag, sz;
-    mbedtls_mpi serial;
+#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
+    mbedtls_mpi serial_mpi;
+#endif
     int ret, before_tag, after_tag;
     size_t olen = 0, pem_len = 0, buf_index = 0;
     int der_len = -1;
@@ -327,7 +329,9 @@
     mbedtls_pk_type_t issuer_key_type;
 
     memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
-    mbedtls_mpi_init(&serial);
+#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
+    mbedtls_mpi_init(&serial_mpi);
+#endif
 
     USE_PSA_INIT();
 
@@ -384,13 +388,18 @@
         TEST_ASSERT(mbedtls_pk_get_type(&issuer_key) == MBEDTLS_PK_OPAQUE);
     }
 
-    TEST_ASSERT(mbedtls_test_read_mpi(&serial, serial_str) == 0);
-
     if (ver != -1) {
         mbedtls_x509write_crt_set_version(&crt, ver);
     }
 
-    TEST_ASSERT(mbedtls_x509write_crt_set_serial(&crt, &serial) == 0);
+#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
+    TEST_ASSERT(mbedtls_mpi_read_binary(&serial_mpi, serial_arg->x,
+                                        serial_arg->len) == 0);
+    TEST_ASSERT(mbedtls_x509write_crt_set_serial(&crt, &serial_mpi) == 0);
+#else
+    TEST_ASSERT(mbedtls_x509write_crt_set_serial_raw(&crt, serial_arg->x,
+                                                     serial_arg->len) == 0);
+#endif
     TEST_ASSERT(mbedtls_x509write_crt_set_validity(&crt, not_before,
                                                    not_after) == 0);
     mbedtls_x509write_crt_set_md_alg(&crt, md_type);
@@ -549,7 +558,9 @@
     mbedtls_pk_free(&issuer_key_alt);
     mbedtls_pk_free(&subject_key);
     mbedtls_pk_free(&issuer_key);
-    mbedtls_mpi_free(&serial);
+#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
+    mbedtls_mpi_free(&serial_mpi);
+#endif
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_destroy_key(key_id);
 #endif
@@ -557,6 +568,37 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_WRITE_C */
+void x509_set_serial_check()
+{
+    mbedtls_x509write_cert ctx;
+    uint8_t invalid_serial[MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN + 1];
+
+    memset(invalid_serial, 0x01, sizeof(invalid_serial));
+
+#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
+    mbedtls_mpi serial_mpi;
+
+    mbedtls_mpi_init(&serial_mpi);
+    TEST_EQUAL(mbedtls_mpi_read_binary(&serial_mpi, invalid_serial,
+                                       sizeof(invalid_serial)), 0);
+    TEST_EQUAL(mbedtls_x509write_crt_set_serial(&ctx, &serial_mpi),
+               MBEDTLS_ERR_X509_BAD_INPUT_DATA);
+#endif
+
+    TEST_EQUAL(mbedtls_x509write_crt_set_serial_raw(&ctx, invalid_serial,
+                                                    sizeof(invalid_serial)),
+               MBEDTLS_ERR_X509_BAD_INPUT_DATA);
+
+exit:
+#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
+    mbedtls_mpi_free(&serial_mpi);
+#else
+    ;
+#endif
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C */
 void mbedtls_x509_string_to_names(char *name, char *parsed_name, int result
                                   )