Import mbedtls-3.6.2

Imports Mbed TLS 3.6.2 from https://github.com/Mbed-TLS/mbedtls.git
tags mbedtls-3.6.2, v3.6.2

Files that are not needed are removed:

cd lib/libmbedtls
rm -rf mbedtls
cp -R path/to/mbedtls-3.6.2/mbedtls .
cd mbedtls
rm CMakeLists.txt DartConfiguration.tcl Makefile
rm .gitignore .travis.yml .pylintrc .globalrc .mypy.ini BRANCHES.md
rm include/.gitignore include/CMakeLists.txt library/.gitignore
rm library/CMakeLists.txt library/Makefile
rm -r cmake
rm -rf .git .github doxygen configs programs scripts tests visualc
rm -rf 3rdparty ChangeLog.d docs pkgconfig .gitmodules .readthedocs.yaml
rm library/mps_*
cd ..
git add mbedtls

This is a complete overwrite of previous code so earlier changes in the
previous branch import/mbedtls-3.6.0 will be added on top of this
commit.

Signed-off-by: Sungbae Yoo <sungbaey@nvidia.com>
diff --git a/lib/libmbedtls/mbedtls/library/bignum.c b/lib/libmbedtls/mbedtls/library/bignum.c
index c022a61..4244909 100644
--- a/lib/libmbedtls/mbedtls/library/bignum.c
+++ b/lib/libmbedtls/mbedtls/library/bignum.c
@@ -27,6 +27,7 @@
 
 #include "mbedtls/bignum.h"
 #include "bignum_core.h"
+#include "bignum_internal.h"
 #include "bn_mul.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
@@ -37,9 +38,6 @@
 
 #include "mbedtls/platform.h"
 
-#include <mempool.h>
-
-void *mbedtls_mpi_mempool;
 
 
 /*
@@ -178,30 +176,13 @@
 #define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n))
 
 /*
- * Implementation that should never be optimized out by the compiler.
- * Reintroduced to allow use of mempool.
- */
-#define mbedtls_mpi_zeroize(v, n) mbedtls_platform_zeroize(v, ciL * (n))
-
-/*
  * Initialize one MPI
  */
-static void mpi_init(mbedtls_mpi *X, short use_mempool)
-{
-    X->s = 1;
-    X->use_mempool = use_mempool;
-    X->n = 0;
-    X->p = NULL;
-}
-
 void mbedtls_mpi_init(mbedtls_mpi *X)
 {
-    mpi_init(X, 0 /*use_mempool*/);
-}
-
-void mbedtls_mpi_init_mempool(mbedtls_mpi *X)
-{
-    mpi_init(X, !!mbedtls_mpi_mempool /*use_mempool*/);
+    X->s = 1;
+    X->n = 0;
+    X->p = NULL;
 }
 
 /*
@@ -214,12 +195,7 @@
     }
 
     if (X->p != NULL) {
-        if(X->use_mempool) {
-            mbedtls_mpi_zeroize(X->p, X->n);
-            mempool_free(mbedtls_mpi_mempool, X->p);
-        } else {
-            mbedtls_mpi_zeroize_and_free(X->p, X->n);
-        }
+        mbedtls_mpi_zeroize_and_free(X->p, X->n);
     }
 
     X->s = 1;
@@ -239,26 +215,13 @@
     }
 
     if (X->n < nblimbs) {
-        if(X->use_mempool) {
-            p = mempool_alloc(mbedtls_mpi_mempool, nblimbs * ciL);
-            if(p == NULL)
-                return MBEDTLS_ERR_MPI_ALLOC_FAILED;
-            memset(p, 0, nblimbs * ciL);
-        } else {
-                p = (mbedtls_mpi_uint *) mbedtls_calloc(nblimbs, ciL);
-                if (p == NULL)
-                    return MBEDTLS_ERR_MPI_ALLOC_FAILED;
+        if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(nblimbs, ciL)) == NULL) {
+            return MBEDTLS_ERR_MPI_ALLOC_FAILED;
         }
 
         if (X->p != NULL) {
             memcpy(p, X->p, X->n * ciL);
-
-            if (X->use_mempool) {
-                mbedtls_mpi_zeroize(X->p, X->n);
-                mempool_free(mbedtls_mpi_mempool, X->p);
-            } else {
-                mbedtls_mpi_zeroize_and_free(X->p, X->n);
-            }
+            mbedtls_mpi_zeroize_and_free(X->p, X->n);
         }
 
         /* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
@@ -300,26 +263,13 @@
         i = nblimbs;
     }
 
-    if (X->use_mempool) {
-        p = mempool_alloc(mbedtls_mpi_mempool, i * ciL);
-        if (p == NULL)
-            return MBEDTLS_ERR_MPI_ALLOC_FAILED;
-        memset(p, 0, i * ciL);
-    } else {
-        if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(i, ciL)) == NULL)
-            return MBEDTLS_ERR_MPI_ALLOC_FAILED;
+    if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(i, ciL)) == NULL) {
+        return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     }
 
     if (X->p != NULL) {
         memcpy(p, X->p, i * ciL);
-
-        if (X->use_mempool) {
-            mbedtls_mpi_zeroize(X->p, X->n);
-            mempool_free(mbedtls_mpi_mempool, X->p);
-        }
-        else {
-            mbedtls_mpi_zeroize_and_free(X->p, X->n);
-        }
+        mbedtls_mpi_zeroize_and_free(X->p, X->n);
     }
 
     /* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
@@ -572,7 +522,7 @@
         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     }
 
-    mbedtls_mpi_init_mempool(&T);
+    mbedtls_mpi_init(&T);
 
     if (s[0] == 0) {
         mbedtls_mpi_free(X);
@@ -699,7 +649,7 @@
     }
 
     p = buf;
-    mbedtls_mpi_init_mempool(&T);
+    mbedtls_mpi_init(&T);
 
     if (X->s == -1) {
         *p++ = '-';
@@ -1247,8 +1197,8 @@
     mbedtls_mpi TA, TB;
     int result_is_zero = 0;
 
-    mbedtls_mpi_init_mempool(&TA);
-    mbedtls_mpi_init_mempool(&TB);
+    mbedtls_mpi_init(&TA);
+    mbedtls_mpi_init(&TB);
 
     if (X == A) {
         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA;
@@ -1452,8 +1402,8 @@
         return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
     }
 
-    mbedtls_mpi_init_mempool(&X); mbedtls_mpi_init_mempool(&Y);
-    mbedtls_mpi_init_mempool(&Z); mbedtls_mpi_init_mempool(&T1);
+    mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
+    mbedtls_mpi_init(&T1);
     /*
      * Avoid dynamic memory allocations for constant-size T2.
      *
@@ -1661,107 +1611,15 @@
     return 0;
 }
 
-/**
- * \remark Replaced by our own because the original has been removed since
- *         mbedtls v3.6.0.
-*/
-void mbedtls_mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N)
-{
-    *mm = mbedtls_mpi_core_montmul_init(N->p);
-}
-
-/** Montgomery multiplication: A = A * B * R^-1 mod N  (HAC 14.36)
- * 
- * \param[in,out]   A   One of the numbers to multiply.
- *                      It must have at least as many limbs as N
- *                      (A->n >= N->n), and any limbs beyond n are ignored.
- *                      On successful completion, A contains the result of
- *                      the multiplication A * B * R^-1 mod N where
- *                      R = (2^ciL)^n.
- * \param[in]       B   One of the numbers to multiply.
- *                      It must be nonzero and must not have more limbs than N
- *                      (B->n <= N->n).
- * \param[in]       N   The modulus. \p N must be odd.
- * \param           mm  The value calculated by `mpi_montg_init(&mm, N)`.
- *                      This is -N^-1 mod 2^ciL.
- * \param[in,out]   T   A bignum for temporary storage.
- *                      It must be at least twice the limb size of N plus 1
- *                      (T->n >= 2 * N->n + 1).
- *                      Its initial content is unused and
- *                      its final content is indeterminate.
- *                      It does not get reallocated.
- * \remark Replaced by our own because the original has been removed since
- *         mbedtls v3.6.0.
- */
-void mbedtls_mpi_montmul(mbedtls_mpi *A, const mbedtls_mpi *B,
-                        const mbedtls_mpi *N, mbedtls_mpi_uint mm,
-                        mbedtls_mpi *T)
-{
-    mbedtls_mpi_core_montmul(A->p, A->p, B->p, B->n, N->p, N->n, mm, T->p);
-}
-
-/**
- * Montgomery reduction: A = A * R^-1 mod N
- *
- * See mbedtls_mpi_montmul() regarding constraints and guarantees on the parameters.
- * 
- * \remark Replaced by our own because the original has been removed since
- *         mbedtls v3.6.0.
- */
-void mbedtls_mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N,
-                        mbedtls_mpi_uint mm, mbedtls_mpi *T)
-{
-    mbedtls_mpi_uint z = 1;
-    mbedtls_mpi U;
-
-    U.n = U.s = (int) z;
-    U.p = &z;
-
-    mbedtls_mpi_montmul(A, &U, N, mm, T);
-}
-
-/**
- * Select an MPI from a table without leaking the index.
- *
- * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
- * reads the entire table in order to avoid leaking the value of idx to an
- * attacker able to observe memory access patterns.
- *
- * \param[out] R        Where to write the selected MPI.
- * \param[in] T         The table to read from.
- * \param[in] T_size    The number of elements in the table.
- * \param[in] idx       The index of the element to select;
- *                      this must satisfy 0 <= idx < T_size.
- *
- * \return \c 0 on success, or a negative error code.
- */
-static int mpi_select(mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
-    for (size_t i = 0; i < T_size; i++) {
-        MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(R, &T[i],
-                                                     (unsigned char) mbedtls_ct_uint_eq(i, idx)));
-    }
-cleanup:
-    return ret;
-}
-
 /*
- * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
+ * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
+ * this function is not constant time with respect to the exponent (parameter E).
  */
-int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
-                        const mbedtls_mpi *E, const mbedtls_mpi *N,
-                        mbedtls_mpi *prec_RR)
+static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,
+                                               const mbedtls_mpi *E, int E_public,
+                                               const mbedtls_mpi *N, mbedtls_mpi *prec_RR)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t window_bitsize;
-    size_t i, j, nblimbs;
-    size_t bufsize, nbits;
-    size_t exponent_bits_in_window = 0;
-    mbedtls_mpi_uint ei, mm, state;
-    mbedtls_mpi RR, T, W[(size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE], WW, Apos;
-    int neg;
 
     if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@@ -1777,262 +1635,92 @@
     }
 
     /*
-     * Init temps and window size
+     * Ensure that the exponent that we are passing to the core is not NULL.
      */
-    mbedtls_mpi_montg_init(&mm, N);
-    mbedtls_mpi_init(&RR); mbedtls_mpi_init(&T);
-    mbedtls_mpi_init(&Apos);
-    mbedtls_mpi_init(&WW);
-    memset(W, 0, sizeof(W));
-
-    i = mbedtls_mpi_bitlen(E);
-
-    window_bitsize = (i > 671) ? 6 : (i > 239) ? 5 :
-                     (i >  79) ? 4 : (i >  23) ? 3 : 1;
-
-#if (MBEDTLS_MPI_WINDOW_SIZE < 6)
-    if (window_bitsize > MBEDTLS_MPI_WINDOW_SIZE) {
-        window_bitsize = MBEDTLS_MPI_WINDOW_SIZE;
+    if (E->n == 0) {
+        ret = mbedtls_mpi_lset(X, 1);
+        return ret;
     }
-#endif
-
-    const size_t w_table_used_size = (size_t) 1 << window_bitsize;
 
     /*
-     * This function is not constant-trace: its memory accesses depend on the
-     * exponent value. To defend against timing attacks, callers (such as RSA
-     * and DHM) should use exponent blinding. However this is not enough if the
-     * adversary can find the exponent in a single trace, so this function
-     * takes extra precautions against adversaries who can observe memory
-     * access patterns.
-     *
-     * This function performs a series of multiplications by table elements and
-     * squarings, and we want the prevent the adversary from finding out which
-     * table element was used, and from distinguishing between multiplications
-     * and squarings. Firstly, when multiplying by an element of the window
-     * W[i], we do a constant-trace table lookup to obfuscate i. This leaves
-     * squarings as having a different memory access patterns from other
-     * multiplications. So secondly, we put the accumulator in the table as
-     * well, and also do a constant-trace table lookup to multiply by the
-     * accumulator which is W[x_index].
-     *
-     * This way, all multiplications take the form of a lookup-and-multiply.
-     * The number of lookup-and-multiply operations inside each iteration of
-     * the main loop still depends on the bits of the exponent, but since the
-     * other operations in the loop don't have an easily recognizable memory
-     * trace, an adversary is unlikely to be able to observe the exact
-     * patterns.
-     *
-     * An adversary may still be able to recover the exponent if they can
-     * observe both memory accesses and branches. However, branch prediction
-     * exploitation typically requires many traces of execution over the same
-     * data, which is defeated by randomized blinding.
+     * Allocate working memory for mbedtls_mpi_core_exp_mod()
      */
-    const size_t x_index = 0;
-    mbedtls_mpi_init(&W[x_index]);
-
-    j = N->n + 1;
-    /* All W[i] including the accumulator must have at least N->n limbs for
-     * the mbedtls_mpi_montmul() and mbedtls_mpi_montred() calls later.
-     * Here we ensure that
-     * W[1] and the accumulator W[x_index] are large enough. later we'll grow
-     * other W[i] to the same length. They must not be shrunk midway through
-     * this function!
-     */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1],  j));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T, j * 2));
-
-    /*
-     * Compensate for negative A (and correct at the end)
-     */
-    neg = (A->s == -1);
-    if (neg) {
-        MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Apos, A));
-        Apos.s = 1;
-        A = &Apos;
+    size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);
+    mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));
+    if (T == NULL) {
+        return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     }
 
+    mbedtls_mpi RR;
+    mbedtls_mpi_init(&RR);
+
     /*
      * If 1st call, pre-compute R^2 mod N
      */
     if (prec_RR == NULL || prec_RR->p == NULL) {
-        MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&RR, 1));
-        MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&RR, N->n * 2 * biL));
-        MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&RR, &RR, N));
+        MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
 
         if (prec_RR != NULL) {
-            memcpy(prec_RR, &RR, sizeof(mbedtls_mpi));
+            *prec_RR = RR;
         }
     } else {
-        memcpy(&RR, prec_RR, sizeof(mbedtls_mpi));
+        MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));
+        RR = *prec_RR;
     }
 
     /*
-     * W[1] = A * R^2 * R^-1 mod N = A * R mod N
+     * To preserve constness we need to make a copy of A. Using X for this to
+     * save memory.
      */
-    if (mbedtls_mpi_cmp_mpi(A, N) >= 0) {
-        MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&W[1], A, N));
-        /* This should be a no-op because W[1] is already that large before
-         * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
-         * in mbedtls_mpi_montmul() below, so let's make sure. */
-        MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], N->n + 1));
-    } else {
-        MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[1], A));
-    }
-
-    /* Note that this is safe because W[1] always has at least N->n limbs
-     * (it grew above and was preserved by mbedtls_mpi_copy()). */
-    mbedtls_mpi_montmul(&W[1], &RR, N, mm, &T);
+    MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
 
     /*
-     * W[x_index] = R^2 * R^-1 mod N = R mod N
+     * Compensate for negative A (and correct at the end).
      */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[x_index], &RR));
-    mbedtls_mpi_montred(&W[x_index], N, mm, &T);
+    X->s = 1;
 
-
-    if (window_bitsize > 1) {
-        /*
-         * W[i] = W[1] ^ i
-         *
-         * The first bit of the sliding window is always 1 and therefore we
-         * only need to store the second half of the table.
-         *
-         * (There are two special elements in the table: W[0] for the
-         * accumulator/result and W[1] for A in Montgomery form. Both of these
-         * are already set at this point.)
-         */
-        j = w_table_used_size / 2;
-
-        MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[j], N->n + 1));
-        MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[j], &W[1]));
-
-        for (i = 0; i < window_bitsize - 1; i++) {
-            mbedtls_mpi_montmul(&W[j], &W[j], N, mm, &T);
-        }
-
-        /*
-         * W[i] = W[i - 1] * W[1]
-         */
-        for (i = j + 1; i < w_table_used_size; i++) {
-            MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[i], N->n + 1));
-            MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[i], &W[i - 1]));
-
-            mbedtls_mpi_montmul(&W[i], &W[1], N, mm, &T);
-        }
+    /*
+     * Make sure that X is in a form that is safe for consumption by
+     * the core functions.
+     *
+     * - The core functions will not touch the limbs of X above N->n. The
+     *   result will be correct if those limbs are 0, which the mod call
+     *   ensures.
+     * - Also, X must have at least as many limbs as N for the calls to the
+     *   core functions.
+     */
+    if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {
+        MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
     }
+    MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));
 
-    nblimbs = E->n;
-    bufsize = 0;
-    nbits   = 0;
-    state   = 0;
-
-    while (1) {
-        if (bufsize == 0) {
-            if (nblimbs == 0) {
-                break;
-            }
-
-            nblimbs--;
-
-            bufsize = sizeof(mbedtls_mpi_uint) << 3;
+    /*
+     * Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().
+     */
+    {
+        mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
+        mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
+        if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
+            mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
+        } else {
+            mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
         }
-
-        bufsize--;
-
-        ei = (E->p[nblimbs] >> bufsize) & 1;
-
-        /*
-         * skip leading 0s
-         */
-        if (ei == 0 && state == 0) {
-            continue;
-        }
-
-        if (ei == 0 && state == 1) {
-            /*
-             * out of window, square W[x_index]
-             */
-            MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
-            mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T);
-            continue;
-        }
-
-        /*
-         * add ei to current window
-         */
-        state = 2;
-
-        nbits++;
-        exponent_bits_in_window |= (ei << (window_bitsize - nbits));
-
-        if (nbits == window_bitsize) {
-            /*
-             * W[x_index] = W[x_index]^window_bitsize R^-1 mod N
-             */
-            for (i = 0; i < window_bitsize; i++) {
-                MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
-                                           x_index));
-                mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T);
-            }
-
-            /*
-             * W[x_index] = W[x_index] * W[exponent_bits_in_window] R^-1 mod N
-             */
-            MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
-                                       exponent_bits_in_window));
-            mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T);
-
-            state--;
-            nbits = 0;
-            exponent_bits_in_window = 0;
-        }
+        mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
     }
 
     /*
-     * process the remaining bits
+     * Correct for negative A.
      */
-    for (i = 0; i < nbits; i++) {
-        MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
-        mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T);
+    if (A->s == -1 && (E->p[0] & 1) != 0) {
+        mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);
+        X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);
 
-        exponent_bits_in_window <<= 1;
-
-        if ((exponent_bits_in_window & ((size_t) 1 << window_bitsize)) != 0) {
-            MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, 1));
-            mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T);
-        }
+        MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
     }
 
-    /*
-     * W[x_index] = A^E * R * R^-1 mod N = A^E mod N
-     */
-    mbedtls_mpi_montred(&W[x_index], N, mm, &T);
-
-    if (neg && E->n != 0 && (E->p[0] & 1) != 0) {
-        W[x_index].s = -1;
-        MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&W[x_index], N, &W[x_index]));
-    }
-
-    /*
-     * Load the result in the output variable.
-     */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &W[x_index]));
-
 cleanup:
 
-    /* The first bit of the sliding window is always 1 and therefore the first
-     * half of the table was unused. */
-    for (i = w_table_used_size/2; i < w_table_used_size; i++) {
-        mbedtls_mpi_free(&W[i]);
-    }
-
-    mbedtls_mpi_free(&W[x_index]);
-    mbedtls_mpi_free(&W[1]);
-    mbedtls_mpi_free(&T);
-    mbedtls_mpi_free(&Apos);
-    mbedtls_mpi_free(&WW);
+    mbedtls_mpi_zeroize_and_free(T, T_limbs);
 
     if (prec_RR == NULL || prec_RR->p == NULL) {
         mbedtls_mpi_free(&RR);
@@ -2041,6 +1729,20 @@
     return ret;
 }
 
+int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
+                        const mbedtls_mpi *E, const mbedtls_mpi *N,
+                        mbedtls_mpi *prec_RR)
+{
+    return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);
+}
+
+int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
+                               const mbedtls_mpi *E, const mbedtls_mpi *N,
+                               mbedtls_mpi *prec_RR)
+{
+    return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
+}
+
 /*
  * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
  */
@@ -2050,7 +1752,7 @@
     size_t lz, lzt;
     mbedtls_mpi TA, TB;
 
-    mbedtls_mpi_init_mempool(&TA); mbedtls_mpi_init_mempool(&TB);
+    mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);
 
     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));
     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));
@@ -2208,11 +1910,9 @@
         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     }
 
-    mbedtls_mpi_init_mempool(&TA); mbedtls_mpi_init_mempool(&TU);
-    mbedtls_mpi_init_mempool(&U1); mbedtls_mpi_init_mempool(&U2);
-    mbedtls_mpi_init_mempool(&G); mbedtls_mpi_init_mempool(&TB);
-    mbedtls_mpi_init_mempool(&TV); mbedtls_mpi_init_mempool(&V1);
-    mbedtls_mpi_init_mempool(&V2);
+    mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TU); mbedtls_mpi_init(&U1); mbedtls_mpi_init(&U2);
+    mbedtls_mpi_init(&G); mbedtls_mpi_init(&TB); mbedtls_mpi_init(&TV);
+    mbedtls_mpi_init(&V1); mbedtls_mpi_init(&V2);
 
     MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, A, N));
 
@@ -2360,9 +2060,9 @@
     size_t i, j, k, s;
     mbedtls_mpi W, R, T, A, RR;
 
-    mbedtls_mpi_init_mempool(&W); mbedtls_mpi_init_mempool(&R);
-    mbedtls_mpi_init_mempool(&T); mbedtls_mpi_init_mempool(&A);
-    mbedtls_mpi_init_mempool(&RR);
+    mbedtls_mpi_init(&W); mbedtls_mpi_init(&R);
+    mbedtls_mpi_init(&T); mbedtls_mpi_init(&A);
+    mbedtls_mpi_init(&RR);
 
     /*
      * W = |X| - 1
@@ -2387,7 +2087,7 @@
                 A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1;
             }
 
-            if (count++ > 300) {
+            if (count++ > 30) {
                 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
                 goto cleanup;
             }
@@ -2500,7 +2200,7 @@
         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     }
 
-    mbedtls_mpi_init_mempool(&Y);
+    mbedtls_mpi_init(&Y);
 
     n = BITS_TO_LIMBS(nbits);
 
@@ -2618,10 +2318,8 @@
     int ret, i;
     mbedtls_mpi A, E, N, X, Y, U, V;
 
-    mbedtls_mpi_init_mempool(&A); mbedtls_mpi_init_mempool(&E);
-    mbedtls_mpi_init_mempool(&N); mbedtls_mpi_init_mempool(&X);
-    mbedtls_mpi_init_mempool(&Y); mbedtls_mpi_init_mempool(&U);
-    mbedtls_mpi_init_mempool(&V);
+    mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N); mbedtls_mpi_init(&X);
+    mbedtls_mpi_init(&Y); mbedtls_mpi_init(&U); mbedtls_mpi_init(&V);
 
     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16,
                                             "EFE021C2645FD1DC586E69184AF4A31E" \
diff --git a/lib/libmbedtls/mbedtls/library/bignum_core.c b/lib/libmbedtls/mbedtls/library/bignum_core.c
index 1a3e0b9..4231554 100644
--- a/lib/libmbedtls/mbedtls/library/bignum_core.c
+++ b/lib/libmbedtls/mbedtls/library/bignum_core.c
@@ -746,8 +746,94 @@
     }
 }
 
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
+int mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
+#endif
+
+/*
+ * This function calculates the indices of the exponent where the exponentiation algorithm should
+ * start processing.
+ *
+ * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
+ * this function is not constant time with respect to the exponent (parameter E).
+ */
+static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E,
+                                                          size_t E_limbs,
+                                                          int E_public,
+                                                          size_t *E_limb_index,
+                                                          size_t *E_bit_index)
+{
+    if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
+        /*
+         * Skip leading zero bits.
+         */
+        size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);
+        if (E_bits == 0) {
+            /*
+             * If E is 0 mbedtls_mpi_core_bitlen() returns 0. Even if that is the case, we will want
+             * to represent it as a single 0 bit and as such the bitlength will be 1.
+             */
+            E_bits = 1;
+        }
+
+        *E_limb_index = E_bits / biL;
+        *E_bit_index = E_bits % biL;
+
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+        mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
+#endif
+    } else {
+        /*
+         * Here we need to be constant time with respect to E and can't do anything better than
+         * start at the first allocated bit.
+         */
+        *E_limb_index = E_limbs;
+        *E_bit_index = 0;
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+        // Only mark the codepath safe if there wasn't an unsafe codepath before
+        if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
+            mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
+        }
+#endif
+    }
+}
+
+/*
+ * Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is
+ * not constant time with respect to the window parameter and consequently the exponent of the
+ * exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe).
+ */
+static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect,
+                                                        mbedtls_mpi_uint *Wtable,
+                                                        size_t AN_limbs, size_t welem,
+                                                        mbedtls_mpi_uint window,
+                                                        int window_public)
+{
+    if (window_public == MBEDTLS_MPI_IS_PUBLIC) {
+        memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+        mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
+#endif
+    } else {
+        /* Select Wtable[window] without leaking window through
+         * memory access patterns. */
+        mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
+                                              AN_limbs, welem, window);
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+        // Only mark the codepath safe if there wasn't an unsafe codepath before
+        if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
+            mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
+        }
+#endif
+    }
+}
+
 /* Exponentiation: X := A^E mod N.
  *
+ * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
+ * this function is not constant time with respect to the exponent (parameter E).
+ *
  * A must already be in Montgomery form.
  *
  * As in other bignum functions, assume that AN_limbs and E_limbs are nonzero.
@@ -758,16 +844,25 @@
  * (The difference is that the body in our loop processes a single bit instead
  * of a full window.)
  */
-void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
-                              const mbedtls_mpi_uint *A,
-                              const mbedtls_mpi_uint *N,
-                              size_t AN_limbs,
-                              const mbedtls_mpi_uint *E,
-                              size_t E_limbs,
-                              const mbedtls_mpi_uint *RR,
-                              mbedtls_mpi_uint *T)
+static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X,
+                                                     const mbedtls_mpi_uint *A,
+                                                     const mbedtls_mpi_uint *N,
+                                                     size_t AN_limbs,
+                                                     const mbedtls_mpi_uint *E,
+                                                     size_t E_limbs,
+                                                     int E_public,
+                                                     const mbedtls_mpi_uint *RR,
+                                                     mbedtls_mpi_uint *T)
 {
-    const size_t wsize = exp_mod_get_window_size(E_limbs * biL);
+    /* We'll process the bits of E from most significant
+     * (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
+     * (limb_index=0, E_bit_index=0). */
+    size_t E_limb_index;
+    size_t E_bit_index;
+    exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public,
+                                           &E_limb_index, &E_bit_index);
+
+    const size_t wsize = exp_mod_get_window_size(E_limb_index * biL);
     const size_t welem = ((size_t) 1) << wsize;
 
     /* This is how we will use the temporary storage T, which must have space
@@ -786,7 +881,7 @@
 
     const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N);
 
-    /* Set Wtable[i] = A^(2^i) (in Montgomery representation) */
+    /* Set Wtable[i] = A^i (in Montgomery representation) */
     exp_mod_precompute_window(A, N, AN_limbs,
                               mm, RR,
                               welem, Wtable, temp);
@@ -798,11 +893,6 @@
     /* X = 1 (in Montgomery presentation) initially */
     memcpy(X, Wtable, AN_limbs * ciL);
 
-    /* We'll process the bits of E from most significant
-     * (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
-     * (limb_index=0, E_bit_index=0). */
-    size_t E_limb_index = E_limbs;
-    size_t E_bit_index = 0;
     /* At any given time, window contains window_bits bits from E.
      * window_bits can go up to wsize. */
     size_t window_bits = 0;
@@ -828,10 +918,9 @@
          * when we've finished processing the exponent. */
         if (window_bits == wsize ||
             (E_bit_index == 0 && E_limb_index == 0)) {
-            /* Select Wtable[window] without leaking window through
-             * memory access patterns. */
-            mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
-                                                  AN_limbs, welem, window);
+
+            exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem,
+                                                 window, E_public);
             /* Multiply X by the selected element. */
             mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm,
                                      temp);
@@ -841,6 +930,42 @@
     } while (!(E_bit_index == 0 && E_limb_index == 0));
 }
 
+void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
+                              const mbedtls_mpi_uint *A,
+                              const mbedtls_mpi_uint *N, size_t AN_limbs,
+                              const mbedtls_mpi_uint *E, size_t E_limbs,
+                              const mbedtls_mpi_uint *RR,
+                              mbedtls_mpi_uint *T)
+{
+    mbedtls_mpi_core_exp_mod_optionally_safe(X,
+                                             A,
+                                             N,
+                                             AN_limbs,
+                                             E,
+                                             E_limbs,
+                                             MBEDTLS_MPI_IS_SECRET,
+                                             RR,
+                                             T);
+}
+
+void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
+                                     const mbedtls_mpi_uint *A,
+                                     const mbedtls_mpi_uint *N, size_t AN_limbs,
+                                     const mbedtls_mpi_uint *E, size_t E_limbs,
+                                     const mbedtls_mpi_uint *RR,
+                                     mbedtls_mpi_uint *T)
+{
+    mbedtls_mpi_core_exp_mod_optionally_safe(X,
+                                             A,
+                                             N,
+                                             AN_limbs,
+                                             E,
+                                             E_limbs,
+                                             MBEDTLS_MPI_IS_PUBLIC,
+                                             RR,
+                                             T);
+}
+
 mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
                                           const mbedtls_mpi_uint *A,
                                           mbedtls_mpi_uint c,  /* doubles as carry */
diff --git a/lib/libmbedtls/mbedtls/library/bignum_core.h b/lib/libmbedtls/mbedtls/library/bignum_core.h
index 92c8d47..cf6485a 100644
--- a/lib/libmbedtls/mbedtls/library/bignum_core.h
+++ b/lib/libmbedtls/mbedtls/library/bignum_core.h
@@ -90,6 +90,27 @@
 #define GET_BYTE(X, i)                                \
     (((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff)
 
+/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by
+ * this constant, the function must be constant time with respect to the parameter.
+ *
+ * This is only needed for functions with the _optionally_safe postfix. All other functions have
+ * fixed behavior that can't be changed at runtime and are constant time with respect to their
+ * parameters as prescribed by their documentation or by conventions in their module's documentation.
+ *
+ * Parameters should be named X_public where X is the name of the
+ * corresponding input parameter.
+ *
+ * Implementation should always check using
+ *  if (X_public == MBEDTLS_MPI_IS_PUBLIC) {
+ *      // unsafe path
+ *  } else {
+ *      // safe path
+ *  }
+ * not the other way round, in order to prevent misuse. (This is, if a value
+ * other than the two below is passed, default to the safe path.) */
+#define MBEDTLS_MPI_IS_PUBLIC  0x2a2a2a2a
+#define MBEDTLS_MPI_IS_SECRET  0
+
 /** Count leading zero bits in a given integer.
  *
  * \warning     The result is undefined if \p a == 0
@@ -605,6 +626,42 @@
 size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs);
 
 /**
+ * \brief            Perform a modular exponentiation with public or secret exponent:
+ *                   X = A^E mod N, where \p A is already in Montgomery form.
+ *
+ * \warning          This function is not constant time with respect to \p E (the exponent).
+ *
+ * \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs ==
+ * \p AN_limbs.
+ *
+ * \param[out] X     The destination MPI, as a little endian array of length
+ *                   \p AN_limbs.
+ * \param[in] A      The base MPI, as a little endian array of length \p AN_limbs.
+ *                   Must be in Montgomery form.
+ * \param[in] N      The modulus, as a little endian array of length \p AN_limbs.
+ * \param AN_limbs   The number of limbs in \p X, \p A, \p N, \p RR.
+ * \param[in] E      The exponent, as a little endian array of length \p E_limbs.
+ * \param E_limbs    The number of limbs in \p E.
+ * \param[in] RR     The precomputed residue of 2^{2*biL} modulo N, as a little
+ *                   endian array of length \p AN_limbs.
+ * \param[in,out] T  Temporary storage of at least the number of limbs returned
+ *                   by `mbedtls_mpi_core_exp_mod_working_limbs()`.
+ *                   Its initial content is unused and its final content is
+ *                   indeterminate.
+ *                   It must not alias or otherwise overlap any of the other
+ *                   parameters.
+ *                   It is up to the caller to zeroize \p T when it is no
+ *                   longer needed, and before freeing it if it was dynamically
+ *                   allocated.
+ */
+void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
+                                     const mbedtls_mpi_uint *A,
+                                     const mbedtls_mpi_uint *N, size_t AN_limbs,
+                                     const mbedtls_mpi_uint *E, size_t E_limbs,
+                                     const mbedtls_mpi_uint *RR,
+                                     mbedtls_mpi_uint *T);
+
+/**
  * \brief            Perform a modular exponentiation with secret exponent:
  *                   X = A^E mod N, where \p A is already in Montgomery form.
  *
@@ -760,4 +817,17 @@
                                     mbedtls_mpi_uint mm,
                                     mbedtls_mpi_uint *T);
 
+/*
+ * Can't define thread local variables with our abstraction layer: do nothing if threading is on.
+ */
+#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
+extern int mbedtls_mpi_optionally_safe_codepath;
+
+static inline void mbedtls_mpi_optionally_safe_codepath_reset(void)
+{
+    // Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
+    mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
+}
+#endif
+
 #endif /* MBEDTLS_BIGNUM_CORE_H */
diff --git a/lib/libmbedtls/mbedtls/library/bignum_internal.h b/lib/libmbedtls/mbedtls/library/bignum_internal.h
new file mode 100644
index 0000000..aceaf55
--- /dev/null
+++ b/lib/libmbedtls/mbedtls/library/bignum_internal.h
@@ -0,0 +1,50 @@
+/**
+ * \file bignum_internal.h
+ *
+ * \brief Internal-only bignum public-key cryptosystem API.
+ *
+ * This file declares bignum-related functions that are to be used
+ * only from within the Mbed TLS library itself.
+ *
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+#ifndef MBEDTLS_BIGNUM_INTERNAL_H
+#define MBEDTLS_BIGNUM_INTERNAL_H
+
+/**
+ * \brief          Perform a modular exponentiation: X = A^E mod N
+ *
+ * \warning        This function is not constant time with respect to \p E (the exponent).
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ *                 This must not alias E or N.
+ * \param A        The base of the exponentiation.
+ *                 This must point to an initialized MPI.
+ * \param E        The exponent MPI. This must point to an initialized MPI.
+ * \param N        The base for the modular reduction. This must point to an
+ *                 initialized MPI.
+ * \param prec_RR  A helper MPI depending solely on \p N which can be used to
+ *                 speed-up multiple modular exponentiations for the same value
+ *                 of \p N. This may be \c NULL. If it is not \c NULL, it must
+ *                 point to an initialized MPI. If it hasn't been used after
+ *                 the call to mbedtls_mpi_init(), this function will compute
+ *                 the helper value and store it in \p prec_RR for reuse on
+ *                 subsequent calls to this function. Otherwise, the function
+ *                 will assume that \p prec_RR holds the helper value set by a
+ *                 previous call to mbedtls_mpi_exp_mod(), and reuse it.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or
+ *                 even, or if \c E is negative.
+ * \return         Another negative error code on different kinds of failures.
+ *
+ */
+int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
+                               const mbedtls_mpi *E, const mbedtls_mpi *N,
+                               mbedtls_mpi *prec_RR);
+
+#endif /* bignum_internal.h */
diff --git a/lib/libmbedtls/mbedtls/library/block_cipher.c b/lib/libmbedtls/mbedtls/library/block_cipher.c
index 04cd7fb..51cdcdf 100644
--- a/lib/libmbedtls/mbedtls/library/block_cipher.c
+++ b/lib/libmbedtls/mbedtls/library/block_cipher.c
@@ -51,6 +51,10 @@
 
 void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
     if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
         psa_destroy_key(ctx->psa_key_id);
diff --git a/lib/libmbedtls/mbedtls/library/cipher.c b/lib/libmbedtls/mbedtls/library/cipher.c
index 3f2f1a8..7f4c121 100644
--- a/lib/libmbedtls/mbedtls/library/cipher.c
+++ b/lib/libmbedtls/mbedtls/library/cipher.c
@@ -242,35 +242,6 @@
     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
 }
 
-int mbedtls_cipher_clone(mbedtls_cipher_context_t *dst,
-                         const mbedtls_cipher_context_t *src)
-{
-    if (dst == NULL || dst->cipher_info == NULL ||
-        src == NULL || src->cipher_info == NULL) {
-        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
-    }
-
-    dst->cipher_info = src->cipher_info;
-    dst->key_bitlen = src->key_bitlen;
-    dst->operation = src->operation;
-#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
-    dst->add_padding = src->add_padding;
-    dst->get_padding = src->get_padding;
-#endif
-    memcpy(dst->unprocessed_data, src->unprocessed_data, MBEDTLS_MAX_BLOCK_LENGTH);
-    dst->unprocessed_len = src->unprocessed_len;
-    memcpy(dst->iv, src->iv, MBEDTLS_MAX_IV_LENGTH);
-    dst->iv_size = src->iv_size;
-    if (mbedtls_cipher_get_base(dst->cipher_info)->ctx_clone_func)
-        mbedtls_cipher_get_base(dst->cipher_info)->ctx_clone_func(dst->cipher_ctx, src->cipher_ctx);
-
-#if defined(MBEDTLS_CMAC_C)
-    if (dst->cmac_ctx != NULL && src->cmac_ctx != NULL)
-        memcpy(dst->cmac_ctx, src->cmac_ctx, sizeof(mbedtls_cmac_context_t));
-#endif
-    return 0;
-}
-
 int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,
                          const mbedtls_cipher_info_t *cipher_info)
 {
@@ -328,16 +299,6 @@
 }
 #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
 
-int mbedtls_cipher_setup_info(mbedtls_cipher_context_t *ctx,
-                              const mbedtls_cipher_info_t *cipher_info )
-{
-    if (NULL == cipher_info || NULL == ctx)
-        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
-
-    ctx->cipher_info = cipher_info;
-    return 0;
-}
-
 int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
                           const unsigned char *key,
                           int key_bitlen,
@@ -888,6 +849,9 @@
     }
 
     padding_len = input[input_len - 1];
+    if (padding_len == 0 || padding_len > input_len) {
+        return MBEDTLS_ERR_CIPHER_INVALID_PADDING;
+    }
     *data_len = input_len - padding_len;
 
     mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
diff --git a/lib/libmbedtls/mbedtls/library/cipher_wrap.c b/lib/libmbedtls/mbedtls/library/cipher_wrap.c
index b570241..d2fee22 100644
--- a/lib/libmbedtls/mbedtls/library/cipher_wrap.c
+++ b/lib/libmbedtls/mbedtls/library/cipher_wrap.c
@@ -11,8 +11,6 @@
 
 #include "common.h"
 
-#include <string.h>
-
 #if defined(MBEDTLS_CIPHER_C)
 
 #include "cipher_wrap.h"
@@ -131,11 +129,6 @@
     return ctx;
 }
 
-static void gcm_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_gcm_context));
-}
-
 static void gcm_ctx_free(void *ctx)
 {
     mbedtls_gcm_free(ctx);
@@ -158,11 +151,6 @@
     return ctx;
 }
 
-static void ccm_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_ccm_context));
-}
-
 static void ccm_ctx_free(void *ctx)
 {
     mbedtls_ccm_free(ctx);
@@ -269,11 +257,6 @@
     return aes;
 }
 
-static void aes_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_aes_context));
-}
-
 static void aes_ctx_free(void *ctx)
 {
     mbedtls_aes_free((mbedtls_aes_context *) ctx);
@@ -306,7 +289,6 @@
     aes_setkey_dec_wrap,
 #endif
     aes_ctx_alloc,
-    aes_ctx_clone,
     aes_ctx_free
 };
 
@@ -621,7 +603,6 @@
     gcm_aes_setkey_wrap,
 #endif
     gcm_ctx_alloc,
-    gcm_ctx_clone,
     gcm_ctx_free,
 #else
     NULL,
@@ -706,7 +687,6 @@
     ccm_aes_setkey_wrap,
 #endif
     ccm_ctx_alloc,
-    ccm_ctx_clone,
     ccm_ctx_free,
 #else
     NULL,
@@ -859,11 +839,6 @@
     return ctx;
 }
 
-static void camellia_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_camellia_context));
-}
-
 static void camellia_ctx_free(void *ctx)
 {
     mbedtls_camellia_free((mbedtls_camellia_context *) ctx);
@@ -896,7 +871,6 @@
     camellia_setkey_dec_wrap,
 #endif
     camellia_ctx_alloc,
-    camellia_ctx_clone,
     camellia_ctx_free
 };
 
@@ -1072,7 +1046,6 @@
     gcm_camellia_setkey_wrap,
 #endif
     gcm_ctx_alloc,
-    gcm_ctx_clone,
     gcm_ctx_free,
 };
 
@@ -1144,7 +1117,6 @@
     ccm_camellia_setkey_wrap,
 #endif
     ccm_ctx_alloc,
-    ccm_ctx_clone,
     ccm_ctx_free,
 };
 
@@ -1730,11 +1702,6 @@
     return des;
 }
 
-static void des_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_des_context));
-}
-
 static void des_ctx_free(void *ctx)
 {
     mbedtls_des_free((mbedtls_des_context *) ctx);
@@ -1755,11 +1722,6 @@
     return des3;
 }
 
-static void des3_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_des3_context));
-}
-
 static void des3_ctx_free(void *ctx)
 {
     mbedtls_des3_free((mbedtls_des3_context *) ctx);
@@ -1790,7 +1752,6 @@
     des_setkey_enc_wrap,
     des_setkey_dec_wrap,
     des_ctx_alloc,
-    des_ctx_clone,
     des_ctx_free
 };
 
@@ -1842,7 +1803,6 @@
     des3_set2key_enc_wrap,
     des3_set2key_dec_wrap,
     des3_ctx_alloc,
-    des3_ctx_clone,
     des3_ctx_free
 };
 
@@ -1894,7 +1854,6 @@
     des3_set3key_enc_wrap,
     des3_set3key_dec_wrap,
     des3_ctx_alloc,
-    des3_ctx_clone,
     des3_ctx_free
 };
 
@@ -1966,11 +1925,6 @@
     return ctx;
 }
 
-static void chacha20_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_chacha20_context));
-}
-
 static void chacha20_ctx_free(void *ctx)
 {
     mbedtls_chacha20_free((mbedtls_chacha20_context *) ctx);
@@ -2003,7 +1957,6 @@
     chacha20_setkey_wrap,
 #endif
     chacha20_ctx_alloc,
-    chacha20_ctx_clone,
     chacha20_ctx_free
 };
 static const mbedtls_cipher_info_t chacha20_info = {
@@ -2049,11 +2002,6 @@
     return ctx;
 }
 
-static void chachapoly_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_chachapoly_context));
-}
-
 static void chachapoly_ctx_free(void *ctx)
 {
     mbedtls_chachapoly_free((mbedtls_chachapoly_context *) ctx);
@@ -2086,7 +2034,6 @@
     chachapoly_setkey_wrap,
 #endif
     chachapoly_ctx_alloc,
-    chachapoly_ctx_clone,
     chachapoly_ctx_free
 };
 static const mbedtls_cipher_info_t chachapoly_info = {
@@ -2126,12 +2073,6 @@
     return (void *) 1;
 }
 
-static void null_ctx_clone(void *dst, const void *src)
-{
-    ((void) dst);
-    ((void) src);
-}
-
 static void null_ctx_free(void *ctx)
 {
     ((void) ctx);
@@ -2163,7 +2104,6 @@
     null_setkey,
 #endif
     null_ctx_alloc,
-    null_ctx_clone,
     null_ctx_free
 };
 
@@ -2191,11 +2131,6 @@
     return ctx;
 }
 
-static void kw_ctx_clone(void *dst, const void *src)
-{
-    memcpy(dst, src, sizeof(mbedtls_nist_kw_context));
-}
-
 static void kw_ctx_free(void *ctx)
 {
     mbedtls_nist_kw_free(ctx);
@@ -2240,7 +2175,6 @@
     kw_aes_setkey_wrap,
     kw_aes_setkey_unwrap,
     kw_ctx_alloc,
-    kw_ctx_clone,
     kw_ctx_free,
 };
 
diff --git a/lib/libmbedtls/mbedtls/library/cipher_wrap.h b/lib/libmbedtls/mbedtls/library/cipher_wrap.h
index aa74289..f229151 100644
--- a/lib/libmbedtls/mbedtls/library/cipher_wrap.h
+++ b/lib/libmbedtls/mbedtls/library/cipher_wrap.h
@@ -134,9 +134,6 @@
     /** Allocate a new context */
     void * (*ctx_alloc_func)(void);
 
-    /** Clone context **/
-    void (*ctx_clone_func)( void *dst, const void *src );
-
     /** Free the given context */
     void (*ctx_free_func)(void *ctx);
 
diff --git a/lib/libmbedtls/mbedtls/library/cmac.c b/lib/libmbedtls/mbedtls/library/cmac.c
index a1ef947..eda10d0 100644
--- a/lib/libmbedtls/mbedtls/library/cmac.c
+++ b/lib/libmbedtls/mbedtls/library/cmac.c
@@ -153,26 +153,11 @@
     }
 }
 
-int mbedtls_cipher_cmac_setup(mbedtls_cipher_context_t *ctx)
-{
-    mbedtls_cmac_context_t *cmac_ctx;
-
-    /* Allocated and initialise in the cipher context memory for the CMAC
-     * context */
-    cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
-    if (cmac_ctx == NULL)
-        return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
-
-    ctx->cmac_ctx = cmac_ctx;
-
-    mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
-    return 0;
-}
-
 int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
                                const unsigned char *key, size_t keybits)
 {
     mbedtls_cipher_type_t type;
+    mbedtls_cmac_context_t *cmac_ctx;
     int retval;
 
     if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
@@ -196,11 +181,18 @@
             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
     }
 
-    /* Check if cmac ctx had been allocated by mbedtls_cipher_cmac_setup() */
-    if( ctx->cmac_ctx != NULL )
-        return 0;
+    /* Allocated and initialise in the cipher context memory for the CMAC
+     * context */
+    cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
+    if (cmac_ctx == NULL) {
+        return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
+    }
 
-    return mbedtls_cipher_cmac_setup( ctx );
+    ctx->cmac_ctx = cmac_ctx;
+
+    mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
+
+    return 0;
 }
 
 int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
diff --git a/lib/libmbedtls/mbedtls/library/common.h b/lib/libmbedtls/mbedtls/library/common.h
index d0e5a07..7bb2674 100644
--- a/lib/libmbedtls/mbedtls/library/common.h
+++ b/lib/libmbedtls/mbedtls/library/common.h
@@ -20,17 +20,7 @@
 #include <stddef.h>
 
 #if defined(__ARM_NEON)
-/*
- * Undefine and restore __section and __data from compiler.h to prevent
- * collision with arm_neon.h
- */
-#pragma push_macro("__section")
-#pragma push_macro("__data")
-#undef __section
-#undef __data
 #include <arm_neon.h>
-#pragma pop_macro("__data")
-#pragma pop_macro("__section")
 #define MBEDTLS_HAVE_NEON_INTRINSICS
 #elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
 #include <arm64_neon.h>
@@ -362,17 +352,19 @@
 #endif
 
 /* Always provide a static assert macro, so it can be used unconditionally.
- * It will expand to nothing on some systems.
- * Can be used outside functions (but don't add a trailing ';' in that case:
- * the semicolon is included here to avoid triggering -Wextra-semi when
- * MBEDTLS_STATIC_ASSERT() expands to nothing).
- * Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
+ * It does nothing on systems where we don't know how to define a static assert.
+ */
+/* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
  * defines static_assert even with -std=c99, but then complains about it.
  */
 #if defined(static_assert) && !defined(__FreeBSD__)
-#define MBEDTLS_STATIC_ASSERT(expr, msg)    static_assert(expr, msg);
+#define MBEDTLS_STATIC_ASSERT(expr, msg)    static_assert(expr, msg)
 #else
-#define MBEDTLS_STATIC_ASSERT(expr, msg)
+/* Make sure `MBEDTLS_STATIC_ASSERT(expr, msg);` is valid both inside and
+ * outside a function. We choose a struct declaration, which can be repeated
+ * any number of times and does not need a matching definition. */
+#define MBEDTLS_STATIC_ASSERT(expr, msg)                                \
+    struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function
 #endif
 
 #if defined(__has_builtin)
diff --git a/lib/libmbedtls/mbedtls/library/ctr_drbg.c b/lib/libmbedtls/mbedtls/library/ctr_drbg.c
index 66d9d28..b82044e 100644
--- a/lib/libmbedtls/mbedtls/library/ctr_drbg.c
+++ b/lib/libmbedtls/mbedtls/library/ctr_drbg.c
@@ -26,13 +26,13 @@
 #endif
 
 /* Using error translation functions from PSA to MbedTLS */
-#if !defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
 #include "psa_util_internal.h"
 #endif
 
 #include "mbedtls/platform.h"
 
-#if !defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
 static psa_status_t ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context *psa_ctx,
                                                unsigned char *key, size_t key_len)
 {
@@ -73,11 +73,11 @@
 void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
 {
     memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
-#if defined(MBEDTLS_AES_C)
-    mbedtls_aes_init(&ctx->aes_ctx);
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
     ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
     ctx->psa_ctx.operation = psa_cipher_operation_init();
+#else
+    mbedtls_aes_init(&ctx->aes_ctx);
 #endif
     /* Indicate that the entropy nonce length is not set explicitly.
      * See mbedtls_ctr_drbg_set_nonce_len(). */
@@ -102,10 +102,10 @@
         mbedtls_mutex_free(&ctx->mutex);
     }
 #endif
-#if defined(MBEDTLS_AES_C)
-    mbedtls_aes_free(&ctx->aes_ctx);
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
     ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
+#else
+    mbedtls_aes_free(&ctx->aes_ctx);
 #endif
     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
     ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
@@ -168,15 +168,15 @@
     unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
     unsigned char *p, *iv;
     int ret = 0;
-#if defined(MBEDTLS_AES_C)
-    mbedtls_aes_context aes_ctx;
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
     psa_status_t status;
     size_t tmp_len;
     mbedtls_ctr_drbg_psa_context psa_ctx;
 
     psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
     psa_ctx.operation = psa_cipher_operation_init();
+#else
+    mbedtls_aes_context aes_ctx;
 #endif
 
     int i, j;
@@ -209,19 +209,19 @@
         key[i] = i;
     }
 
-#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
+    status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
+    if (status != PSA_SUCCESS) {
+        ret = psa_generic_status_to_mbedtls(status);
+        goto exit;
+    }
+#else
     mbedtls_aes_init(&aes_ctx);
 
     if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
                                       MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
         goto exit;
     }
-#else
-    status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
-    if (status != PSA_SUCCESS) {
-        ret = psa_generic_status_to_mbedtls(status);
-        goto exit;
-    }
 #endif
 
     /*
@@ -238,18 +238,18 @@
             use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
                        MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
 
-#if defined(MBEDTLS_AES_C)
-            if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
-                                             chain, chain)) != 0) {
-                goto exit;
-            }
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
             status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE,
                                        chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
             if (status != PSA_SUCCESS) {
                 ret = psa_generic_status_to_mbedtls(status);
                 goto exit;
             }
+#else
+            if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
+                                             chain, chain)) != 0) {
+                goto exit;
+            }
 #endif
         }
 
@@ -264,12 +264,7 @@
     /*
      * Do final encryption with reduced data
      */
-#if defined(MBEDTLS_AES_C)
-    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
-                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
-        goto exit;
-    }
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
     ctr_drbg_destroy_psa_contex(&psa_ctx);
 
     status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
@@ -277,32 +272,37 @@
         ret = psa_generic_status_to_mbedtls(status);
         goto exit;
     }
+#else
+    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
+                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
+        goto exit;
+    }
 #endif
     iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
     p = output;
 
     for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
-#if defined(MBEDTLS_AES_C)
-        if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
-                                         iv, iv)) != 0) {
-            goto exit;
-        }
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
         status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE,
                                    iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
         if (status != PSA_SUCCESS) {
             ret = psa_generic_status_to_mbedtls(status);
             goto exit;
         }
+#else
+        if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
+                                         iv, iv)) != 0) {
+            goto exit;
+        }
 #endif
         memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
     }
 exit:
-#if defined(MBEDTLS_AES_C)
-    mbedtls_aes_free(&aes_ctx);
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
     ctr_drbg_destroy_psa_contex(&psa_ctx);
+#else
+    mbedtls_aes_free(&aes_ctx);
 #endif
     /*
      * tidy up the stack
@@ -336,7 +336,7 @@
     unsigned char *p = tmp;
     int j;
     int ret = 0;
-#if !defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
     psa_status_t status;
     size_t tmp_len;
 #endif
@@ -352,18 +352,18 @@
         /*
          * Crypt counter block
          */
-#if defined(MBEDTLS_AES_C)
-        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
-                                         ctx->counter, p)) != 0) {
-            goto exit;
-        }
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
         status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
                                    p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
         if (status != PSA_SUCCESS) {
             ret = psa_generic_status_to_mbedtls(status);
             goto exit;
         }
+#else
+        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
+                                         ctx->counter, p)) != 0) {
+            goto exit;
+        }
 #endif
 
         p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
@@ -374,12 +374,7 @@
     /*
      * Update key and counter
      */
-#if defined(MBEDTLS_AES_C)
-    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
-                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
-        goto exit;
-    }
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
     ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
 
     status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
@@ -387,6 +382,11 @@
         ret = psa_generic_status_to_mbedtls(status);
         goto exit;
     }
+#else
+    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
+                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
+        goto exit;
+    }
 #endif
     memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
            MBEDTLS_CTR_DRBG_BLOCKSIZE);
@@ -564,12 +564,7 @@
                  good_nonce_len(ctx->entropy_len));
 
     /* Initialize with an empty key. */
-#if defined(MBEDTLS_AES_C)
-    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
-                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
-        return ret;
-    }
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
     psa_status_t status;
 
     status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE);
@@ -577,6 +572,11 @@
         ret = psa_generic_status_to_mbedtls(status);
         return status;
     }
+#else
+    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
+                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
+        return ret;
+    }
 #endif
 
     /* Do the initial seeding. */
@@ -655,12 +655,7 @@
         /*
          * Crypt counter block
          */
-#if defined(MBEDTLS_AES_C)
-        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
-                                         ctx->counter, locals.tmp)) != 0) {
-            goto exit;
-        }
-#else
+#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
         psa_status_t status;
         size_t tmp_len;
 
@@ -670,6 +665,11 @@
             ret = psa_generic_status_to_mbedtls(status);
             goto exit;
         }
+#else
+        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
+                                         ctx->counter, locals.tmp)) != 0) {
+            goto exit;
+        }
 #endif
 
         use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
diff --git a/lib/libmbedtls/mbedtls/library/ecp.c b/lib/libmbedtls/mbedtls/library/ecp.c
index ab50a47..427059b 100644
--- a/lib/libmbedtls/mbedtls/library/ecp.c
+++ b/lib/libmbedtls/mbedtls/library/ecp.c
@@ -382,10 +382,6 @@
 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
     { MBEDTLS_ECP_DP_CURVE448,     30,     448,    "x448"              },
 #endif
-#if defined(MBEDTLS_ECP_DP_SM2_ENABLED)
-    /* https://tools.ietf.org/id/draft-yang-tls-tls13-sm-suites-05.html */
-    { MBEDTLS_ECP_DP_SM2,          41,     256,    "sm2"               },
-#endif
     { MBEDTLS_ECP_DP_NONE,          0,     0,      NULL                },
 };
 
@@ -2916,7 +2912,7 @@
 
 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
-#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n), .use_mempool = 0 }
+#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) }
 #define ECP_MPI_INIT_ARRAY(x)   \
     ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint))
 /*
diff --git a/lib/libmbedtls/mbedtls/library/ecp_curves.c b/lib/libmbedtls/mbedtls/library/ecp_curves.c
index b6287ac..c3cd33f 100644
--- a/lib/libmbedtls/mbedtls/library/ecp_curves.c
+++ b/lib/libmbedtls/mbedtls/library/ecp_curves.c
@@ -4488,48 +4488,6 @@
 
 #if defined(ECP_LOAD_GROUP)
 /*
- * Domain parameters for SM2 (GM/T 0003 Part 5)
- */
-#if defined(MBEDTLS_ECP_DP_SM2_ENABLED)
-static const mbedtls_mpi_uint sm2_p[] = {
-    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 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 ),
-};
-static const mbedtls_mpi_uint sm2_a[] = {
-    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 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 ),
-};
-static const mbedtls_mpi_uint sm2_b[] = {
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x0E, 0x94, 0x4D, 0x41, 0xBD, 0xBC, 0xDD ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x8F, 0xAB, 0x15, 0xF5, 0x89, 0x97, 0xF3 ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x09, 0x65, 0xCF, 0x4B, 0x9E, 0x5A, 0x4D ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x5E, 0x9F, 0x9D, 0x9E, 0xFA, 0xE9, 0x28 ),
-};
-static const mbedtls_mpi_uint sm2_gx[] = {
-    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0x74, 0x4C, 0x33, 0x89, 0x45, 0x5A, 0x71 ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x0B, 0x66, 0xF2, 0xBF, 0x0B, 0xE3, 0x8F ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0xC9, 0x39, 0x6A, 0x46, 0x04, 0x99, 0x5F ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x81, 0x19, 0x1F, 0x2C, 0xAE, 0xC4, 0x32 ),
-};
-static const mbedtls_mpi_uint sm2_gy[] = {
-    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xF0, 0x39, 0x21, 0xE5, 0x32, 0xDF, 0x02 ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x47, 0x2A, 0xC6, 0x7C, 0x87, 0xA9, 0xD0 ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0x21, 0x69, 0x6B, 0xE3, 0xCE, 0xBD, 0x59 ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0x77, 0xF6, 0xF4, 0xA2, 0x36, 0x37, 0xBC ),
-};
-static const mbedtls_mpi_uint sm2_n[] = {
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x41, 0xD5, 0x39, 0x09, 0xF4, 0xBB, 0x53 ),
-    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0x05, 0xC6, 0x21, 0x6B, 0xDF, 0x03, 0x72 ),
-    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 ),
-};
-#define sm2_T NULL
-#endif /* MBEDTLS_ECP_DP_SM2_ENABLED */
-/*
  * Create an MPI from embedded constants
  * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint))
  */
@@ -4823,11 +4781,6 @@
             return LOAD_GROUP_A(brainpoolP384r1);
 #endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
 
-#if defined(MBEDTLS_ECP_DP_SM2_ENABLED)
-        case MBEDTLS_ECP_DP_SM2:
-            return( LOAD_GROUP_A( sm2 ) );
-#endif /* MBEDTLS_ECP_DP_SM2_ENABLED */
-
 #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
         case MBEDTLS_ECP_DP_BP512R1:
             return LOAD_GROUP_A(brainpoolP512r1);
diff --git a/lib/libmbedtls/mbedtls/library/entropy.c b/lib/libmbedtls/mbedtls/library/entropy.c
index e3bc851..7dcf067 100644
--- a/lib/libmbedtls/mbedtls/library/entropy.c
+++ b/lib/libmbedtls/mbedtls/library/entropy.c
@@ -61,6 +61,10 @@
 
 void mbedtls_entropy_free(mbedtls_entropy_context *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     /* If the context was already free, don't call free() again.
      * This is important for mutexes which don't allow double-free. */
     if (ctx->accumulator_started == -1) {
diff --git a/lib/libmbedtls/mbedtls/library/entropy_poll.c b/lib/libmbedtls/mbedtls/library/entropy_poll.c
index 794ee03..611768c 100644
--- a/lib/libmbedtls/mbedtls/library/entropy_poll.c
+++ b/lib/libmbedtls/mbedtls/library/entropy_poll.c
@@ -5,10 +5,12 @@
  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  */
 
-#if defined(__linux__) || defined(__midipix__) && !defined(_GNU_SOURCE)
+#if defined(__linux__) || defined(__midipix__)
 /* Ensure that syscall() is available even when compiling with -std=c99 */
+#if !defined(_GNU_SOURCE)
 #define _GNU_SOURCE
 #endif
+#endif
 
 #include "common.h"
 
diff --git a/lib/libmbedtls/mbedtls/library/error.c b/lib/libmbedtls/mbedtls/library/error.c
index 84b637a..6ad7162 100644
--- a/lib/libmbedtls/mbedtls/library/error.c
+++ b/lib/libmbedtls/mbedtls/library/error.c
@@ -418,7 +418,7 @@
         case -(MBEDTLS_ERR_SSL_BAD_CERTIFICATE):
             return( "SSL - Processing of the Certificate handshake message failed" );
         case -(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET):
-            return( "SSL - * Received NewSessionTicket Post Handshake Message. This error code is experimental and may be changed or removed without notice" );
+            return( "SSL - A TLS 1.3 NewSessionTicket message has been received" );
         case -(MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA):
             return( "SSL - Not possible to read early data" );
         case -(MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA):
diff --git a/lib/libmbedtls/mbedtls/library/lmots.c b/lib/libmbedtls/mbedtls/library/lmots.c
index c7091b4..c51cb41 100644
--- a/lib/libmbedtls/mbedtls/library/lmots.c
+++ b/lib/libmbedtls/mbedtls/library/lmots.c
@@ -387,6 +387,10 @@
 
 void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     mbedtls_platform_zeroize(ctx, sizeof(*ctx));
 }
 
@@ -556,6 +560,10 @@
 
 void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     mbedtls_platform_zeroize(ctx,
                              sizeof(*ctx));
 }
diff --git a/lib/libmbedtls/mbedtls/library/lms.c b/lib/libmbedtls/mbedtls/library/lms.c
index 8d3cae0..7f7bec0 100644
--- a/lib/libmbedtls/mbedtls/library/lms.c
+++ b/lib/libmbedtls/mbedtls/library/lms.c
@@ -229,6 +229,10 @@
 
 void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     mbedtls_platform_zeroize(ctx, sizeof(*ctx));
 }
 
@@ -528,6 +532,10 @@
 
 void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     unsigned int idx;
 
     if (ctx->have_private_key) {
diff --git a/lib/libmbedtls/mbedtls/library/md.c b/lib/libmbedtls/mbedtls/library/md.c
index dbd4e91..c95846a 100644
--- a/lib/libmbedtls/mbedtls/library/md.c
+++ b/lib/libmbedtls/mbedtls/library/md.c
@@ -41,7 +41,7 @@
 #include "mbedtls/sha512.h"
 #include "mbedtls/sha3.h"
 
-#if defined(MBEDTLS_PSA_CRYPTO_C)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
 #include <psa/crypto.h>
 #include "md_psa.h"
 #include "psa_util_internal.h"
@@ -403,9 +403,6 @@
             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
     }
 
-    if (dst->hmac_ctx != NULL && src->hmac_ctx != NULL)
-        memcpy(dst->hmac_ctx, src->hmac_ctx, 2 * src->md_info->block_size);
-
     return 0;
 }
 
@@ -764,13 +761,13 @@
     return md_info->type;
 }
 
-#if defined(MBEDTLS_PSA_CRYPTO_C)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
 int mbedtls_md_error_from_psa(psa_status_t status)
 {
     return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_md_errors,
                                    psa_generic_status_to_mbedtls);
 }
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
 
 
 /************************************************************************
diff --git a/lib/libmbedtls/mbedtls/library/net_sockets.c b/lib/libmbedtls/mbedtls/library/net_sockets.c
index edec587..ef89a88 100644
--- a/lib/libmbedtls/mbedtls/library/net_sockets.c
+++ b/lib/libmbedtls/mbedtls/library/net_sockets.c
@@ -683,7 +683,7 @@
  */
 void mbedtls_net_free(mbedtls_net_context *ctx)
 {
-    if (ctx->fd == -1) {
+    if (ctx == NULL || ctx->fd == -1) {
         return;
     }
 
diff --git a/lib/libmbedtls/mbedtls/library/nist_kw.c b/lib/libmbedtls/mbedtls/library/nist_kw.c
index f15425b..8faafe4 100644
--- a/lib/libmbedtls/mbedtls/library/nist_kw.c
+++ b/lib/libmbedtls/mbedtls/library/nist_kw.c
@@ -102,6 +102,10 @@
  */
 void mbedtls_nist_kw_free(mbedtls_nist_kw_context *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     mbedtls_cipher_free(&ctx->cipher_ctx);
     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_nist_kw_context));
 }
diff --git a/lib/libmbedtls/mbedtls/library/pem.c b/lib/libmbedtls/mbedtls/library/pem.c
index 0fee5df..0207601 100644
--- a/lib/libmbedtls/mbedtls/library/pem.c
+++ b/lib/libmbedtls/mbedtls/library/pem.c
@@ -481,6 +481,10 @@
 
 void mbedtls_pem_free(mbedtls_pem_context *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     if (ctx->buf != NULL) {
         mbedtls_zeroize_and_free(ctx->buf, ctx->buflen);
     }
diff --git a/lib/libmbedtls/mbedtls/library/pk.c b/lib/libmbedtls/mbedtls/library/pk.c
index 097777f..3fe51ea 100644
--- a/lib/libmbedtls/mbedtls/library/pk.c
+++ b/lib/libmbedtls/mbedtls/library/pk.c
@@ -868,7 +868,6 @@
     psa_status_t status;
     psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_type_t key_type;
-    psa_algorithm_t alg_type;
     size_t key_bits;
     /* Use a buffer size large enough to contain either a key pair or public key. */
     unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE];
@@ -899,7 +898,6 @@
         key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
     }
     key_bits = psa_get_key_bits(&key_attr);
-    alg_type = psa_get_key_algorithm(&key_attr);
 
 #if defined(MBEDTLS_RSA_C)
     if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) ||
@@ -919,6 +917,7 @@
             goto exit;
         }
 
+        psa_algorithm_t alg_type = psa_get_key_algorithm(&key_attr);
         mbedtls_md_type_t md_type = MBEDTLS_MD_NONE;
         if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) {
             md_type = mbedtls_md_type_from_psa_alg(alg_type);
@@ -968,6 +967,7 @@
     } else
 #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     {
+        (void) key_bits;
         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
     }
 
@@ -1327,43 +1327,19 @@
     }
 
     if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
-        psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
-        psa_algorithm_t psa_alg, sign_alg;
-#if defined(MBEDTLS_PSA_CRYPTO_C)
-        psa_algorithm_t psa_enrollment_alg;
-#endif /* MBEDTLS_PSA_CRYPTO_C */
         psa_status_t status;
 
-        status = psa_get_key_attributes(ctx->priv_id, &key_attr);
-        if (status != PSA_SUCCESS) {
-            return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
-        }
-        psa_alg = psa_get_key_algorithm(&key_attr);
-#if defined(MBEDTLS_PSA_CRYPTO_C)
-        psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr);
-#endif /* MBEDTLS_PSA_CRYPTO_C */
-        psa_reset_key_attributes(&key_attr);
-
-        /* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between
-         * alg and enrollment alg should be of type RSA_PSS. */
-        if (PSA_ALG_IS_RSA_PSS(psa_alg)) {
-            sign_alg = psa_alg;
-        }
-#if defined(MBEDTLS_PSA_CRYPTO_C)
-        else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) {
-            sign_alg = psa_enrollment_alg;
-        }
-#endif /* MBEDTLS_PSA_CRYPTO_C */
-        else {
-            /* The opaque key has no RSA PSS algorithm associated. */
-            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
-        }
-        /* Adjust the hashing algorithm. */
-        sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg);
-
-        status = psa_sign_hash(ctx->priv_id, sign_alg,
+        /* PSA_ALG_RSA_PSS() behaves the same as PSA_ALG_RSA_PSS_ANY_SALT() when
+         * performing a signature, but they are encoded differently. Instead of
+         * extracting the proper one from the wrapped key policy, just try both. */
+        status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
                                hash, hash_len,
                                sig, sig_size, sig_len);
+        if (status == PSA_ERROR_NOT_PERMITTED) {
+            status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg),
+                                   hash, hash_len,
+                                   sig, sig_size, sig_len);
+        }
         return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
     }
 
diff --git a/lib/libmbedtls/mbedtls/library/pkwrite.c b/lib/libmbedtls/mbedtls/library/pkwrite.c
index 5e009c5..2a69844 100644
--- a/lib/libmbedtls/mbedtls/library/pkwrite.c
+++ b/lib/libmbedtls/mbedtls/library/pkwrite.c
@@ -65,17 +65,21 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
         uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
-        size_t len = 0, tmp_len = 0;
+        size_t tmp_len = 0;
 
         if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) {
             return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
         }
+        /* Ensure there's enough space in the provided buffer before copying data into it. */
+        if (tmp_len > (size_t) (*p - buf)) {
+            mbedtls_platform_zeroize(tmp, sizeof(tmp));
+            return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+        }
         *p -= tmp_len;
         memcpy(*p, tmp, tmp_len);
-        len += tmp_len;
         mbedtls_platform_zeroize(tmp, sizeof(tmp));
 
-        return (int) len;
+        return (int) tmp_len;
     }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
     return mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), buf, p);
@@ -125,6 +129,10 @@
         if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
             return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
         }
+        /* Ensure there's enough space in the provided buffer before copying data into it. */
+        if (len > (size_t) (*p - start)) {
+            return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+        }
         *p -= len;
         memcpy(*p, buf, len);
         return (int) len;
diff --git a/lib/libmbedtls/mbedtls/library/platform_util.c b/lib/libmbedtls/mbedtls/library/platform_util.c
index 0741bf5..19ef07a 100644
--- a/lib/libmbedtls/mbedtls/library/platform_util.c
+++ b/lib/libmbedtls/mbedtls/library/platform_util.c
@@ -149,7 +149,7 @@
 #include <time.h>
 #if !defined(_WIN32) && (defined(unix) || \
     defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
-    defined(__MACH__)) || defined__midipix__)
+    defined(__MACH__)) || defined(__midipix__))
 #include <unistd.h>
 #endif /* !_WIN32 && (unix || __unix || __unix__ ||
         * (__APPLE__ && __MACH__) || __midipix__) */
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto.c b/lib/libmbedtls/mbedtls/library/psa_crypto.c
index 969c695..c4f41db 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto.c
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto.c
@@ -1210,15 +1210,15 @@
         case PSA_SLOT_PENDING_DELETION:
             /* In this state psa_wipe_key_slot() must only be called if the
              * caller is the last reader. */
-            if (slot->registered_readers != 1) {
-                MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 1);
+            if (slot->var.occupied.registered_readers != 1) {
+                MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 1);
                 status = PSA_ERROR_CORRUPTION_DETECTED;
             }
             break;
         case PSA_SLOT_FILLING:
             /* In this state registered_readers must be 0. */
-            if (slot->registered_readers != 0) {
-                MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 0);
+            if (slot->var.occupied.registered_readers != 0) {
+                MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 0);
                 status = PSA_ERROR_CORRUPTION_DETECTED;
             }
             break;
@@ -1232,6 +1232,11 @@
             status = PSA_ERROR_CORRUPTION_DETECTED;
     }
 
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+    size_t slice_index = slot->slice_index;
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
+
     /* Multipart operations may still be using the key. This is safe
      * because all multipart operation objects are independent from
      * the key slot: if they need to access the key after the setup
@@ -1242,6 +1247,17 @@
      * zeroize because the metadata is not particularly sensitive.
      * This memset also sets the slot's state to PSA_SLOT_EMPTY. */
     memset(slot, 0, sizeof(*slot));
+
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+    /* If the slot is already corrupted, something went deeply wrong,
+     * like a thread still using the slot or a stray pointer leading
+     * to the slot's memory being used for another object. Let the slot
+     * leak rather than make the corruption worse. */
+    if (status == PSA_SUCCESS) {
+        status = psa_free_key_slot(slice_index, slot);
+    }
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
     return status;
 }
 
@@ -1753,8 +1769,6 @@
     psa_se_drv_table_entry_t **p_drv)
 {
     psa_status_t status;
-    psa_key_id_t volatile_key_id;
-    psa_key_slot_t *slot;
 
     (void) method;
     *p_drv = NULL;
@@ -1764,11 +1778,16 @@
         return status;
     }
 
+    int key_is_volatile = PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime);
+    psa_key_id_t volatile_key_id;
+
 #if defined(MBEDTLS_THREADING_C)
     PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
                               &mbedtls_threading_key_slot_mutex));
 #endif
-    status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
+    status = psa_reserve_free_key_slot(
+        key_is_volatile ? &volatile_key_id : NULL,
+        p_slot);
 #if defined(MBEDTLS_THREADING_C)
     PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
                               &mbedtls_threading_key_slot_mutex));
@@ -1776,7 +1795,7 @@
     if (status != PSA_SUCCESS) {
         return status;
     }
-    slot = *p_slot;
+    psa_key_slot_t *slot = *p_slot;
 
     /* We're storing the declared bit-size of the key. It's up to each
      * creation mechanism to verify that this information is correct.
@@ -1787,7 +1806,7 @@
      * definition. */
 
     slot->attr = *attributes;
-    if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
+    if (key_is_volatile) {
 #if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
         slot->attr.id = volatile_key_id;
 #else
@@ -1835,6 +1854,9 @@
 
         status = psa_copy_key_material_into_slot(
             slot, (uint8_t *) (&slot_number), sizeof(slot_number));
+        if (status != PSA_SUCCESS) {
+            return status;
+        }
     }
 
     if (*p_drv == NULL && method == PSA_KEY_CREATION_REGISTER) {
@@ -2146,6 +2168,14 @@
         return PSA_ERROR_NOT_SUPPORTED;
     }
 
+    /* Not usable with volatile keys, even with an appropriate location,
+     * due to the API design.
+     * https://github.com/Mbed-TLS/mbedtls/issues/9253
+     */
+    if (PSA_KEY_LIFETIME_IS_VOLATILE(psa_get_key_lifetime(attributes))) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
     status = psa_start_key_creation(PSA_KEY_CREATION_REGISTER, attributes,
                                     &slot, &driver);
     if (status != PSA_SUCCESS) {
@@ -4628,11 +4658,7 @@
         goto exit;
     }
 
-    if (alg == PSA_ALG_CCM_STAR_NO_TAG &&
-        input_length < PSA_BLOCK_CIPHER_BLOCK_LENGTH(slot->attr.type)) {
-        status = PSA_ERROR_INVALID_ARGUMENT;
-        goto exit;
-    } else if (input_length < PSA_CIPHER_IV_LENGTH(slot->attr.type, alg)) {
+    if (input_length < PSA_CIPHER_IV_LENGTH(slot->attr.type, alg)) {
         status = PSA_ERROR_INVALID_ARGUMENT;
         goto exit;
     }
@@ -5194,6 +5220,12 @@
         goto exit;
     }
 
+    /* No input to add (zero length), nothing to do. */
+    if (input_length == 0) {
+        status = PSA_SUCCESS;
+        goto exit;
+    }
+
     if (operation->lengths_set) {
         if (operation->ad_remaining < input_length) {
             status = PSA_ERROR_INVALID_ARGUMENT;
@@ -6407,27 +6439,28 @@
     return status;
 }
 
-static const psa_key_production_parameters_t default_production_parameters =
-    PSA_KEY_PRODUCTION_PARAMETERS_INIT;
+static const psa_custom_key_parameters_t default_custom_production =
+    PSA_CUSTOM_KEY_PARAMETERS_INIT;
 
-int psa_key_production_parameters_are_default(
-    const psa_key_production_parameters_t *params,
-    size_t params_data_length)
+int psa_custom_key_parameters_are_default(
+    const psa_custom_key_parameters_t *custom,
+    size_t custom_data_length)
 {
-    if (params->flags != 0) {
+    if (custom->flags != 0) {
         return 0;
     }
-    if (params_data_length != 0) {
+    if (custom_data_length != 0) {
         return 0;
     }
     return 1;
 }
 
-psa_status_t psa_key_derivation_output_key_ext(
+psa_status_t psa_key_derivation_output_key_custom(
     const psa_key_attributes_t *attributes,
     psa_key_derivation_operation_t *operation,
-    const psa_key_production_parameters_t *params,
-    size_t params_data_length,
+    const psa_custom_key_parameters_t *custom,
+    const uint8_t *custom_data,
+    size_t custom_data_length,
     mbedtls_svc_key_id_t *key)
 {
     psa_status_t status;
@@ -6442,7 +6475,8 @@
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
-    if (!psa_key_production_parameters_are_default(params, params_data_length)) {
+    (void) custom_data;         /* We only accept 0-length data */
+    if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) {
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
@@ -6477,14 +6511,29 @@
     return status;
 }
 
+psa_status_t psa_key_derivation_output_key_ext(
+    const psa_key_attributes_t *attributes,
+    psa_key_derivation_operation_t *operation,
+    const psa_key_production_parameters_t *params,
+    size_t params_data_length,
+    mbedtls_svc_key_id_t *key)
+{
+    return psa_key_derivation_output_key_custom(
+        attributes, operation,
+        (const psa_custom_key_parameters_t *) params,
+        params->data, params_data_length,
+        key);
+}
+
 psa_status_t psa_key_derivation_output_key(
     const psa_key_attributes_t *attributes,
     psa_key_derivation_operation_t *operation,
     mbedtls_svc_key_id_t *key)
 {
-    return psa_key_derivation_output_key_ext(attributes, operation,
-                                             &default_production_parameters, 0,
-                                             key);
+    return psa_key_derivation_output_key_custom(attributes, operation,
+                                                &default_custom_production,
+                                                NULL, 0,
+                                                key);
 }
 
 
@@ -7858,15 +7907,18 @@
 
 psa_status_t psa_generate_key_internal(
     const psa_key_attributes_t *attributes,
-    const psa_key_production_parameters_t *params, size_t params_data_length,
+    const psa_custom_key_parameters_t *custom,
+    const uint8_t *custom_data,
+    size_t custom_data_length,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_key_type_t type = attributes->type;
 
     /* Only used for RSA */
-    (void) params;
-    (void) params_data_length;
+    (void) custom;
+    (void) custom_data;
+    (void) custom_data_length;
 
     if (key_type_is_raw_bytes(type)) {
         status = psa_generate_random_internal(key_buffer, key_buffer_size);
@@ -7884,7 +7936,7 @@
 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
     if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
         return mbedtls_psa_rsa_generate_key(attributes,
-                                            params, params_data_length,
+                                            custom_data, custom_data_length,
                                             key_buffer,
                                             key_buffer_size,
                                             key_buffer_length);
@@ -7916,10 +7968,11 @@
     return PSA_SUCCESS;
 }
 
-psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
-                                  const psa_key_production_parameters_t *params,
-                                  size_t params_data_length,
-                                  mbedtls_svc_key_id_t *key)
+psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes,
+                                     const psa_custom_key_parameters_t *custom,
+                                     const uint8_t *custom_data,
+                                     size_t custom_data_length,
+                                     mbedtls_svc_key_id_t *key)
 {
     psa_status_t status;
     psa_key_slot_t *slot = NULL;
@@ -7941,12 +7994,12 @@
 
 #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
     if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
-        if (params->flags != 0) {
+        if (custom->flags != 0) {
             return PSA_ERROR_INVALID_ARGUMENT;
         }
     } else
 #endif
-    if (!psa_key_production_parameters_are_default(params, params_data_length)) {
+    if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) {
         return PSA_ERROR_INVALID_ARGUMENT;
     }
 
@@ -7987,7 +8040,8 @@
     }
 
     status = psa_driver_wrapper_generate_key(attributes,
-                                             params, params_data_length,
+                                             custom,
+                                             custom_data, custom_data_length,
                                              slot->key.data, slot->key.bytes,
                                              &slot->key.bytes);
     if (status != PSA_SUCCESS) {
@@ -8005,12 +8059,25 @@
     return status;
 }
 
+psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
+                                  const psa_key_production_parameters_t *params,
+                                  size_t params_data_length,
+                                  mbedtls_svc_key_id_t *key)
+{
+    return psa_generate_key_custom(
+        attributes,
+        (const psa_custom_key_parameters_t *) params,
+        params->data, params_data_length,
+        key);
+}
+
 psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
                               mbedtls_svc_key_id_t *key)
 {
-    return psa_generate_key_ext(attributes,
-                                &default_production_parameters, 0,
-                                key);
+    return psa_generate_key_custom(attributes,
+                                   &default_custom_production,
+                                   NULL, 0,
+                                   key);
 }
 
 /****************************************************************/
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto_cipher.c b/lib/libmbedtls/mbedtls/library/psa_crypto_cipher.c
index 881d673..3216c94 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto_cipher.c
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto_cipher.c
@@ -263,7 +263,7 @@
 {
     mbedtls_cipher_mode_t mode;
     psa_status_t status;
-    mbedtls_cipher_id_t cipher_id_tmp;
+    mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE;
 
     status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
     if (status != PSA_SUCCESS) {
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto_core.h b/lib/libmbedtls/mbedtls/library/psa_crypto_core.h
index 9462d2e..21e7559 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto_core.h
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto_core.h
@@ -59,6 +59,8 @@
  * and metadata for one key.
  */
 typedef struct {
+    /* This field is accessed in a lot of places. Putting it first
+     * reduces the code size. */
     psa_key_attributes_t attr;
 
     /*
@@ -78,35 +80,77 @@
      * slots that are in a suitable state for the function.
      * For example, psa_get_and_lock_key_slot_in_memory, which finds a slot
      * containing a given key ID, will only check slots whose state variable is
-     * PSA_SLOT_FULL. */
+     * PSA_SLOT_FULL.
+     */
     psa_key_slot_state_t state;
 
-    /*
-     * Number of functions registered as reading the material in the key slot.
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+    /* The index of the slice containing this slot.
+     * This field must be filled if the slot contains a key
+     * (including keys being created or destroyed), and can be either
+     * filled or 0 when the slot is free.
      *
-     * Library functions must not write directly to registered_readers
-     *
-     * A function must call psa_register_read(slot) before reading the current
-     * contents of the slot for an operation.
-     * They then must call psa_unregister_read(slot) once they have finished
-     * reading the current contents of the slot. If the key slot mutex is not
-     * held (when mutexes are enabled), this call must be done via a call to
-     * psa_unregister_read_under_mutex(slot).
-     * A function must call psa_key_slot_has_readers(slot) to check if
-     * the slot is in use for reading.
-     *
-     * This counter is used to prevent resetting the key slot while the library
-     * may access it. For example, such control is needed in the following
-     * scenarios:
-     * . In case of key slot starvation, all key slots contain the description
-     *   of a key, and the library asks for the description of a persistent
-     *   key not present in the key slots, the key slots currently accessed by
-     *   the library cannot be reclaimed to free a key slot to load the
-     *   persistent key.
-     * . In case of a multi-threaded application where one thread asks to close
-     *   or purge or destroy a key while it is in use by the library through
-     *   another thread. */
-    size_t registered_readers;
+     * In most cases, the slice index can be deduced from the key identifer.
+     * We keep it in a separate field for robustness (it reduces the chance
+     * that a coding mistake in the key store will result in accessing the
+     * wrong slice), and also so that it's available even on code paths
+     * during creation or destruction where the key identifier might not be
+     * filled in.
+     * */
+    uint8_t slice_index;
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
+    union {
+        struct {
+            /* The index of the next slot in the free list for this
+             * slice, relative * to the next array element.
+             *
+             * That is, 0 means the next slot, 1 means the next slot
+             * but one, etc. -1 would mean the slot itself. -2 means
+             * the previous slot, etc.
+             *
+             * If this is beyond the array length, the free list ends with the
+             * current element.
+             *
+             * The reason for this strange encoding is that 0 means the next
+             * element. This way, when we allocate a slice and initialize it
+             * to all-zero, the slice is ready for use, with a free list that
+             * consists of all the slots in order.
+             */
+            int32_t next_free_relative_to_next;
+        } free;
+
+        struct {
+            /*
+             * Number of functions registered as reading the material in the key slot.
+             *
+             * Library functions must not write directly to registered_readers
+             *
+             * A function must call psa_register_read(slot) before reading
+             * the current contents of the slot for an operation.
+             * They then must call psa_unregister_read(slot) once they have
+             * finished reading the current contents of the slot. If the key
+             * slot mutex is not held (when mutexes are enabled), this call
+             * must be done via a call to
+             * psa_unregister_read_under_mutex(slot).
+             * A function must call psa_key_slot_has_readers(slot) to check if
+             * the slot is in use for reading.
+             *
+             * This counter is used to prevent resetting the key slot while
+             * the library may access it. For example, such control is needed
+             * in the following scenarios:
+             * . In case of key slot starvation, all key slots contain the
+             *   description of a key, and the library asks for the
+             *   description of a persistent key not present in the
+             *   key slots, the key slots currently accessed by the
+             *   library cannot be reclaimed to free a key slot to load
+             *   the persistent key.
+             * . In case of a multi-threaded application where one thread
+             *   asks to close or purge or destroy a key while it is in use
+             *   by the library through another thread. */
+            size_t registered_readers;
+        } occupied;
+    } var;
 
     /* Dynamically allocated key data buffer.
      * Format as specified in psa_export_key(). */
@@ -169,7 +213,7 @@
  */
 static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot)
 {
-    return slot->registered_readers > 0;
+    return slot->var.occupied.registered_readers > 0;
 }
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@@ -343,17 +387,18 @@
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length);
 
-/** Whether a key production parameters structure is the default.
+/** Whether a key custom production parameters structure is the default.
  *
- * Calls to a key generation driver with non-default production parameters
+ * Calls to a key generation driver with non-default custom production parameters
  * require a driver supporting custom production parameters.
  *
- * \param[in] params            The key production parameters to check.
- * \param params_data_length    Size of `params->data` in bytes.
+ * \param[in] custom            The key custom production parameters to check.
+ * \param custom_data_length    Size of the associated variable-length data
+ *                              in bytes.
  */
-int psa_key_production_parameters_are_default(
-    const psa_key_production_parameters_t *params,
-    size_t params_data_length);
+int psa_custom_key_parameters_are_default(
+    const psa_custom_key_parameters_t *custom,
+    size_t custom_data_length);
 
 /**
  * \brief Generate a key.
@@ -362,9 +407,9 @@
  *       entry point.
  *
  * \param[in]  attributes         The attributes for the key to generate.
- * \param[in]  params             The production parameters from
- *                                psa_generate_key_ext().
- * \param      params_data_length The size of `params->data` in bytes.
+ * \param[in] custom              Custom parameters for the key generation.
+ * \param[in] custom_data         Variable-length data associated with \c custom.
+ * \param custom_data_length      Length of `custom_data` in bytes.
  * \param[out] key_buffer         Buffer where the key data is to be written.
  * \param[in]  key_buffer_size    Size of \p key_buffer in bytes.
  * \param[out] key_buffer_length  On success, the number of bytes written in
@@ -379,8 +424,9 @@
  *         The size of \p key_buffer is too small.
  */
 psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes,
-                                       const psa_key_production_parameters_t *params,
-                                       size_t params_data_length,
+                                       const psa_custom_key_parameters_t *custom,
+                                       const uint8_t *custom_data,
+                                       size_t custom_data_length,
                                        uint8_t *key_buffer,
                                        size_t key_buffer_size,
                                        size_t *key_buffer_length);
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto_driver_wrappers.h b/lib/libmbedtls/mbedtls/library/psa_crypto_driver_wrappers.h
index ea6aee3..b901557 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto_driver_wrappers.h
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto_driver_wrappers.h
@@ -730,7 +730,8 @@
 
 static inline psa_status_t psa_driver_wrapper_generate_key(
     const psa_key_attributes_t *attributes,
-    const psa_key_production_parameters_t *params, size_t params_data_length,
+    const psa_custom_key_parameters_t *custom,
+    const uint8_t *custom_data, size_t custom_data_length,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
@@ -739,7 +740,7 @@
 
 #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
     int is_default_production =
-        psa_key_production_parameters_are_default(params, params_data_length);
+        psa_custom_key_parameters_are_default(custom, custom_data_length);
     if( location != PSA_KEY_LOCATION_LOCAL_STORAGE && !is_default_production )
     {
         /* We don't support passing custom production parameters
@@ -810,7 +811,7 @@
 
             /* Software fallback */
             status = psa_generate_key_internal(
-                attributes, params, params_data_length,
+                attributes, custom, custom_data, custom_data_length,
                 key_buffer, key_buffer_size, key_buffer_length );
             break;
 
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto_random_impl.h b/lib/libmbedtls/mbedtls/library/psa_crypto_random_impl.h
index 533fb2e..5b51631 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto_random_impl.h
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto_random_impl.h
@@ -21,13 +21,10 @@
 #include "mbedtls/entropy.h"
 
 /* Choose a DRBG based on configuration and availability */
-#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
-
-#include "mbedtls/hmac_drbg.h"
-
-#elif defined(MBEDTLS_CTR_DRBG_C)
+#if defined(MBEDTLS_CTR_DRBG_C)
 
 #include "mbedtls/ctr_drbg.h"
+#undef MBEDTLS_PSA_HMAC_DRBG_MD_TYPE
 
 #elif defined(MBEDTLS_HMAC_DRBG_C)
 
@@ -49,17 +46,11 @@
 #error "No hash algorithm available for HMAC_DBRG."
 #endif
 
-#else /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
+#else /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
 
 #error "No DRBG module available for the psa_crypto module."
 
-#endif /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
-
-#if defined(MBEDTLS_CTR_DRBG_C)
-#include "mbedtls/ctr_drbg.h"
-#elif defined(MBEDTLS_HMAC_DRBG_C)
-#include "mbedtls/hmac_drbg.h"
-#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
+#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
 
 /* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */
 #if defined(MBEDTLS_CTR_DRBG_C)
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto_rsa.c b/lib/libmbedtls/mbedtls/library/psa_crypto_rsa.c
index 2f613b3..38dc3b8 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto_rsa.c
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto_rsa.c
@@ -197,16 +197,14 @@
 
     status = mbedtls_psa_rsa_load_representation(
         attributes->type, key_buffer, key_buffer_size, &rsa);
-    if (status != PSA_SUCCESS) {
-        return status;
+    if (status == PSA_SUCCESS) {
+        status = mbedtls_psa_rsa_export_key(PSA_KEY_TYPE_RSA_PUBLIC_KEY,
+                                            rsa,
+                                            data,
+                                            data_size,
+                                            data_length);
     }
 
-    status = mbedtls_psa_rsa_export_key(PSA_KEY_TYPE_RSA_PUBLIC_KEY,
-                                        rsa,
-                                        data,
-                                        data_size,
-                                        data_length);
-
     mbedtls_rsa_free(rsa);
     mbedtls_free(rsa);
 
@@ -241,7 +239,7 @@
 
 psa_status_t mbedtls_psa_rsa_generate_key(
     const psa_key_attributes_t *attributes,
-    const psa_key_production_parameters_t *params, size_t params_data_length,
+    const uint8_t *custom_data, size_t custom_data_length,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
 {
     psa_status_t status;
@@ -249,8 +247,8 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     int exponent = 65537;
 
-    if (params_data_length != 0) {
-        status = psa_rsa_read_exponent(params->data, params_data_length,
+    if (custom_data_length != 0) {
+        status = psa_rsa_read_exponent(custom_data, custom_data_length,
                                        &exponent);
         if (status != PSA_SUCCESS) {
             return status;
@@ -264,6 +262,7 @@
                               (unsigned int) attributes->bits,
                               exponent);
     if (ret != 0) {
+        mbedtls_rsa_free(&rsa);
         return mbedtls_to_psa_error(ret);
     }
 
@@ -330,7 +329,7 @@
                                                  key_buffer_size,
                                                  &rsa);
     if (status != PSA_SUCCESS) {
-        return status;
+        goto exit;
     }
 
     status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto_rsa.h b/lib/libmbedtls/mbedtls/library/psa_crypto_rsa.h
index ffeef26..1a78000 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto_rsa.h
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto_rsa.h
@@ -105,17 +105,11 @@
 /**
  * \brief Generate an RSA key.
  *
- * \note The signature of the function is that of a PSA driver generate_key
- *       entry point.
- *
  * \param[in]  attributes         The attributes for the RSA key to generate.
- * \param[in]  params             Production parameters for the key
- *                                generation. This function only uses
- *                                `params->data`,
- *                                which contains the public exponent.
+ * \param[in]  custom_data        The public exponent to use.
  *                                This can be a null pointer if
  *                                \c params_data_length is 0.
- * \param params_data_length      Length of `params->data` in bytes.
+ * \param custom_data_length      Length of \p custom_data in bytes.
  *                                This can be 0, in which case the
  *                                public exponent will be 65537.
  * \param[out] key_buffer         Buffer where the key data is to be written.
@@ -132,7 +126,7 @@
  */
 psa_status_t mbedtls_psa_rsa_generate_key(
     const psa_key_attributes_t *attributes,
-    const psa_key_production_parameters_t *params, size_t params_data_length,
+    const uint8_t *custom_data, size_t custom_data_length,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
 
 /** Sign an already-calculated hash with an RSA private key.
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto_slot_management.c b/lib/libmbedtls/mbedtls/library/psa_crypto_slot_management.c
index b184ed0..9850d8c 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto_slot_management.c
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto_slot_management.c
@@ -27,8 +27,166 @@
 #include "mbedtls/threading.h"
 #endif
 
+
+
+/* Make sure we have distinct ranges of key identifiers for distinct
+ * purposes. */
+MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_USER_MIN < PSA_KEY_ID_USER_MAX,
+                      "Empty user key ID range");
+MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN < PSA_KEY_ID_VENDOR_MAX,
+                      "Empty vendor key ID range");
+MBEDTLS_STATIC_ASSERT(MBEDTLS_PSA_KEY_ID_BUILTIN_MIN < MBEDTLS_PSA_KEY_ID_BUILTIN_MAX,
+                      "Empty builtin key ID range");
+MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MIN < PSA_KEY_ID_VOLATILE_MAX,
+                      "Empty volatile key ID range");
+
+MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_USER_MAX < PSA_KEY_ID_VENDOR_MIN ||
+                      PSA_KEY_ID_VENDOR_MAX < PSA_KEY_ID_USER_MIN,
+                      "Overlap between user key IDs and vendor key IDs");
+
+MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN <= MBEDTLS_PSA_KEY_ID_BUILTIN_MIN &&
+                      MBEDTLS_PSA_KEY_ID_BUILTIN_MAX <= PSA_KEY_ID_VENDOR_MAX,
+                      "Builtin key identifiers are not in the vendor range");
+
+MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN <= PSA_KEY_ID_VOLATILE_MIN &&
+                      PSA_KEY_ID_VOLATILE_MAX <= PSA_KEY_ID_VENDOR_MAX,
+                      "Volatile key identifiers are not in the vendor range");
+
+MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN ||
+                      MBEDTLS_PSA_KEY_ID_BUILTIN_MAX < PSA_KEY_ID_VOLATILE_MIN,
+                      "Overlap between builtin key IDs and volatile key IDs");
+
+
+
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+
+/* Dynamic key store.
+ *
+ * The key store consists of multiple slices.
+ *
+ * The volatile keys are stored in variable-sized tables called slices.
+ * Slices are allocated on demand and deallocated when possible.
+ * The size of slices increases exponentially, so the average overhead
+ * (number of slots that are allocated but not used) is roughly
+ * proportional to the number of keys (with a factor that grows
+ * when the key store is fragmented).
+ *
+ * One slice is dedicated to the cache of persistent and built-in keys.
+ * For simplicity, they are separated from volatile keys. This cache
+ * slice has a fixed size and has the slice index KEY_SLOT_CACHE_SLICE_INDEX,
+ * located after the slices for volatile keys.
+ */
+
+/* Size of the last slice containing the cache of persistent and built-in keys. */
+#define PERSISTENT_KEY_CACHE_COUNT MBEDTLS_PSA_KEY_SLOT_COUNT
+
+/* Volatile keys are stored in slices 0 through
+ * (KEY_SLOT_VOLATILE_SLICE_COUNT - 1) inclusive.
+ * Each slice is twice the size of the previous slice.
+ * Volatile key identifiers encode the slice number as follows:
+ *     bits 30..31:  0b10 (mandated by the PSA Crypto specification).
+ *     bits 25..29:  slice index (0...KEY_SLOT_VOLATILE_SLICE_COUNT-1)
+ *     bits 0..24:   slot index in slice
+ */
+#define KEY_ID_SLOT_INDEX_WIDTH 25u
+#define KEY_ID_SLICE_INDEX_WIDTH 5u
+
+#define KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH 16u
+#define KEY_SLOT_VOLATILE_SLICE_COUNT 22u
+#define KEY_SLICE_COUNT (KEY_SLOT_VOLATILE_SLICE_COUNT + 1u)
+#define KEY_SLOT_CACHE_SLICE_INDEX KEY_SLOT_VOLATILE_SLICE_COUNT
+
+
+/* Check that the length of the largest slice (calculated as
+ * KEY_SLICE_LENGTH_MAX below) does not overflow size_t. We use
+ * an indirect method in case the calculation of KEY_SLICE_LENGTH_MAX
+ * itself overflows uintmax_t: if (BASE_LENGTH << c)
+ * overflows size_t then BASE_LENGTH > SIZE_MAX >> c.
+ */
+#if (KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH >              \
+     SIZE_MAX >> (KEY_SLOT_VOLATILE_SLICE_COUNT - 1))
+#error "Maximum slice length overflows size_t"
+#endif
+
+#if KEY_ID_SLICE_INDEX_WIDTH + KEY_ID_SLOT_INDEX_WIDTH > 30
+#error "Not enough room in volatile key IDs for slice index and slot index"
+#endif
+#if KEY_SLOT_VOLATILE_SLICE_COUNT > (1 << KEY_ID_SLICE_INDEX_WIDTH)
+#error "Too many slices to fit the slice index in a volatile key ID"
+#endif
+#define KEY_SLICE_LENGTH_MAX                                            \
+    (KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH << (KEY_SLOT_VOLATILE_SLICE_COUNT - 1))
+#if KEY_SLICE_LENGTH_MAX > 1 << KEY_ID_SLOT_INDEX_WIDTH
+#error "Not enough room in volatile key IDs for a slot index in the largest slice"
+#endif
+#if KEY_ID_SLICE_INDEX_WIDTH > 8
+#error "Slice index does not fit in uint8_t for psa_key_slot_t::slice_index"
+#endif
+
+
+/* Calculate the volatile key id to use for a given slot.
+ * This function assumes valid parameter values. */
+static psa_key_id_t volatile_key_id_of_index(size_t slice_idx,
+                                             size_t slot_idx)
+{
+    /* We assert above that the slice and slot indexes fit in separate
+     * bit-fields inside psa_key_id_t, which is a 32-bit type per the
+     * PSA Cryptography specification. */
+    return (psa_key_id_t) (0x40000000u |
+                           (slice_idx << KEY_ID_SLOT_INDEX_WIDTH) |
+                           slot_idx);
+}
+
+/* Calculate the slice containing the given volatile key.
+ * This function assumes valid parameter values. */
+static size_t slice_index_of_volatile_key_id(psa_key_id_t key_id)
+{
+    size_t mask = (1LU << KEY_ID_SLICE_INDEX_WIDTH) - 1;
+    return (key_id >> KEY_ID_SLOT_INDEX_WIDTH) & mask;
+}
+
+/* Calculate the index of the slot containing the given volatile key.
+ * This function assumes valid parameter values. */
+static size_t slot_index_of_volatile_key_id(psa_key_id_t key_id)
+{
+    return key_id & ((1LU << KEY_ID_SLOT_INDEX_WIDTH) - 1);
+}
+
+/* In global_data.first_free_slot_index, use this special value to
+ * indicate that the slice is full. */
+#define FREE_SLOT_INDEX_NONE ((size_t) -1)
+
+#if defined(MBEDTLS_TEST_HOOKS)
+size_t psa_key_slot_volatile_slice_count(void)
+{
+    return KEY_SLOT_VOLATILE_SLICE_COUNT;
+}
+#endif
+
+#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
+/* Static key store.
+ *
+ * All the keys (volatile or persistent) are in a single slice.
+ * We only use slices as a concept to allow some differences between
+ * static and dynamic key store management to be buried in auxiliary
+ * functions.
+ */
+
+#define PERSISTENT_KEY_CACHE_COUNT MBEDTLS_PSA_KEY_SLOT_COUNT
+#define KEY_SLICE_COUNT 1u
+#define KEY_SLOT_CACHE_SLICE_INDEX 0
+
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
+
 typedef struct {
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+    psa_key_slot_t *key_slices[KEY_SLICE_COUNT];
+    size_t first_free_slot_index[KEY_SLOT_VOLATILE_SLICE_COUNT];
+#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
     psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
     uint8_t key_slots_initialized;
 } psa_global_data_t;
 
@@ -51,6 +209,125 @@
     return initialized;
 }
 
+
+
+/** The length of the given slice in the key slot table.
+ *
+ * \param slice_idx     The slice number. It must satisfy
+ *                      0 <= slice_idx < KEY_SLICE_COUNT.
+ *
+ * \return              The number of elements in the given slice.
+ */
+static inline size_t key_slice_length(size_t slice_idx);
+
+/** Get a pointer to the slot where the given volatile key is located.
+ *
+ * \param key_id        The key identifier. It must be a valid volatile key
+ *                      identifier.
+ * \return              A pointer to the only slot that the given key
+ *                      can be in. Note that the slot may be empty or
+ *                      contain a different key.
+ */
+static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id);
+
+/** Get a pointer to an entry in the persistent key cache.
+ *
+ * \param slot_idx      The index in the table. It must satisfy
+ *                      0 <= slot_idx < PERSISTENT_KEY_CACHE_COUNT.
+ * \return              A pointer to the slot containing the given
+ *                      persistent key cache entry.
+ */
+static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx);
+
+/** Get a pointer to a slot given by slice and index.
+ *
+ * \param slice_idx     The slice number. It must satisfy
+ *                      0 <= slice_idx < KEY_SLICE_COUNT.
+ * \param slot_idx      An index in the given slice. It must satisfy
+ *                      0 <= slot_idx < key_slice_length(slice_idx).
+ *
+ * \return              A pointer to the given slot.
+ */
+static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx);
+
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+
+#if defined(MBEDTLS_TEST_HOOKS)
+size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)(size_t slice_idx) = NULL;
+#endif
+
+static inline size_t key_slice_length(size_t slice_idx)
+{
+    if (slice_idx == KEY_SLOT_CACHE_SLICE_INDEX) {
+        return PERSISTENT_KEY_CACHE_COUNT;
+    } else {
+#if defined(MBEDTLS_TEST_HOOKS)
+        if (mbedtls_test_hook_psa_volatile_key_slice_length != NULL) {
+            return mbedtls_test_hook_psa_volatile_key_slice_length(slice_idx);
+        }
+#endif
+        return KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH << slice_idx;
+    }
+}
+
+static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id)
+{
+    size_t slice_idx = slice_index_of_volatile_key_id(key_id);
+    if (slice_idx >= KEY_SLOT_VOLATILE_SLICE_COUNT) {
+        return NULL;
+    }
+    size_t slot_idx = slot_index_of_volatile_key_id(key_id);
+    if (slot_idx >= key_slice_length(slice_idx)) {
+        return NULL;
+    }
+    psa_key_slot_t *slice = global_data.key_slices[slice_idx];
+    if (slice == NULL) {
+        return NULL;
+    }
+    return &slice[slot_idx];
+}
+
+static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx)
+{
+    return &global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX][slot_idx];
+}
+
+static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx)
+{
+    return &global_data.key_slices[slice_idx][slot_idx];
+}
+
+#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
+static inline size_t key_slice_length(size_t slice_idx)
+{
+    (void) slice_idx;
+    return ARRAY_LENGTH(global_data.key_slots);
+}
+
+static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id)
+{
+    MBEDTLS_STATIC_ASSERT(ARRAY_LENGTH(global_data.key_slots) <=
+                          PSA_KEY_ID_VOLATILE_MAX - PSA_KEY_ID_VOLATILE_MIN + 1,
+                          "The key slot array is larger than the volatile key ID range");
+    return &global_data.key_slots[key_id - PSA_KEY_ID_VOLATILE_MIN];
+}
+
+static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx)
+{
+    return &global_data.key_slots[slot_idx];
+}
+
+static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx)
+{
+    (void) slice_idx;
+    return &global_data.key_slots[slot_idx];
+}
+
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
+
+
 int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok)
 {
     psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);
@@ -112,12 +389,13 @@
     psa_key_slot_t *slot = NULL;
 
     if (psa_key_id_is_volatile(key_id)) {
-        slot = &global_data.key_slots[key_id - PSA_KEY_ID_VOLATILE_MIN];
+        slot = get_volatile_key_slot(key_id);
 
         /* Check if both the PSA key identifier key_id and the owner
          * identifier of key match those of the key slot. */
-        if ((slot->state == PSA_SLOT_FULL) &&
-            (mbedtls_svc_key_id_equal(key, slot->attr.id))) {
+        if (slot != NULL &&
+            slot->state == PSA_SLOT_FULL &&
+            mbedtls_svc_key_id_equal(key, slot->attr.id)) {
             status = PSA_SUCCESS;
         } else {
             status = PSA_ERROR_DOES_NOT_EXIST;
@@ -127,8 +405,8 @@
             return PSA_ERROR_INVALID_HANDLE;
         }
 
-        for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
-            slot = &global_data.key_slots[slot_idx];
+        for (slot_idx = 0; slot_idx < PERSISTENT_KEY_CACHE_COUNT; slot_idx++) {
+            slot = get_persistent_key_slot(slot_idx);
             /* Only consider slots which are in a full state. */
             if ((slot->state == PSA_SLOT_FULL) &&
                 (mbedtls_svc_key_id_equal(key, slot->attr.id))) {
@@ -151,29 +429,169 @@
 
 psa_status_t psa_initialize_key_slots(void)
 {
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+    global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX] =
+        mbedtls_calloc(PERSISTENT_KEY_CACHE_COUNT,
+                       sizeof(*global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX]));
+    if (global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX] == NULL) {
+        return PSA_ERROR_INSUFFICIENT_MEMORY;
+    }
+#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
     /* Nothing to do: program startup and psa_wipe_all_key_slots() both
      * guarantee that the key slots are initialized to all-zero, which
      * means that all the key slots are in a valid, empty state. The global
      * data mutex is already held when calling this function, so no need to
      * lock it here, to set the flag. */
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
     global_data.key_slots_initialized = 1;
     return PSA_SUCCESS;
 }
 
 void psa_wipe_all_key_slots(void)
 {
-    size_t slot_idx;
-
-    for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
-        psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
-        slot->registered_readers = 1;
-        slot->state = PSA_SLOT_PENDING_DELETION;
-        (void) psa_wipe_key_slot(slot);
+    for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) {
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+        if (global_data.key_slices[slice_idx] == NULL) {
+            continue;
+        }
+#endif  /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+        for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) {
+            psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx);
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+            /* When MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled, calling
+             * psa_wipe_key_slot() on an unused slot is useless, but it
+             * happens to work (because we flip the state to PENDING_DELETION).
+             *
+             * When MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled,
+             * psa_wipe_key_slot() needs to have a valid slice_index
+             * field, but that value might not be correct in a
+             * free slot, so we must not call it.
+             *
+             * Bypass the call to psa_wipe_key_slot() if the slot is empty,
+             * but only if MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, to save
+             * a few bytes of code size otherwise.
+             */
+            if (slot->state == PSA_SLOT_EMPTY) {
+                continue;
+            }
+#endif
+            slot->var.occupied.registered_readers = 1;
+            slot->state = PSA_SLOT_PENDING_DELETION;
+            (void) psa_wipe_key_slot(slot);
+        }
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+        mbedtls_free(global_data.key_slices[slice_idx]);
+        global_data.key_slices[slice_idx] = NULL;
+#endif  /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
     }
+
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+    for (size_t slice_idx = 0; slice_idx < KEY_SLOT_VOLATILE_SLICE_COUNT; slice_idx++) {
+        global_data.first_free_slot_index[slice_idx] = 0;
+    }
+#endif  /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
     /* The global data mutex is already held when calling this function. */
     global_data.key_slots_initialized = 0;
 }
 
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+
+static psa_status_t psa_allocate_volatile_key_slot(psa_key_id_t *key_id,
+                                                   psa_key_slot_t **p_slot)
+{
+    size_t slice_idx;
+    for (slice_idx = 0; slice_idx < KEY_SLOT_VOLATILE_SLICE_COUNT; slice_idx++) {
+        if (global_data.first_free_slot_index[slice_idx] != FREE_SLOT_INDEX_NONE) {
+            break;
+        }
+    }
+    if (slice_idx == KEY_SLOT_VOLATILE_SLICE_COUNT) {
+        return PSA_ERROR_INSUFFICIENT_MEMORY;
+    }
+
+    if (global_data.key_slices[slice_idx] == NULL) {
+        global_data.key_slices[slice_idx] =
+            mbedtls_calloc(key_slice_length(slice_idx),
+                           sizeof(psa_key_slot_t));
+        if (global_data.key_slices[slice_idx] == NULL) {
+            return PSA_ERROR_INSUFFICIENT_MEMORY;
+        }
+    }
+    psa_key_slot_t *slice = global_data.key_slices[slice_idx];
+
+    size_t slot_idx = global_data.first_free_slot_index[slice_idx];
+    *key_id = volatile_key_id_of_index(slice_idx, slot_idx);
+
+    psa_key_slot_t *slot = &slice[slot_idx];
+    size_t next_free = slot_idx + 1 + slot->var.free.next_free_relative_to_next;
+    if (next_free >= key_slice_length(slice_idx)) {
+        next_free = FREE_SLOT_INDEX_NONE;
+    }
+    global_data.first_free_slot_index[slice_idx] = next_free;
+    /* The .next_free field is not meaningful when the slot is not free,
+     * so give it the same content as freshly initialized memory. */
+    slot->var.free.next_free_relative_to_next = 0;
+
+    psa_status_t status = psa_key_slot_state_transition(slot,
+                                                        PSA_SLOT_EMPTY,
+                                                        PSA_SLOT_FILLING);
+    if (status != PSA_SUCCESS) {
+        /* The only reason for failure is if the slot state was not empty.
+         * This indicates that something has gone horribly wrong.
+         * In this case, we leave the slot out of the free list, and stop
+         * modifying it. This minimizes any further corruption. The slot
+         * is a memory leak, but that's a lesser evil. */
+        return status;
+    }
+
+    *p_slot = slot;
+    /* We assert at compile time that the slice index fits in uint8_t. */
+    slot->slice_index = (uint8_t) slice_idx;
+    return PSA_SUCCESS;
+}
+
+psa_status_t psa_free_key_slot(size_t slice_idx,
+                               psa_key_slot_t *slot)
+{
+
+    if (slice_idx == KEY_SLOT_CACHE_SLICE_INDEX) {
+        /* This is a cache entry. We don't maintain a free list, so
+         * there's nothing to do. */
+        return PSA_SUCCESS;
+    }
+    if (slice_idx >= KEY_SLOT_VOLATILE_SLICE_COUNT) {
+        return PSA_ERROR_CORRUPTION_DETECTED;
+    }
+
+    psa_key_slot_t *slice = global_data.key_slices[slice_idx];
+    psa_key_slot_t *slice_end = slice + key_slice_length(slice_idx);
+    if (slot < slice || slot >= slice_end) {
+        /* The slot isn't actually in the slice! We can't detect that
+         * condition for sure, because the pointer comparison itself is
+         * undefined behavior in that case. That same condition makes the
+         * subtraction to calculate the slot index also UB.
+         * Give up now to avoid causing further corruption.
+         */
+        return PSA_ERROR_CORRUPTION_DETECTED;
+    }
+    size_t slot_idx = slot - slice;
+
+    size_t next_free = global_data.first_free_slot_index[slice_idx];
+    if (next_free >= key_slice_length(slice_idx)) {
+        /* The slot was full. The newly freed slot thus becomes the
+         * end of the free list. */
+        next_free = key_slice_length(slice_idx);
+    }
+    global_data.first_free_slot_index[slice_idx] = slot_idx;
+    slot->var.free.next_free_relative_to_next =
+        (int32_t) next_free - (int32_t) slot_idx - 1;
+
+    return PSA_SUCCESS;
+}
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
 psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
                                        psa_key_slot_t **p_slot)
 {
@@ -186,9 +604,19 @@
         goto error;
     }
 
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+    if (volatile_key_id != NULL) {
+        return psa_allocate_volatile_key_slot(volatile_key_id, p_slot);
+    }
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
+    /* With a dynamic key store, allocate an entry in the cache slice,
+     * applicable only to non-volatile keys that get cached in RAM.
+     * With a static key store, allocate an entry in the sole slice,
+     * applicable to all keys. */
     selected_slot = unused_persistent_key_slot = NULL;
-    for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
-        psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
+    for (slot_idx = 0; slot_idx < PERSISTENT_KEY_CACHE_COUNT; slot_idx++) {
+        psa_key_slot_t *slot = get_key_slot(KEY_SLOT_CACHE_SLICE_INDEX, slot_idx);
         if (slot->state == PSA_SLOT_EMPTY) {
             selected_slot = slot;
             break;
@@ -226,8 +654,18 @@
             goto error;
         }
 
-        *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +
-                           ((psa_key_id_t) (selected_slot - global_data.key_slots));
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+        selected_slot->slice_index = KEY_SLOT_CACHE_SLICE_INDEX;
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
+#if !defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+        if (volatile_key_id != NULL) {
+            /* Refresh slot_idx, for when the slot is not the original
+             * selected_slot but rather unused_persistent_key_slot.  */
+            slot_idx = selected_slot - global_data.key_slots;
+            *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + slot_idx;
+        }
+#endif
         *p_slot = selected_slot;
 
         return PSA_SUCCESS;
@@ -236,7 +674,6 @@
 
 error:
     *p_slot = NULL;
-    *volatile_key_id = 0;
 
     return status;
 }
@@ -395,9 +832,8 @@
     /* Loading keys from storage requires support for such a mechanism */
 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \
     defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
-    psa_key_id_t volatile_key_id;
 
-    status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
+    status = psa_reserve_free_key_slot(NULL, p_slot);
     if (status != PSA_SUCCESS) {
 #if defined(MBEDTLS_THREADING_C)
         PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
@@ -424,6 +860,8 @@
     if (status != PSA_SUCCESS) {
         psa_wipe_key_slot(*p_slot);
 
+        /* If the key does not exist, we need to return
+         * PSA_ERROR_INVALID_HANDLE. */
         if (status == PSA_ERROR_DOES_NOT_EXIST) {
             status = PSA_ERROR_INVALID_HANDLE;
         }
@@ -440,6 +878,9 @@
     status = PSA_ERROR_INVALID_HANDLE;
 #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
 
+    if (status != PSA_SUCCESS) {
+        *p_slot = NULL;
+    }
 #if defined(MBEDTLS_THREADING_C)
     PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
                               &mbedtls_threading_key_slot_mutex));
@@ -460,12 +901,12 @@
     /* If we are the last reader and the slot is marked for deletion,
      * we must wipe the slot here. */
     if ((slot->state == PSA_SLOT_PENDING_DELETION) &&
-        (slot->registered_readers == 1)) {
+        (slot->var.occupied.registered_readers == 1)) {
         return psa_wipe_key_slot(slot);
     }
 
     if (psa_key_slot_has_readers(slot)) {
-        slot->registered_readers--;
+        slot->var.occupied.registered_readers--;
         return PSA_SUCCESS;
     }
 
@@ -599,7 +1040,7 @@
         return status;
     }
 
-    if (slot->registered_readers == 1) {
+    if (slot->var.occupied.registered_readers == 1) {
         status = psa_wipe_key_slot(slot);
     } else {
         status = psa_unregister_read(slot);
@@ -634,7 +1075,7 @@
     }
 
     if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
-        (slot->registered_readers == 1)) {
+        (slot->var.occupied.registered_readers == 1)) {
         status = psa_wipe_key_slot(slot);
     } else {
         status = psa_unregister_read(slot);
@@ -649,34 +1090,39 @@
 
 void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats)
 {
-    size_t slot_idx;
-
     memset(stats, 0, sizeof(*stats));
 
-    for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) {
-        const psa_key_slot_t *slot = &global_data.key_slots[slot_idx];
-        if (psa_key_slot_has_readers(slot)) {
-            ++stats->locked_slots;
-        }
-        if (slot->state == PSA_SLOT_EMPTY) {
-            ++stats->empty_slots;
+    for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) {
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+        if (global_data.key_slices[slice_idx] == NULL) {
             continue;
         }
-        if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
-            ++stats->volatile_slots;
-        } else {
-            psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id);
-            ++stats->persistent_slots;
-            if (id > stats->max_open_internal_key_id) {
-                stats->max_open_internal_key_id = id;
+#endif  /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+        for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) {
+            const psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx);
+            if (slot->state == PSA_SLOT_EMPTY) {
+                ++stats->empty_slots;
+                continue;
             }
-        }
-        if (PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime) !=
-            PSA_KEY_LOCATION_LOCAL_STORAGE) {
-            psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id);
-            ++stats->external_slots;
-            if (id > stats->max_open_external_key_id) {
-                stats->max_open_external_key_id = id;
+            if (psa_key_slot_has_readers(slot)) {
+                ++stats->locked_slots;
+            }
+            if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
+                ++stats->volatile_slots;
+            } else {
+                psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id);
+                ++stats->persistent_slots;
+                if (id > stats->max_open_internal_key_id) {
+                    stats->max_open_internal_key_id = id;
+                }
+            }
+            if (PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime) !=
+                PSA_KEY_LOCATION_LOCAL_STORAGE) {
+                psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id);
+                ++stats->external_slots;
+                if (id > stats->max_open_external_key_id) {
+                    stats->max_open_external_key_id = id;
+                }
             }
         }
     }
diff --git a/lib/libmbedtls/mbedtls/library/psa_crypto_slot_management.h b/lib/libmbedtls/mbedtls/library/psa_crypto_slot_management.h
index bcfc9d8..af1208e 100644
--- a/lib/libmbedtls/mbedtls/library/psa_crypto_slot_management.h
+++ b/lib/libmbedtls/mbedtls/library/psa_crypto_slot_management.h
@@ -15,20 +15,26 @@
 
 /** Range of volatile key identifiers.
  *
- *  The last #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation
+ *  The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation
  *  range of key identifiers are reserved for volatile key identifiers.
- *  A volatile key identifier is equal to #PSA_KEY_ID_VOLATILE_MIN plus the
- *  index of the key slot containing the volatile key definition.
+ *
+ *  If \c id is a a volatile key identifier, #PSA_KEY_ID_VOLATILE_MIN - \c id
+ *  indicates the key slot containing the volatile key definition. See
+ *  psa_crypto_slot_management.c for details.
  */
 
 /** The minimum value for a volatile key identifier.
  */
-#define PSA_KEY_ID_VOLATILE_MIN  (PSA_KEY_ID_VENDOR_MAX - \
-                                  MBEDTLS_PSA_KEY_SLOT_COUNT + 1)
+#define PSA_KEY_ID_VOLATILE_MIN  PSA_KEY_ID_VENDOR_MIN
 
 /** The maximum value for a volatile key identifier.
  */
-#define PSA_KEY_ID_VOLATILE_MAX  PSA_KEY_ID_VENDOR_MAX
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+#define PSA_KEY_ID_VOLATILE_MAX (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1)
+#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+#define PSA_KEY_ID_VOLATILE_MAX                                 \
+    (PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1)
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
 
 /** Test whether a key identifier is a volatile key identifier.
  *
@@ -58,6 +64,9 @@
  * It is the responsibility of the caller to call psa_unregister_read(slot)
  * when they have finished reading the contents of the slot.
  *
+ * On failure, `*p_slot` is set to NULL. This ensures that it is always valid
+ * to call psa_unregister_read on the returned slot.
+ *
  * \param key           Key identifier to query.
  * \param[out] p_slot   On success, `*p_slot` contains a pointer to the
  *                      key slot containing the description of the key
@@ -91,6 +100,24 @@
  */
 psa_status_t psa_initialize_key_slots(void);
 
+#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+/* Allow test code to customize the key slice length. We use this in tests
+ * that exhaust the key store to reach a full key store in reasonable time
+ * and memory.
+ *
+ * The length of each slice must be between 1 and
+ * (1 << KEY_ID_SLOT_INDEX_WIDTH) inclusive.
+ *
+ * The length for a given slice index must not change while
+ * the key store is initialized.
+ */
+extern size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)(
+    size_t slice_idx);
+
+/* The number of volatile key slices. */
+size_t psa_key_slot_volatile_slice_count(void);
+#endif
+
 /** Delete all data from key slots in memory.
  * This function is not thread safe, it wipes every key slot regardless of
  * state and reader count. It should only be called when no slot is in use.
@@ -110,13 +137,22 @@
  * If multi-threading is enabled, the caller must hold the
  * global key slot mutex.
  *
- * \param[out] volatile_key_id   On success, volatile key identifier
- *                               associated to the returned slot.
+ * \param[out] volatile_key_id   - If null, reserve a cache slot for
+ *                                 a persistent or built-in key.
+ *                               - If non-null, allocate a slot for
+ *                                 a volatile key. On success,
+ *                                 \p *volatile_key_id is the
+ *                                 identifier corresponding to the
+ *                                 returned slot. It is the caller's
+ *                                 responsibility to set this key identifier
+ *                                 in the attributes.
  * \param[out] p_slot            On success, a pointer to the slot.
  *
  * \retval #PSA_SUCCESS \emptydescription
  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
  *         There were no free key slots.
+ *         When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, there was not
+ *         enough memory to allocate more slots.
  * \retval #PSA_ERROR_BAD_STATE \emptydescription
  * \retval #PSA_ERROR_CORRUPTION_DETECTED
  *         This function attempted to operate on a key slot which was in an
@@ -125,6 +161,29 @@
 psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
                                        psa_key_slot_t **p_slot);
 
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+/** Return a key slot to the free list.
+ *
+ * Call this function when a slot obtained from psa_reserve_free_key_slot()
+ * is no longer in use.
+ *
+ * If multi-threading is enabled, the caller must hold the
+ * global key slot mutex.
+ *
+ * \param slice_idx             The slice containing the slot.
+ *                              This is `slot->slice_index` when the slot
+ *                              is obtained from psa_reserve_free_key_slot().
+ * \param slot                  The key slot.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ *         This function attempted to operate on a key slot which was in an
+ *         unexpected state.
+ */
+psa_status_t psa_free_key_slot(size_t slice_idx,
+                               psa_key_slot_t *slot);
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
+
 /** Change the state of a key slot.
  *
  * This function changes the state of the key slot from expected_state to
@@ -171,10 +230,10 @@
 static inline psa_status_t psa_register_read(psa_key_slot_t *slot)
 {
     if ((slot->state != PSA_SLOT_FULL) ||
-        (slot->registered_readers >= SIZE_MAX)) {
+        (slot->var.occupied.registered_readers >= SIZE_MAX)) {
         return PSA_ERROR_CORRUPTION_DETECTED;
     }
-    slot->registered_readers++;
+    slot->var.occupied.registered_readers++;
 
     return PSA_SUCCESS;
 }
diff --git a/lib/libmbedtls/mbedtls/library/psa_util.c b/lib/libmbedtls/mbedtls/library/psa_util.c
index 4ccc5b0..679d00e 100644
--- a/lib/libmbedtls/mbedtls/library/psa_util.c
+++ b/lib/libmbedtls/mbedtls/library/psa_util.c
@@ -443,6 +443,9 @@
     if (raw_len != (2 * coordinate_len)) {
         return MBEDTLS_ERR_ASN1_INVALID_DATA;
     }
+    if (coordinate_len > sizeof(r)) {
+        return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+    }
 
     /* Since raw and der buffers might overlap, dump r and s before starting
      * the conversion. */
@@ -561,6 +564,9 @@
     if (raw_size < coordinate_size * 2) {
         return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
     }
+    if (2 * coordinate_size > sizeof(raw_tmp)) {
+        return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+    }
 
     /* Check that the provided input DER buffer has the right header. */
     ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
diff --git a/lib/libmbedtls/mbedtls/library/rsa.c b/lib/libmbedtls/mbedtls/library/rsa.c
index e99e4af..557faaf 100644
--- a/lib/libmbedtls/mbedtls/library/rsa.c
+++ b/lib/libmbedtls/mbedtls/library/rsa.c
@@ -29,6 +29,7 @@
 
 #include "mbedtls/rsa.h"
 #include "bignum_core.h"
+#include "bignum_internal.h"
 #include "rsa_alt_helpers.h"
 #include "rsa_internal.h"
 #include "mbedtls/oid.h"
@@ -47,8 +48,6 @@
 
 #include "mbedtls/platform.h"
 
-#include <fault_mitigation.h>
-
 /*
  * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
  *
@@ -1261,7 +1260,7 @@
     }
 
     olen = ctx->len;
-    MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
+    MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod_unsafe(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
 
 cleanup:
@@ -1957,10 +1956,7 @@
     /*
      * RSA operation
      */
-    if( ctx->P.n == 0 )
-        ret = mbedtls_rsa_private( ctx, NULL, NULL, input, buf );
-    else
-        ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf);
+    ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf);
 
     if (ret != 0) {
         goto cleanup;
@@ -2221,9 +2217,6 @@
     p += hlen;
     *p++ = 0xBC;
 
-    if (ctx->P.n == 0)
-        return mbedtls_rsa_private(ctx, NULL, NULL, sig, sig);
-
     return mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig);
 }
 
@@ -2641,7 +2634,7 @@
         return ret;
     }
 
-    if (FTMN_CALLEE_DONE_MEMCMP(memcmp, hash_start, result, hlen) != 0) {
+    if (memcmp(hash_start, result, hlen) != 0) {
         return MBEDTLS_ERR_RSA_VERIFY_FAILED;
     }
 
@@ -2723,8 +2716,8 @@
      * Compare
      */
 
-    if ((ret = FTMN_CALLEE_DONE_MEMCMP(mbedtls_ct_memcmp, encoded,
-                                       encoded_expected, sig_len )) != 0) {
+    if ((ret = mbedtls_ct_memcmp(encoded, encoded_expected,
+                                 sig_len)) != 0) {
         ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
         goto cleanup;
     }
diff --git a/lib/libmbedtls/mbedtls/library/sha256.c b/lib/libmbedtls/mbedtls/library/sha256.c
index 8788981..159accc 100644
--- a/lib/libmbedtls/mbedtls/library/sha256.c
+++ b/lib/libmbedtls/mbedtls/library/sha256.c
@@ -44,7 +44,9 @@
 #endif /* defined(__clang__) &&  (__clang_major__ >= 4) */
 
 /* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
+#if !defined(_GNU_SOURCE)
 #define _GNU_SOURCE
+#endif
 
 #include "common.h"
 
@@ -150,7 +152,9 @@
     return 1;
 }
 #elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
+#ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
+#endif
 #include <Windows.h>
 #include <processthreadsapi.h>
 
diff --git a/lib/libmbedtls/mbedtls/library/ssl_cookie.c b/lib/libmbedtls/mbedtls/library/ssl_cookie.c
index 2772cac..acc9e8c 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_cookie.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_cookie.c
@@ -84,6 +84,10 @@
 
 void mbedtls_ssl_cookie_free(mbedtls_ssl_cookie_ctx *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_destroy_key(ctx->psa_hmac_key);
 #else
diff --git a/lib/libmbedtls/mbedtls/library/ssl_debug_helpers_generated.c b/lib/libmbedtls/mbedtls/library/ssl_debug_helpers_generated.c
index f8b4448..734c417 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_debug_helpers_generated.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_debug_helpers_generated.c
@@ -60,7 +60,7 @@
         return "ffdhe8192";
     };
 
-    return "UNKOWN";
+    return "UNKNOWN";
 }
 const char *mbedtls_ssl_sig_alg_to_str( uint16_t in )
 {
diff --git a/lib/libmbedtls/mbedtls/library/ssl_misc.h b/lib/libmbedtls/mbedtls/library/ssl_misc.h
index a8807f6..9866879 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_misc.h
+++ b/lib/libmbedtls/mbedtls/library/ssl_misc.h
@@ -1507,7 +1507,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
-#if defined(MBEDTLS_SSL_CLI_C)
+#if defined(MBEDTLS_SSL_CLI_C) || defined(MBEDTLS_SSL_SRV_C)
 MBEDTLS_CHECK_RETURN_CRITICAL
 int mbedtls_ssl_conf_has_static_psk(mbedtls_ssl_config const *conf);
 #endif
@@ -1674,18 +1674,53 @@
 }
 
 /*
- * Check usage of a certificate wrt extensions:
- * keyUsage, extendedKeyUsage (later), and nSCertType (later).
+ * Verify a certificate.
  *
- * Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we
- * check a cert we received from them)!
+ * [in/out] ssl: misc. things read
+ *               ssl->session_negotiate->verify_result updated
+ * [in] authmode: one of MBEDTLS_SSL_VERIFY_{NONE,OPTIONAL,REQUIRED}
+ * [in] chain: the certificate chain to verify (ie the peer's chain)
+ * [in] ciphersuite_info: For TLS 1.2, this session's ciphersuite;
+ *                        for TLS 1.3, may be left NULL.
+ * [in] rs_ctx: restart context if restartable ECC is in use;
+ *              leave NULL for no restartable behaviour.
+ *
+ * Return:
+ * - 0 if the handshake should continue. Depending on the
+ *   authmode it means:
+ *   - REQUIRED: the certificate was found to be valid, trusted & acceptable.
+ *     ssl->session_negotiate->verify_result is 0.
+ *   - OPTIONAL: the certificate may or may not be acceptable, but
+ *     ssl->session_negotiate->verify_result was updated with the result.
+ *   - NONE: the certificate wasn't even checked.
+ * - MBEDTLS_ERR_X509_CERT_VERIFY_FAILED or MBEDTLS_ERR_SSL_BAD_CERTIFICATE if
+ *   the certificate was found to be invalid/untrusted/unacceptable and the
+ *   handshake should be aborted (can only happen with REQUIRED).
+ * - another error code if another error happened (out-of-memory, etc.)
+ */
+MBEDTLS_CHECK_RETURN_CRITICAL
+int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
+                                   int authmode,
+                                   mbedtls_x509_crt *chain,
+                                   const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
+                                   void *rs_ctx);
+
+/*
+ * Check usage of a certificate wrt usage extensions:
+ * keyUsage and extendedKeyUsage.
+ * (Note: nSCertType is deprecated and not standard, we don't check it.)
+ *
+ * Note: if tls_version is 1.3, ciphersuite is ignored and can be NULL.
+ *
+ * Note: recv_endpoint is the receiver's endpoint.
  *
  * Return 0 if everything is OK, -1 if not.
  */
 MBEDTLS_CHECK_RETURN_CRITICAL
 int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
                                  const mbedtls_ssl_ciphersuite_t *ciphersuite,
-                                 int cert_endpoint,
+                                 int recv_endpoint,
+                                 mbedtls_ssl_protocol_version tls_version,
                                  uint32_t *flags);
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
@@ -1891,6 +1926,26 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+
+/** \brief Initialize the PSA crypto subsystem if necessary.
+ *
+ * Call this function before doing any cryptography in a TLS 1.3 handshake.
+ *
+ * This is necessary in Mbed TLS 3.x for backward compatibility.
+ * Up to Mbed TLS 3.5, in the default configuration, you could perform
+ * a TLS connection with default parameters without having called
+ * psa_crypto_init(), since the TLS layer only supported TLS 1.2 and
+ * did not use PSA crypto. (TLS 1.2 only uses PSA crypto if
+ * MBEDTLS_USE_PSA_CRYPTO is enabled, which is not the case in the default
+ * configuration.) Starting with Mbed TLS 3.6.0, TLS 1.3 is enabled
+ * by default, and the TLS 1.3 layer uses PSA crypto. This means that
+ * applications that are not otherwise using PSA crypto and that worked
+ * with Mbed TLS 3.5 started failing in TLS 3.6.0 if they connected to
+ * a peer that supports TLS 1.3. See
+ * https://github.com/Mbed-TLS/mbedtls/issues/9072
+ */
+int mbedtls_ssl_tls13_crypto_init(mbedtls_ssl_context *ssl);
+
 extern const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[
     MBEDTLS_SERVER_HELLO_RANDOM_LEN];
 MBEDTLS_CHECK_RETURN_CRITICAL
@@ -2914,8 +2969,37 @@
 {
     session->ticket_flags &= ~(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
 }
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
 
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT 0
+#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT 1
+
+#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK \
+    (1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT)
+#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK \
+    (1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT)
+
+static inline int mbedtls_ssl_conf_get_session_tickets(
+    const mbedtls_ssl_config *conf)
+{
+    return conf->session_tickets & MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK ?
+           MBEDTLS_SSL_SESSION_TICKETS_ENABLED :
+           MBEDTLS_SSL_SESSION_TICKETS_DISABLED;
+}
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+static inline int mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(
+    const mbedtls_ssl_config *conf)
+{
+    return conf->session_tickets & MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK ?
+           MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED :
+           MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED;
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
 #if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
 int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl);
 #endif
diff --git a/lib/libmbedtls/mbedtls/library/ssl_msg.c b/lib/libmbedtls/mbedtls/library/ssl_msg.c
index b07cd96..ef722d7 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_msg.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_msg.c
@@ -5570,9 +5570,9 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+#if defined(MBEDTLS_SSL_CLI_C)
 MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_check_new_session_ticket(mbedtls_ssl_context *ssl)
+static int ssl_tls13_is_new_session_ticket(mbedtls_ssl_context *ssl)
 {
 
     if ((ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl)) ||
@@ -5580,15 +5580,9 @@
         return 0;
     }
 
-    ssl->keep_current_message = 1;
-
-    MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received"));
-    mbedtls_ssl_handshake_set_state(ssl,
-                                    MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
-
-    return MBEDTLS_ERR_SSL_WANT_READ;
+    return 1;
 }
-#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+#endif /* MBEDTLS_SSL_CLI_C */
 
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
@@ -5596,14 +5590,29 @@
 
     MBEDTLS_SSL_DEBUG_MSG(3, ("received post-handshake message"));
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+#if defined(MBEDTLS_SSL_CLI_C)
     if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-        int ret = ssl_tls13_check_new_session_ticket(ssl);
-        if (ret != 0) {
-            return ret;
+        if (ssl_tls13_is_new_session_ticket(ssl)) {
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+            MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received"));
+            if (mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(ssl->conf) ==
+                MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED) {
+                ssl->keep_current_message = 1;
+
+                mbedtls_ssl_handshake_set_state(ssl,
+                                                MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
+                return MBEDTLS_ERR_SSL_WANT_READ;
+            } else {
+                MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, handling disabled."));
+                return 0;
+            }
+#else
+            MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, not supported."));
+            return 0;
+#endif
         }
     }
-#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+#endif /* MBEDTLS_SSL_CLI_C */
 
     /* Fail in all other cases. */
     return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
diff --git a/lib/libmbedtls/mbedtls/library/ssl_ticket.c b/lib/libmbedtls/mbedtls/library/ssl_ticket.c
index 6a31b0b..bfb656c 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_ticket.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_ticket.c
@@ -534,6 +534,10 @@
  */
 void mbedtls_ssl_ticket_free(mbedtls_ssl_ticket_context *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_destroy_key(ctx->keys[0].key);
     psa_destroy_key(ctx->keys[1].key);
diff --git a/lib/libmbedtls/mbedtls/library/ssl_tls.c b/lib/libmbedtls/mbedtls/library/ssl_tls.c
index c5e0649..c773365 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_tls.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_tls.c
@@ -132,7 +132,7 @@
 
 int mbedtls_ssl_get_own_cid(mbedtls_ssl_context *ssl,
                             int *enabled,
-                            unsigned char own_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX],
+                            unsigned char own_cid[MBEDTLS_SSL_CID_IN_LEN_MAX],
                             size_t *own_cid_len)
 {
     *enabled = MBEDTLS_SSL_CID_DISABLED;
@@ -1354,29 +1354,6 @@
         return ret;
     }
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-    /* RFC 8446 section 4.4.3
-     *
-     * If the verification fails, the receiver MUST terminate the handshake with
-     * a "decrypt_error" alert.
-     *
-     * If the client is configured as TLS 1.3 only with optional verify, return
-     * bad config.
-     *
-     */
-    if (mbedtls_ssl_conf_tls13_is_ephemeral_enabled(
-            (mbedtls_ssl_context *) ssl)                            &&
-        ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT                &&
-        ssl->conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3    &&
-        ssl->conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_3    &&
-        ssl->conf->authmode == MBEDTLS_SSL_VERIFY_OPTIONAL) {
-        MBEDTLS_SSL_DEBUG_MSG(
-            1, ("Optional verify auth mode "
-                "is not available for TLS 1.3 client"));
-        return MBEDTLS_ERR_SSL_BAD_CONFIG;
-    }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
-
     if (ssl->conf->f_rng == NULL) {
         MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
         return MBEDTLS_ERR_SSL_NO_RNG;
@@ -1760,6 +1737,7 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
     if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
         const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
             mbedtls_ssl_ciphersuite_from_id(session->ciphersuite);
 
@@ -1770,6 +1748,14 @@
                                       session->ciphersuite));
             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
         }
+#else
+        /*
+         * If session tickets are not enabled, it is not possible to resume a
+         * TLS 1.3 session, thus do not make any change to the SSL context in
+         * the first place.
+         */
+        return 0;
+#endif
     }
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
 
@@ -2234,6 +2220,7 @@
         mbedtls_zeroize_and_free(ssl->handshake->psk,
                                  ssl->handshake->psk_len);
         ssl->handshake->psk_len = 0;
+        ssl->handshake->psk = NULL;
     }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 }
@@ -2999,11 +2986,24 @@
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
 #if defined(MBEDTLS_SSL_CLI_C)
+
 void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets)
 {
-    conf->session_tickets = use_tickets;
+    conf->session_tickets &= ~MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK;
+    conf->session_tickets |= (use_tickets != 0) <<
+                             MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT;
 }
-#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+void mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
+    mbedtls_ssl_config *conf, int signal_new_session_tickets)
+{
+    conf->session_tickets &= ~MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK;
+    conf->session_tickets |= (signal_new_session_tickets != 0) <<
+                             MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT;
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#endif /* MBEDTLS_SSL_CLI_C */
 
 #if defined(MBEDTLS_SSL_SRV_C)
 
@@ -4049,7 +4049,7 @@
 }
 
 static int ssl_tls13_session_load(const mbedtls_ssl_session *session,
-                                  unsigned char *buf,
+                                  const unsigned char *buf,
                                   size_t buf_len)
 {
     ((void) session);
@@ -5868,7 +5868,33 @@
     if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
         conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-        conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
+        mbedtls_ssl_conf_session_tickets(conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED);
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+        /* Contrary to TLS 1.2 tickets, TLS 1.3 NewSessionTicket message
+         * handling is disabled by default in Mbed TLS 3.6.x for backward
+         * compatibility with client applications developed using Mbed TLS 3.5
+         * or earlier with the default configuration.
+         *
+         * Up to Mbed TLS 3.5, in the default configuration TLS 1.3 was
+         * disabled, and a Mbed TLS client with the default configuration would
+         * establish a TLS 1.2 connection with a TLS 1.2 and TLS 1.3 capable
+         * server.
+         *
+         * Starting with Mbed TLS 3.6.0, TLS 1.3 is enabled by default, and thus
+         * an Mbed TLS client with the default configuration establishes a
+         * TLS 1.3 connection with a TLS 1.2 and TLS 1.3 capable server. If
+         * following the handshake the TLS 1.3 server sends NewSessionTicket
+         * messages and the Mbed TLS client processes them, this results in
+         * Mbed TLS high level APIs (mbedtls_ssl_read(),
+         * mbedtls_ssl_handshake(), ...) to eventually return an
+         * #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET non fatal error code
+         * (see the documentation of mbedtls_ssl_read() for more information on
+         * that error code). Applications unaware of that TLS 1.3 specific non
+         * fatal error code are then failing.
+         */
+        mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
+            conf, MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED);
+#endif
 #endif
     }
 #endif
@@ -6030,6 +6056,10 @@
  */
 void mbedtls_ssl_config_free(mbedtls_ssl_config *conf)
 {
+    if (conf == NULL) {
+        return;
+    }
+
 #if defined(MBEDTLS_DHM_C)
     mbedtls_mpi_free(&conf->dhm_P);
     mbedtls_mpi_free(&conf->dhm_G);
@@ -6344,71 +6374,6 @@
 }
 #endif
 
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
-                                 const mbedtls_ssl_ciphersuite_t *ciphersuite,
-                                 int cert_endpoint,
-                                 uint32_t *flags)
-{
-    int ret = 0;
-    unsigned int usage = 0;
-    const char *ext_oid;
-    size_t ext_len;
-
-    if (cert_endpoint == MBEDTLS_SSL_IS_SERVER) {
-        /* Server part of the key exchange */
-        switch (ciphersuite->key_exchange) {
-            case MBEDTLS_KEY_EXCHANGE_RSA:
-            case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
-                usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
-                break;
-
-            case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
-            case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
-            case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
-                usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
-                break;
-
-            case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
-            case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
-                usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
-                break;
-
-            /* Don't use default: we want warnings when adding new values */
-            case MBEDTLS_KEY_EXCHANGE_NONE:
-            case MBEDTLS_KEY_EXCHANGE_PSK:
-            case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
-            case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
-            case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
-                usage = 0;
-        }
-    } else {
-        /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
-        usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
-    }
-
-    if (mbedtls_x509_crt_check_key_usage(cert, usage) != 0) {
-        *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
-        ret = -1;
-    }
-
-    if (cert_endpoint == MBEDTLS_SSL_IS_SERVER) {
-        ext_oid = MBEDTLS_OID_SERVER_AUTH;
-        ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
-    } else {
-        ext_oid = MBEDTLS_OID_CLIENT_AUTH;
-        ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
-    }
-
-    if (mbedtls_x509_crt_check_extended_key_usage(cert, ext_oid, ext_len) != 0) {
-        *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
-        ret = -1;
-    }
-
-    return ret;
-}
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 int mbedtls_ssl_get_handshake_transcript(mbedtls_ssl_context *ssl,
                                          const mbedtls_md_type_t md,
@@ -7927,196 +7892,6 @@
     return SSL_CERTIFICATE_EXPECTED;
 }
 
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
-                                        int authmode,
-                                        mbedtls_x509_crt *chain,
-                                        void *rs_ctx)
-{
-    int ret = 0;
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
-        ssl->handshake->ciphersuite_info;
-    int have_ca_chain = 0;
-
-    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
-    void *p_vrfy;
-
-    if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
-        return 0;
-    }
-
-    if (ssl->f_vrfy != NULL) {
-        MBEDTLS_SSL_DEBUG_MSG(3, ("Use context-specific verification callback"));
-        f_vrfy = ssl->f_vrfy;
-        p_vrfy = ssl->p_vrfy;
-    } else {
-        MBEDTLS_SSL_DEBUG_MSG(3, ("Use configuration-specific verification callback"));
-        f_vrfy = ssl->conf->f_vrfy;
-        p_vrfy = ssl->conf->p_vrfy;
-    }
-
-    /*
-     * Main check: verify certificate
-     */
-#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
-    if (ssl->conf->f_ca_cb != NULL) {
-        ((void) rs_ctx);
-        have_ca_chain = 1;
-
-        MBEDTLS_SSL_DEBUG_MSG(3, ("use CA callback for X.509 CRT verification"));
-        ret = mbedtls_x509_crt_verify_with_ca_cb(
-            chain,
-            ssl->conf->f_ca_cb,
-            ssl->conf->p_ca_cb,
-            ssl->conf->cert_profile,
-            ssl->hostname,
-            &ssl->session_negotiate->verify_result,
-            f_vrfy, p_vrfy);
-    } else
-#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
-    {
-        mbedtls_x509_crt *ca_chain;
-        mbedtls_x509_crl *ca_crl;
-
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-        if (ssl->handshake->sni_ca_chain != NULL) {
-            ca_chain = ssl->handshake->sni_ca_chain;
-            ca_crl   = ssl->handshake->sni_ca_crl;
-        } else
-#endif
-        {
-            ca_chain = ssl->conf->ca_chain;
-            ca_crl   = ssl->conf->ca_crl;
-        }
-
-        if (ca_chain != NULL) {
-            have_ca_chain = 1;
-        }
-
-        ret = mbedtls_x509_crt_verify_restartable(
-            chain,
-            ca_chain, ca_crl,
-            ssl->conf->cert_profile,
-            ssl->hostname,
-            &ssl->session_negotiate->verify_result,
-            f_vrfy, p_vrfy, rs_ctx);
-    }
-
-    if (ret != 0) {
-        MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret);
-    }
-
-#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
-    if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
-        return MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
-    }
-#endif
-
-    /*
-     * Secondary checks: always done, but change 'ret' only if it was 0
-     */
-
-#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
-    {
-        const mbedtls_pk_context *pk = &chain->pk;
-
-        /* If certificate uses an EC key, make sure the curve is OK.
-         * This is a public key, so it can't be opaque, so can_do() is a good
-         * enough check to ensure pk_ec() is safe to use here. */
-        if (mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) {
-            /* and in the unlikely case the above assumption no longer holds
-             * we are making sure that pk_ec() here does not return a NULL
-             */
-            mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk);
-            if (grp_id == MBEDTLS_ECP_DP_NONE) {
-                MBEDTLS_SSL_DEBUG_MSG(1, ("invalid group ID"));
-                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
-            }
-            if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
-                ssl->session_negotiate->verify_result |=
-                    MBEDTLS_X509_BADCERT_BAD_KEY;
-
-                MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (EC key curve)"));
-                if (ret == 0) {
-                    ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
-                }
-            }
-        }
-    }
-#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
-
-    if (mbedtls_ssl_check_cert_usage(chain,
-                                     ciphersuite_info,
-                                     !ssl->conf->endpoint,
-                                     &ssl->session_negotiate->verify_result) != 0) {
-        MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
-        if (ret == 0) {
-            ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
-        }
-    }
-
-    /* mbedtls_x509_crt_verify_with_profile is supposed to report a
-     * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
-     * with details encoded in the verification flags. All other kinds
-     * of error codes, including those from the user provided f_vrfy
-     * functions, are treated as fatal and lead to a failure of
-     * ssl_parse_certificate even if verification was optional. */
-    if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
-        (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
-         ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE)) {
-        ret = 0;
-    }
-
-    if (have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
-        MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain"));
-        ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
-    }
-
-    if (ret != 0) {
-        uint8_t alert;
-
-        /* The certificate may have been rejected for several reasons.
-           Pick one and send the corresponding alert. Which alert to send
-           may be a subject of debate in some cases. */
-        if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER) {
-            alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
-            alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE) {
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE) {
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE) {
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK) {
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY) {
-            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
-            alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
-            alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
-        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
-            alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
-        } else {
-            alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
-        }
-        mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                       alert);
-    }
-
-#if defined(MBEDTLS_DEBUG_C)
-    if (ssl->session_negotiate->verify_result != 0) {
-        MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x",
-                                  (unsigned int) ssl->session_negotiate->verify_result));
-    } else {
-        MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear"));
-    }
-#endif /* MBEDTLS_DEBUG_C */
-
-    return ret;
-}
-
 #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_remember_peer_crt_digest(mbedtls_ssl_context *ssl,
@@ -8173,6 +7948,7 @@
 {
     int ret = 0;
     int crt_expected;
+    /* Authmode: precedence order is SNI if used else configuration */
 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
                        ? ssl->handshake->sni_authmode
@@ -8252,8 +8028,9 @@
     }
 #endif
 
-    ret = ssl_parse_certificate_verify(ssl, authmode,
-                                       chain, rs_ctx);
+    ret = mbedtls_ssl_verify_certificate(ssl, authmode, chain,
+                                         ssl->handshake->ciphersuite_info,
+                                         rs_ctx);
     if (ret != 0) {
         goto exit;
     }
@@ -9919,4 +9696,274 @@
     return 0;
 }
 #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */
+
+/*
+ * The following functions are used by 1.2 and 1.3, client and server.
+ */
+#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
+int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
+                                 const mbedtls_ssl_ciphersuite_t *ciphersuite,
+                                 int recv_endpoint,
+                                 mbedtls_ssl_protocol_version tls_version,
+                                 uint32_t *flags)
+{
+    int ret = 0;
+    unsigned int usage = 0;
+    const char *ext_oid;
+    size_t ext_len;
+
+    /*
+     * keyUsage
+     */
+
+    /* Note: don't guard this with MBEDTLS_SSL_CLI_C because the server wants
+     * to check what a compliant client will think while choosing which cert
+     * to send to the client. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2 &&
+        recv_endpoint == MBEDTLS_SSL_IS_CLIENT) {
+        /* TLS 1.2 server part of the key exchange */
+        switch (ciphersuite->key_exchange) {
+            case MBEDTLS_KEY_EXCHANGE_RSA:
+            case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
+                usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
+                break;
+
+            case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+            case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+            case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+                usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
+                break;
+
+            case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+            case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+                usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
+                break;
+
+            /* Don't use default: we want warnings when adding new values */
+            case MBEDTLS_KEY_EXCHANGE_NONE:
+            case MBEDTLS_KEY_EXCHANGE_PSK:
+            case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
+            case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+            case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
+                usage = 0;
+        }
+    } else
+#endif
+    {
+        /* This is either TLS 1.3 authentication, which always uses signatures,
+         * or 1.2 client auth: rsa_sign and mbedtls_ecdsa_sign are the only
+         * options we implement, both using signatures. */
+        (void) tls_version;
+        (void) ciphersuite;
+        usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
+    }
+
+    if (mbedtls_x509_crt_check_key_usage(cert, usage) != 0) {
+        *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
+        ret = -1;
+    }
+
+    /*
+     * extKeyUsage
+     */
+
+    if (recv_endpoint == MBEDTLS_SSL_IS_CLIENT) {
+        ext_oid = MBEDTLS_OID_SERVER_AUTH;
+        ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
+    } else {
+        ext_oid = MBEDTLS_OID_CLIENT_AUTH;
+        ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
+    }
+
+    if (mbedtls_x509_crt_check_extended_key_usage(cert, ext_oid, ext_len) != 0) {
+        *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
+        ret = -1;
+    }
+
+    return ret;
+}
+
+int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
+                                   int authmode,
+                                   mbedtls_x509_crt *chain,
+                                   const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
+                                   void *rs_ctx)
+{
+    if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
+        return 0;
+    }
+
+    /*
+     * Primary check: use the appropriate X.509 verification function
+     */
+    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
+    void *p_vrfy;
+    if (ssl->f_vrfy != NULL) {
+        MBEDTLS_SSL_DEBUG_MSG(3, ("Use context-specific verification callback"));
+        f_vrfy = ssl->f_vrfy;
+        p_vrfy = ssl->p_vrfy;
+    } else {
+        MBEDTLS_SSL_DEBUG_MSG(3, ("Use configuration-specific verification callback"));
+        f_vrfy = ssl->conf->f_vrfy;
+        p_vrfy = ssl->conf->p_vrfy;
+    }
+
+    int ret = 0;
+    int have_ca_chain_or_callback = 0;
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+    if (ssl->conf->f_ca_cb != NULL) {
+        ((void) rs_ctx);
+        have_ca_chain_or_callback = 1;
+
+        MBEDTLS_SSL_DEBUG_MSG(3, ("use CA callback for X.509 CRT verification"));
+        ret = mbedtls_x509_crt_verify_with_ca_cb(
+            chain,
+            ssl->conf->f_ca_cb,
+            ssl->conf->p_ca_cb,
+            ssl->conf->cert_profile,
+            ssl->hostname,
+            &ssl->session_negotiate->verify_result,
+            f_vrfy, p_vrfy);
+    } else
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+    {
+        mbedtls_x509_crt *ca_chain;
+        mbedtls_x509_crl *ca_crl;
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+        if (ssl->handshake->sni_ca_chain != NULL) {
+            ca_chain = ssl->handshake->sni_ca_chain;
+            ca_crl   = ssl->handshake->sni_ca_crl;
+        } else
+#endif
+        {
+            ca_chain = ssl->conf->ca_chain;
+            ca_crl   = ssl->conf->ca_crl;
+        }
+
+        if (ca_chain != NULL) {
+            have_ca_chain_or_callback = 1;
+        }
+
+        ret = mbedtls_x509_crt_verify_restartable(
+            chain,
+            ca_chain, ca_crl,
+            ssl->conf->cert_profile,
+            ssl->hostname,
+            &ssl->session_negotiate->verify_result,
+            f_vrfy, p_vrfy, rs_ctx);
+    }
+
+    if (ret != 0) {
+        MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret);
+    }
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+    if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
+        return MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
+    }
+#endif
+
+    /*
+     * Secondary checks: always done, but change 'ret' only if it was 0
+     */
+
+    /* With TLS 1.2 and ECC certs, check that the curve used by the
+     * certificate is on our list of acceptable curves.
+     *
+     * With TLS 1.3 this is not needed because the curve is part of the
+     * signature algorithm (eg ecdsa_secp256r1_sha256) which is checked when
+     * we validate the signature made with the key associated to this cert.
+     */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_PK_HAVE_ECC_KEYS)
+    if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 &&
+        mbedtls_pk_can_do(&chain->pk, MBEDTLS_PK_ECKEY)) {
+        if (mbedtls_ssl_check_curve(ssl, mbedtls_pk_get_ec_group_id(&chain->pk)) != 0) {
+            MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (EC key curve)"));
+            ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
+            if (ret == 0) {
+                ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
+            }
+        }
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_PK_HAVE_ECC_KEYS */
+
+    /* Check X.509 usage extensions (keyUsage, extKeyUsage) */
+    if (mbedtls_ssl_check_cert_usage(chain,
+                                     ciphersuite_info,
+                                     ssl->conf->endpoint,
+                                     ssl->tls_version,
+                                     &ssl->session_negotiate->verify_result) != 0) {
+        MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
+        if (ret == 0) {
+            ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
+        }
+    }
+
+    /* With authmode optional, we want to keep going if the certificate was
+     * unacceptable, but still fail on other errors (out of memory etc),
+     * including fatal errors from the f_vrfy callback.
+     *
+     * The only acceptable errors are:
+     * - MBEDTLS_ERR_X509_CERT_VERIFY_FAILED: cert rejected by primary check;
+     * - MBEDTLS_ERR_SSL_BAD_CERTIFICATE: cert rejected by secondary checks.
+     * Anything else is a fatal error. */
+    if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
+        (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
+         ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE)) {
+        ret = 0;
+    }
+
+    /* Return a specific error as this is a user error: inconsistent
+     * configuration - can't verify without trust anchors. */
+    if (have_ca_chain_or_callback == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
+        MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain"));
+        ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
+    }
+
+    if (ret != 0) {
+        uint8_t alert;
+
+        /* The certificate may have been rejected for several reasons.
+           Pick one and send the corresponding alert. Which alert to send
+           may be a subject of debate in some cases. */
+        if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER) {
+            alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
+        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
+            alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE) {
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE) {
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK) {
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY) {
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
+            alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
+        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
+            alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
+        } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
+            alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
+        } else {
+            alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
+        }
+        mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                       alert);
+    }
+
+#if defined(MBEDTLS_DEBUG_C)
+    if (ssl->session_negotiate->verify_result != 0) {
+        MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x",
+                                  (unsigned int) ssl->session_negotiate->verify_result));
+    } else {
+        MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear"));
+    }
+#endif /* MBEDTLS_DEBUG_C */
+
+    return ret;
+}
+#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
+
 #endif /* MBEDTLS_SSL_TLS_C */
diff --git a/lib/libmbedtls/mbedtls/library/ssl_tls12_client.c b/lib/libmbedtls/mbedtls/library/ssl_tls12_client.c
index eac6a3a..9b2da5a 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_tls12_client.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_tls12_client.c
@@ -364,7 +364,8 @@
 
     *olen = 0;
 
-    if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
+    if (mbedtls_ssl_conf_get_session_tickets(ssl->conf) ==
+        MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
         return 0;
     }
 
@@ -787,7 +788,8 @@
                                         const unsigned char *buf,
                                         size_t len)
 {
-    if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
+    if ((mbedtls_ssl_conf_get_session_tickets(ssl->conf) ==
+         MBEDTLS_SSL_SESSION_TICKETS_DISABLED) ||
         len != 0) {
         MBEDTLS_SSL_DEBUG_MSG(1,
                               ("non-matching session ticket extension"));
diff --git a/lib/libmbedtls/mbedtls/library/ssl_tls12_server.c b/lib/libmbedtls/mbedtls/library/ssl_tls12_server.c
index b49a8ae..03722ac 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_tls12_server.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_tls12_server.c
@@ -756,7 +756,9 @@
          * and decrypting with the same RSA key.
          */
         if (mbedtls_ssl_check_cert_usage(cur->cert, ciphersuite_info,
-                                         MBEDTLS_SSL_IS_SERVER, &flags) != 0) {
+                                         MBEDTLS_SSL_IS_CLIENT,
+                                         MBEDTLS_SSL_VERSION_TLS1_2,
+                                         &flags) != 0) {
             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: "
                                       "(extended) key usage extension"));
             continue;
@@ -2631,13 +2633,8 @@
             ssl->handshake->xxdh_psa_type = psa_get_key_type(&key_attributes);
             ssl->handshake->xxdh_psa_bits = psa_get_key_bits(&key_attributes);
 
-            if (pk_type == MBEDTLS_PK_OPAQUE) {
-                /* Opaque key is created by the user (externally from Mbed TLS)
-                 * so we assume it already has the right algorithm and flags
-                 * set. Just copy its ID as reference. */
-                ssl->handshake->xxdh_psa_privkey = pk->priv_id;
-                ssl->handshake->xxdh_psa_privkey_is_external = 1;
-            } else {
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+            if (pk_type != MBEDTLS_PK_OPAQUE) {
                 /* PK_ECKEY[_DH] and PK_ECDSA instead as parsed from the PK
                  * module and only have ECDSA capabilities. Since we need
                  * them for ECDH later, we export and then re-import them with
@@ -2665,10 +2662,20 @@
                 /* Set this key as owned by the TLS library: it will be its duty
                  * to clear it exit. */
                 ssl->handshake->xxdh_psa_privkey_is_external = 0;
-            }
 
+                ret = 0;
+                break;
+            }
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
+            /* Opaque key is created by the user (externally from Mbed TLS)
+             * so we assume it already has the right algorithm and flags
+             * set. Just copy its ID as reference. */
+            ssl->handshake->xxdh_psa_privkey = pk->priv_id;
+            ssl->handshake->xxdh_psa_privkey_is_external = 1;
             ret = 0;
             break;
+
 #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
         case MBEDTLS_PK_ECKEY:
         case MBEDTLS_PK_ECKEY_DH:
@@ -3916,7 +3923,7 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
-        uint8_t ecpoint_len;
+        size_t ecpoint_len;
 
         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
 
diff --git a/lib/libmbedtls/mbedtls/library/ssl_tls13_client.c b/lib/libmbedtls/mbedtls/library/ssl_tls13_client.c
index 7fcc394..b63b5e6 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_tls13_client.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_tls13_client.c
@@ -666,6 +666,7 @@
     return 0;
 }
 
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
 static psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg(int ciphersuite)
 {
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
@@ -678,7 +679,6 @@
     return PSA_ALG_NONE;
 }
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
 static int ssl_tls13_has_configured_ticket(mbedtls_ssl_context *ssl)
 {
     mbedtls_ssl_session *session = ssl->session_negotiate;
@@ -1141,6 +1141,11 @@
 
     *out_len = 0;
 
+    ret = mbedtls_ssl_tls13_crypto_init(ssl);
+    if (ret != 0) {
+        return ret;
+    }
+
     /* Write supported_versions extension
      *
      * Supported Versions Extension is mandatory with TLS 1.3.
diff --git a/lib/libmbedtls/mbedtls/library/ssl_tls13_generic.c b/lib/libmbedtls/mbedtls/library/ssl_tls13_generic.c
index d448a05..b6d0978 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_tls13_generic.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_tls13_generic.c
@@ -27,7 +27,6 @@
 #include "psa/crypto.h"
 #include "psa_util_internal.h"
 
-#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
 /* Define a local translating function to save code size by not using too many
  * arguments in each translating place. */
 static int local_err_translation(psa_status_t status)
@@ -37,7 +36,16 @@
                                  psa_generic_status_to_mbedtls);
 }
 #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
-#endif
+
+int mbedtls_ssl_tls13_crypto_init(mbedtls_ssl_context *ssl)
+{
+    psa_status_t status = psa_crypto_init();
+    if (status != PSA_SUCCESS) {
+        (void) ssl; // unused when debugging is disabled
+        MBEDTLS_SSL_DEBUG_RET(1, "psa_crypto_init", status);
+    }
+    return PSA_TO_MBEDTLS_ERR(status);
+}
 
 const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[
     MBEDTLS_SERVER_HELLO_RANDOM_LEN] =
@@ -193,10 +201,12 @@
     idx = 64;
 
     if (from == MBEDTLS_SSL_IS_CLIENT) {
-        memcpy(verify_buffer + idx, MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(client_cv));
+        memcpy(verify_buffer + idx, mbedtls_ssl_tls13_labels.client_cv,
+               MBEDTLS_SSL_TLS1_3_LBL_LEN(client_cv));
         idx += MBEDTLS_SSL_TLS1_3_LBL_LEN(client_cv);
     } else { /* from == MBEDTLS_SSL_IS_SERVER */
-        memcpy(verify_buffer + idx, MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(server_cv));
+        memcpy(verify_buffer + idx, mbedtls_ssl_tls13_labels.server_cv,
+               MBEDTLS_SSL_TLS1_3_LBL_LEN(server_cv));
         idx += MBEDTLS_SSL_TLS1_3_LBL_LEN(server_cv);
     }
 
@@ -470,6 +480,7 @@
         mbedtls_free(ssl->session_negotiate->peer_cert);
     }
 
+    /* This is used by ssl_tls13_validate_certificate() */
     if (certificate_list_len == 0) {
         ssl->session_negotiate->peer_cert = NULL;
         ret = 0;
@@ -625,25 +636,13 @@
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
 {
-    int ret = 0;
-    int authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
-    mbedtls_x509_crt *ca_chain;
-    mbedtls_x509_crl *ca_crl;
-    const char *ext_oid;
-    size_t ext_len;
-    uint32_t verify_result = 0;
-
-    /* If SNI was used, overwrite authentication mode
-     * from the configuration. */
-#if defined(MBEDTLS_SSL_SRV_C)
-    if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-        if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) {
-            authmode = ssl->handshake->sni_authmode;
-        } else
-#endif
-        authmode = ssl->conf->authmode;
-    }
+    /* Authmode: precedence order is SNI if used else configuration */
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
+                       ? ssl->handshake->sni_authmode
+                       : ssl->conf->authmode;
+#else
+    const int authmode = ssl->conf->authmode;
 #endif
 
     /*
@@ -675,6 +674,11 @@
 #endif /* MBEDTLS_SSL_SRV_C */
 
 #if defined(MBEDTLS_SSL_CLI_C)
+        /* Regardless of authmode, the server is not allowed to send an empty
+         * certificate chain. (Last paragraph before 4.4.2.1 in RFC 8446: "The
+         * server's certificate_list MUST always be non-empty.") With authmode
+         * optional/none, we continue the handshake if we can't validate the
+         * server's cert, but we still break it if no certificate was sent. */
         if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
             MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_NO_CERT,
                                          MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE);
@@ -683,114 +687,9 @@
 #endif /* MBEDTLS_SSL_CLI_C */
     }
 
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-    if (ssl->handshake->sni_ca_chain != NULL) {
-        ca_chain = ssl->handshake->sni_ca_chain;
-        ca_crl = ssl->handshake->sni_ca_crl;
-    } else
-#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
-    {
-        ca_chain = ssl->conf->ca_chain;
-        ca_crl = ssl->conf->ca_crl;
-    }
-
-    /*
-     * Main check: verify certificate
-     */
-    ret = mbedtls_x509_crt_verify_with_profile(
-        ssl->session_negotiate->peer_cert,
-        ca_chain, ca_crl,
-        ssl->conf->cert_profile,
-        ssl->hostname,
-        &verify_result,
-        ssl->conf->f_vrfy, ssl->conf->p_vrfy);
-
-    if (ret != 0) {
-        MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret);
-    }
-
-    /*
-     * Secondary checks: always done, but change 'ret' only if it was 0
-     */
-    if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-        ext_oid = MBEDTLS_OID_SERVER_AUTH;
-        ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
-    } else {
-        ext_oid = MBEDTLS_OID_CLIENT_AUTH;
-        ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
-    }
-
-    if ((mbedtls_x509_crt_check_key_usage(
-             ssl->session_negotiate->peer_cert,
-             MBEDTLS_X509_KU_DIGITAL_SIGNATURE) != 0) ||
-        (mbedtls_x509_crt_check_extended_key_usage(
-             ssl->session_negotiate->peer_cert,
-             ext_oid, ext_len) != 0)) {
-        MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
-        if (ret == 0) {
-            ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
-        }
-    }
-
-    /* mbedtls_x509_crt_verify_with_profile is supposed to report a
-     * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
-     * with details encoded in the verification flags. All other kinds
-     * of error codes, including those from the user provided f_vrfy
-     * functions, are treated as fatal and lead to a failure of
-     * mbedtls_ssl_tls13_parse_certificate even if verification was optional.
-     */
-    if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
-        (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
-         ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE)) {
-        ret = 0;
-    }
-
-    if (ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
-        MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain"));
-        ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
-    }
-
-    if (ret != 0) {
-        /* The certificate may have been rejected for several reasons.
-           Pick one and send the corresponding alert. Which alert to send
-           may be a subject of debate in some cases. */
-        if (verify_result & MBEDTLS_X509_BADCERT_OTHER) {
-            MBEDTLS_SSL_PEND_FATAL_ALERT(
-                MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED, ret);
-        } else if (verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
-            MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_BAD_CERT, ret);
-        } else if (verify_result & (MBEDTLS_X509_BADCERT_KEY_USAGE |
-                                    MBEDTLS_X509_BADCERT_EXT_KEY_USAGE |
-                                    MBEDTLS_X509_BADCERT_NS_CERT_TYPE |
-                                    MBEDTLS_X509_BADCERT_BAD_PK |
-                                    MBEDTLS_X509_BADCERT_BAD_KEY)) {
-            MBEDTLS_SSL_PEND_FATAL_ALERT(
-                MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT, ret);
-        } else if (verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
-            MBEDTLS_SSL_PEND_FATAL_ALERT(
-                MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED, ret);
-        } else if (verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
-            MBEDTLS_SSL_PEND_FATAL_ALERT(
-                MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED, ret);
-        } else if (verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
-            MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA, ret);
-        } else {
-            MBEDTLS_SSL_PEND_FATAL_ALERT(
-                MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN, ret);
-        }
-    }
-
-#if defined(MBEDTLS_DEBUG_C)
-    if (verify_result != 0) {
-        MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x",
-                                  (unsigned int) verify_result));
-    } else {
-        MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear"));
-    }
-#endif /* MBEDTLS_DEBUG_C */
-
-    ssl->session_negotiate->verify_result = verify_result;
-    return ret;
+    return mbedtls_ssl_verify_certificate(ssl, authmode,
+                                          ssl->session_negotiate->peer_cert,
+                                          NULL, NULL);
 }
 #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 MBEDTLS_CHECK_RETURN_CRITICAL
@@ -1482,9 +1381,11 @@
          ssl->total_early_data_size)) {
 
         MBEDTLS_SSL_DEBUG_MSG(
-            2, ("EarlyData: Too much early data received, %u + %" MBEDTLS_PRINTF_SIZET " > %u",
-                ssl->total_early_data_size, early_data_len,
-                ssl->session_negotiate->max_early_data_size));
+            2, ("EarlyData: Too much early data received, "
+                "%lu + %" MBEDTLS_PRINTF_SIZET " > %lu",
+                (unsigned long) ssl->total_early_data_size,
+                early_data_len,
+                (unsigned long) ssl->session_negotiate->max_early_data_size));
 
         MBEDTLS_SSL_PEND_FATAL_ALERT(
             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
diff --git a/lib/libmbedtls/mbedtls/library/ssl_tls13_server.c b/lib/libmbedtls/mbedtls/library/ssl_tls13_server.c
index 2760d76..693edc7 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_tls13_server.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_tls13_server.c
@@ -92,8 +92,9 @@
         return;
     }
 
-    MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%x",
-                              (unsigned) psk_ciphersuite_id, psk_hash_alg));
+    MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%lx",
+                              (unsigned) psk_ciphersuite_id,
+                              (unsigned long) psk_hash_alg));
 }
 
 #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
@@ -172,12 +173,12 @@
 #define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE 1
 #define SSL_TLS1_3_PSK_IDENTITY_MATCH 0
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl);
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl);
 
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_tls13_offered_psks_check_identity_match_ticket(
     mbedtls_ssl_context *ssl,
@@ -575,10 +576,8 @@
         psa_algorithm_t psk_hash_alg;
         int allowed_key_exchange_modes;
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
         mbedtls_ssl_session session;
         mbedtls_ssl_session_init(&session);
-#endif
 
         MBEDTLS_SSL_CHK_BUF_READ_PTR(p_identity_len, identities_end, 2 + 1 + 4);
         identity_len = MBEDTLS_GET_UINT16_BE(p_identity_len, 0);
@@ -1356,19 +1355,23 @@
      * compression methods and the length of the extensions.
      *
      * cipher_suites                cipher_suites_len bytes
-     * legacy_compression_methods                   2 bytes
-     * extensions_len                               2 bytes
+     * legacy_compression_methods length            1 byte
      */
-    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cipher_suites_len + 2 + 2);
+    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cipher_suites_len + 1);
     p += cipher_suites_len;
     cipher_suites_end = p;
 
+    /* Check if we have enough data for legacy_compression_methods
+     * and the length of the extensions (2 bytes).
+     */
+    MBEDTLS_SSL_CHK_BUF_READ_PTR(p + 1, end, p[0] + 2);
+
     /*
      * Search for the supported versions extension and parse it to determine
      * if the client supports TLS 1.3.
      */
     ret = mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts(
-        ssl, p + 2, end,
+        ssl, p + 1 + p[0], end,
         &supported_versions_data, &supported_versions_data_end);
     if (ret < 0) {
         MBEDTLS_SSL_DEBUG_RET(1,
@@ -1409,6 +1412,12 @@
     ssl->session_negotiate->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
     ssl->session_negotiate->endpoint = ssl->conf->endpoint;
 
+    /* Before doing any crypto, make sure we can. */
+    ret = mbedtls_ssl_tls13_crypto_init(ssl);
+    if (ret != 0) {
+        return ret;
+    }
+
     /*
      * We are negotiating the version 1.3 of the protocol. Do what we have
      * postponed: copy of the client random bytes, copy of the legacy session
@@ -3109,6 +3118,7 @@
     return 0;
 }
 
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
 /*
  * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
  */
@@ -3138,7 +3148,6 @@
     return SSL_NEW_SESSION_TICKET_WRITE;
 }
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
 MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
                                                 unsigned char *ticket_nonce,
diff --git a/lib/libmbedtls/mbedtls/library/version_features.c b/lib/libmbedtls/mbedtls/library/version_features.c
index 406161d..f542d98 100644
--- a/lib/libmbedtls/mbedtls/library/version_features.c
+++ b/lib/libmbedtls/mbedtls/library/version_features.c
@@ -423,6 +423,9 @@
 #if defined(MBEDTLS_PSA_CRYPTO_SPM)
     "PSA_CRYPTO_SPM", //no-check-names
 #endif /* MBEDTLS_PSA_CRYPTO_SPM */
+#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
+    "PSA_KEY_STORE_DYNAMIC", //no-check-names
+#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
 #if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
     "PSA_P256M_DRIVER_ENABLED", //no-check-names
 #endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */
diff --git a/lib/libmbedtls/mbedtls/library/x509_crt.c b/lib/libmbedtls/mbedtls/library/x509_crt.c
index 2fd56fb..53cdcf0 100644
--- a/lib/libmbedtls/mbedtls/library/x509_crt.c
+++ b/lib/libmbedtls/mbedtls/library/x509_crt.c
@@ -48,7 +48,9 @@
 
 #if defined(MBEDTLS_HAVE_TIME)
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+#ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
+#endif
 #include <windows.h>
 #else
 #include <time.h>
diff --git a/lib/libmbedtls/mbedtls/library/x509write_crt.c b/lib/libmbedtls/mbedtls/library/x509write_crt.c
index 72f5a10..56f23c9 100644
--- a/lib/libmbedtls/mbedtls/library/x509write_crt.c
+++ b/lib/libmbedtls/mbedtls/library/x509write_crt.c
@@ -46,6 +46,10 @@
 
 void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     mbedtls_asn1_free_named_data_list(&ctx->subject);
     mbedtls_asn1_free_named_data_list(&ctx->issuer);
     mbedtls_asn1_free_named_data_list(&ctx->extensions);
diff --git a/lib/libmbedtls/mbedtls/library/x509write_csr.c b/lib/libmbedtls/mbedtls/library/x509write_csr.c
index d3ddbcc..0d6f6bb 100644
--- a/lib/libmbedtls/mbedtls/library/x509write_csr.c
+++ b/lib/libmbedtls/mbedtls/library/x509write_csr.c
@@ -43,6 +43,10 @@
 
 void mbedtls_x509write_csr_free(mbedtls_x509write_csr *ctx)
 {
+    if (ctx == NULL) {
+        return;
+    }
+
     mbedtls_asn1_free_named_data_list(&ctx->subject);
     mbedtls_asn1_free_named_data_list(&ctx->extensions);