Squashed commit upgrading to mbedtls-2.28.1

Squash merging branch import/mbedtls-2.28.1

 ebf1f6a58089 ("libmbedtls: compile new files added with 2.28.1")
 3ffb51b58a54 ("libmbedtls: add SM2 curve")
 c425755720b4 ("libmbedtls: mbedtls_mpi_exp_mod(): optimize mempool usage")
 23493c822a82 ("libmbedtls: mbedtls_mpi_exp_mod(): reduce stack usage")
 dcdca2348dff ("libmbedtls: mbedtls_mpi_exp_mod() initialize W")
 dc2994976958 ("libmbedtls: fix no CRT issue")
 c6628873b281 ("libmbedtls: add interfaces in mbedtls for context memory operation")
 8acd202d3e55 ("libmedtls: mpi_miller_rabin: increase count limit")
 37284e28d5d9 ("libmbedtls: add mbedtls_mpi_init_mempool()")
 b499a75f29f3 ("libmbedtls: make mbedtls_mpi_mont*() available")
 2080a8c96a5d ("mbedtls: configure mbedtls to reach for config")
 e0858334327a ("mbedtls: remove default include/mbedtls/config.h")
 dd9688e6b8ce ("Import mbedtls-2.28.1")

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/lib/libmbedtls/mbedtls/library/aes.c b/lib/libmbedtls/mbedtls/library/aes.c
index 3f61642..03d8b7e 100644
--- a/lib/libmbedtls/mbedtls/library/aes.c
+++ b/lib/libmbedtls/mbedtls/library/aes.c
@@ -57,29 +57,6 @@
 #define AES_VALIDATE( cond )        \
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ]       )             \
-        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i)                                    \
-{                                                               \
-    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
-    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
-    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
-    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
-}
-#endif
-
 #if defined(MBEDTLS_PADLOCK_C) &&                      \
     ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
 static int aes_padlock_ace = -1;
@@ -409,7 +386,7 @@
     {
         pow[i] = x;
         log[x] = i;
-        x = ( x ^ XTIME( x ) ) & 0xFF;
+        x = MBEDTLS_BYTE_0( x ^ XTIME( x ) );
     }
 
     /*
@@ -418,7 +395,7 @@
     for( i = 0, x = 1; i < 10; i++ )
     {
         RCON[i] = (uint32_t) x;
-        x = XTIME( x ) & 0xFF;
+        x = MBEDTLS_BYTE_0( XTIME( x ) );
     }
 
     /*
@@ -431,10 +408,10 @@
     {
         x = pow[255 - log[i]];
 
-        y  = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
-        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
-        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
-        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        y  = x; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+        x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+        x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+        x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
         x ^= y ^ 0x63;
 
         FSb[i] = (unsigned char) x;
@@ -447,8 +424,8 @@
     for( i = 0; i < 256; i++ )
     {
         x = FSb[i];
-        y = XTIME( x ) & 0xFF;
-        z =  ( y ^ x ) & 0xFF;
+        y = MBEDTLS_BYTE_0( XTIME( x ) );
+        z = MBEDTLS_BYTE_0( y ^ x );
 
         FT0[i] = ( (uint32_t) y       ) ^
                  ( (uint32_t) x <<  8 ) ^
@@ -590,7 +567,7 @@
 
     for( i = 0; i < ( keybits >> 5 ); i++ )
     {
-        GET_UINT32_LE( RK[i], key, i << 2 );
+        RK[i] = MBEDTLS_GET_UINT32_LE( key, i << 2 );
     }
 
     switch( ctx->nr )
@@ -600,10 +577,10 @@
             for( i = 0; i < 10; i++, RK += 4 )
             {
                 RK[4]  = RK[0] ^ RCON[i] ^
-                ( (uint32_t) FSb[ ( RK[3] >>  8 ) & 0xFF ]       ) ^
-                ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] <<  8 ) ^
-                ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
-                ( (uint32_t) FSb[ ( RK[3]       ) & 0xFF ] << 24 );
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[3] ) ]       ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[3] ) ] <<  8 ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[3] ) ] << 16 ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[3] ) ] << 24 );
 
                 RK[5]  = RK[1] ^ RK[4];
                 RK[6]  = RK[2] ^ RK[5];
@@ -616,10 +593,10 @@
             for( i = 0; i < 8; i++, RK += 6 )
             {
                 RK[6]  = RK[0] ^ RCON[i] ^
-                ( (uint32_t) FSb[ ( RK[5] >>  8 ) & 0xFF ]       ) ^
-                ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] <<  8 ) ^
-                ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
-                ( (uint32_t) FSb[ ( RK[5]       ) & 0xFF ] << 24 );
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[5] ) ]       ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[5] ) ] <<  8 ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[5] ) ] << 16 ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[5] ) ] << 24 );
 
                 RK[7]  = RK[1] ^ RK[6];
                 RK[8]  = RK[2] ^ RK[7];
@@ -634,20 +611,20 @@
             for( i = 0; i < 7; i++, RK += 8 )
             {
                 RK[8]  = RK[0] ^ RCON[i] ^
-                ( (uint32_t) FSb[ ( RK[7] >>  8 ) & 0xFF ]       ) ^
-                ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] <<  8 ) ^
-                ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
-                ( (uint32_t) FSb[ ( RK[7]       ) & 0xFF ] << 24 );
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[7] ) ]       ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[7] ) ] <<  8 ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[7] ) ] << 16 ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[7] ) ] << 24 );
 
                 RK[9]  = RK[1] ^ RK[8];
                 RK[10] = RK[2] ^ RK[9];
                 RK[11] = RK[3] ^ RK[10];
 
                 RK[12] = RK[4] ^
-                ( (uint32_t) FSb[ ( RK[11]       ) & 0xFF ]       ) ^
-                ( (uint32_t) FSb[ ( RK[11] >>  8 ) & 0xFF ] <<  8 ) ^
-                ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
-                ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[11] ) ]       ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[11] ) ] <<  8 ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[11] ) ] << 16 ) ^
+                ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[11] ) ] << 24 );
 
                 RK[13] = RK[5] ^ RK[12];
                 RK[14] = RK[6] ^ RK[13];
@@ -713,10 +690,10 @@
     {
         for( j = 0; j < 4; j++, SK++ )
         {
-            *RK++ = AES_RT0( FSb[ ( *SK       ) & 0xFF ] ) ^
-                    AES_RT1( FSb[ ( *SK >>  8 ) & 0xFF ] ) ^
-                    AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
-                    AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
+            *RK++ = AES_RT0( FSb[ MBEDTLS_BYTE_0( *SK ) ] ) ^
+                    AES_RT1( FSb[ MBEDTLS_BYTE_1( *SK ) ] ) ^
+                    AES_RT2( FSb[ MBEDTLS_BYTE_2( *SK ) ] ) ^
+                    AES_RT3( FSb[ MBEDTLS_BYTE_3( *SK ) ] );
         }
     }
 
@@ -809,52 +786,52 @@
 }
 #endif /* MBEDTLS_CIPHER_MODE_XTS */
 
-#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)                     \
-    do                                                          \
-    {                                                           \
-        (X0) = *RK++ ^ AES_FT0( ( (Y0)       ) & 0xFF ) ^       \
-                       AES_FT1( ( (Y1) >>  8 ) & 0xFF ) ^       \
-                       AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^       \
-                       AES_FT3( ( (Y3) >> 24 ) & 0xFF );        \
-                                                                \
-        (X1) = *RK++ ^ AES_FT0( ( (Y1)       ) & 0xFF ) ^       \
-                       AES_FT1( ( (Y2) >>  8 ) & 0xFF ) ^       \
-                       AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^       \
-                       AES_FT3( ( (Y0) >> 24 ) & 0xFF );        \
-                                                                \
-        (X2) = *RK++ ^ AES_FT0( ( (Y2)       ) & 0xFF ) ^       \
-                       AES_FT1( ( (Y3) >>  8 ) & 0xFF ) ^       \
-                       AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^       \
-                       AES_FT3( ( (Y1) >> 24 ) & 0xFF );        \
-                                                                \
-        (X3) = *RK++ ^ AES_FT0( ( (Y3)       ) & 0xFF ) ^       \
-                       AES_FT1( ( (Y0) >>  8 ) & 0xFF ) ^       \
-                       AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^       \
-                       AES_FT3( ( (Y2) >> 24 ) & 0xFF );        \
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)                 \
+    do                                                      \
+    {                                                       \
+        (X0) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y0 ) ) ^    \
+                       AES_FT1( MBEDTLS_BYTE_1( Y1 ) ) ^    \
+                       AES_FT2( MBEDTLS_BYTE_2( Y2 ) ) ^    \
+                       AES_FT3( MBEDTLS_BYTE_3( Y3 ) );     \
+                                                            \
+        (X1) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y1 ) ) ^    \
+                       AES_FT1( MBEDTLS_BYTE_1( Y2 ) ) ^    \
+                       AES_FT2( MBEDTLS_BYTE_2( Y3 ) ) ^    \
+                       AES_FT3( MBEDTLS_BYTE_3( Y0 ) );     \
+                                                            \
+        (X2) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y2 ) ) ^    \
+                       AES_FT1( MBEDTLS_BYTE_1( Y3 ) ) ^    \
+                       AES_FT2( MBEDTLS_BYTE_2( Y0 ) ) ^    \
+                       AES_FT3( MBEDTLS_BYTE_3( Y1 ) );     \
+                                                            \
+        (X3) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y3 ) ) ^    \
+                       AES_FT1( MBEDTLS_BYTE_1( Y0 ) ) ^    \
+                       AES_FT2( MBEDTLS_BYTE_2( Y1 ) ) ^    \
+                       AES_FT3( MBEDTLS_BYTE_3( Y2 ) );     \
     } while( 0 )
 
 #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)                 \
     do                                                      \
     {                                                       \
-        (X0) = *RK++ ^ AES_RT0( ( (Y0)       ) & 0xFF ) ^   \
-                       AES_RT1( ( (Y3) >>  8 ) & 0xFF ) ^   \
-                       AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^   \
-                       AES_RT3( ( (Y1) >> 24 ) & 0xFF );    \
+        (X0) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y0 ) ) ^    \
+                       AES_RT1( MBEDTLS_BYTE_1( Y3 ) ) ^    \
+                       AES_RT2( MBEDTLS_BYTE_2( Y2 ) ) ^    \
+                       AES_RT3( MBEDTLS_BYTE_3( Y1 ) );     \
                                                             \
-        (X1) = *RK++ ^ AES_RT0( ( (Y1)       ) & 0xFF ) ^   \
-                       AES_RT1( ( (Y0) >>  8 ) & 0xFF ) ^   \
-                       AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^   \
-                       AES_RT3( ( (Y2) >> 24 ) & 0xFF );    \
+        (X1) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y1 ) ) ^    \
+                       AES_RT1( MBEDTLS_BYTE_1( Y0 ) ) ^    \
+                       AES_RT2( MBEDTLS_BYTE_2( Y3 ) ) ^    \
+                       AES_RT3( MBEDTLS_BYTE_3( Y2 ) );     \
                                                             \
-        (X2) = *RK++ ^ AES_RT0( ( (Y2)       ) & 0xFF ) ^   \
-                       AES_RT1( ( (Y1) >>  8 ) & 0xFF ) ^   \
-                       AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^   \
-                       AES_RT3( ( (Y3) >> 24 ) & 0xFF );    \
+        (X2) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y2 ) ) ^    \
+                       AES_RT1( MBEDTLS_BYTE_1( Y1 ) ) ^    \
+                       AES_RT2( MBEDTLS_BYTE_2( Y0 ) ) ^    \
+                       AES_RT3( MBEDTLS_BYTE_3( Y3 ) );     \
                                                             \
-        (X3) = *RK++ ^ AES_RT0( ( (Y3)       ) & 0xFF ) ^   \
-                       AES_RT1( ( (Y2) >>  8 ) & 0xFF ) ^   \
-                       AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^   \
-                       AES_RT3( ( (Y0) >> 24 ) & 0xFF );    \
+        (X3) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y3 ) ) ^    \
+                       AES_RT1( MBEDTLS_BYTE_1( Y2 ) ) ^    \
+                       AES_RT2( MBEDTLS_BYTE_2( Y1 ) ) ^    \
+                       AES_RT3( MBEDTLS_BYTE_3( Y0 ) );     \
     } while( 0 )
 
 /*
@@ -873,10 +850,10 @@
         uint32_t Y[4];
     } t;
 
-    GET_UINT32_LE( t.X[0], input,  0 ); t.X[0] ^= *RK++;
-    GET_UINT32_LE( t.X[1], input,  4 ); t.X[1] ^= *RK++;
-    GET_UINT32_LE( t.X[2], input,  8 ); t.X[2] ^= *RK++;
-    GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
+    t.X[0] = MBEDTLS_GET_UINT32_LE( input,  0 ); t.X[0] ^= *RK++;
+    t.X[1] = MBEDTLS_GET_UINT32_LE( input,  4 ); t.X[1] ^= *RK++;
+    t.X[2] = MBEDTLS_GET_UINT32_LE( input,  8 ); t.X[2] ^= *RK++;
+    t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
 
     for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
     {
@@ -887,33 +864,33 @@
     AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
 
     t.X[0] = *RK++ ^ \
-            ( (uint32_t) FSb[ ( t.Y[0]       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( t.Y[1] >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[0] ) ]       ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] <<  8 ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
 
     t.X[1] = *RK++ ^ \
-            ( (uint32_t) FSb[ ( t.Y[1]       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( t.Y[2] >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[1] ) ]       ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] <<  8 ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
 
     t.X[2] = *RK++ ^ \
-            ( (uint32_t) FSb[ ( t.Y[2]       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( t.Y[3] >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[2] ) ]       ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] <<  8 ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
 
     t.X[3] = *RK++ ^ \
-            ( (uint32_t) FSb[ ( t.Y[3]       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( t.Y[0] >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[3] ) ]       ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] <<  8 ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
+            ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
 
-    PUT_UINT32_LE( t.X[0], output,  0 );
-    PUT_UINT32_LE( t.X[1], output,  4 );
-    PUT_UINT32_LE( t.X[2], output,  8 );
-    PUT_UINT32_LE( t.X[3], output, 12 );
+    MBEDTLS_PUT_UINT32_LE( t.X[0], output,  0 );
+    MBEDTLS_PUT_UINT32_LE( t.X[1], output,  4 );
+    MBEDTLS_PUT_UINT32_LE( t.X[2], output,  8 );
+    MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
 
     mbedtls_platform_zeroize( &t, sizeof( t ) );
 
@@ -926,7 +903,7 @@
                           const unsigned char input[16],
                           unsigned char output[16] )
 {
-    mbedtls_internal_aes_encrypt( ctx, input, output );
+    MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_encrypt( ctx, input, output ) );
 }
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
@@ -946,10 +923,10 @@
         uint32_t Y[4];
     } t;
 
-    GET_UINT32_LE( t.X[0], input,  0 ); t.X[0] ^= *RK++;
-    GET_UINT32_LE( t.X[1], input,  4 ); t.X[1] ^= *RK++;
-    GET_UINT32_LE( t.X[2], input,  8 ); t.X[2] ^= *RK++;
-    GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
+    t.X[0] = MBEDTLS_GET_UINT32_LE( input,  0 ); t.X[0] ^= *RK++;
+    t.X[1] = MBEDTLS_GET_UINT32_LE( input,  4 ); t.X[1] ^= *RK++;
+    t.X[2] = MBEDTLS_GET_UINT32_LE( input,  8 ); t.X[2] ^= *RK++;
+    t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
 
     for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
     {
@@ -960,33 +937,33 @@
     AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
 
     t.X[0] = *RK++ ^ \
-            ( (uint32_t) RSb[ ( t.Y[0]       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( t.Y[3] >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[0] ) ]       ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] <<  8 ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
 
     t.X[1] = *RK++ ^ \
-            ( (uint32_t) RSb[ ( t.Y[1]       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( t.Y[0] >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[1] ) ]       ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] <<  8 ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
 
     t.X[2] = *RK++ ^ \
-            ( (uint32_t) RSb[ ( t.Y[2]       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( t.Y[1] >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[2] ) ]       ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] <<  8 ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
 
     t.X[3] = *RK++ ^ \
-            ( (uint32_t) RSb[ ( t.Y[3]       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( t.Y[2] >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[3] ) ]       ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] <<  8 ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
+            ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
 
-    PUT_UINT32_LE( t.X[0], output,  0 );
-    PUT_UINT32_LE( t.X[1], output,  4 );
-    PUT_UINT32_LE( t.X[2], output,  8 );
-    PUT_UINT32_LE( t.X[3], output, 12 );
+    MBEDTLS_PUT_UINT32_LE( t.X[0], output,  0 );
+    MBEDTLS_PUT_UINT32_LE( t.X[1], output,  4 );
+    MBEDTLS_PUT_UINT32_LE( t.X[2], output,  8 );
+    MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
 
     mbedtls_platform_zeroize( &t, sizeof( t ) );
 
@@ -999,7 +976,7 @@
                           const unsigned char input[16],
                           unsigned char output[16] )
 {
-    mbedtls_internal_aes_decrypt( ctx, input, output );
+    MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_decrypt( ctx, input, output ) );
 }
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
 
@@ -1052,6 +1029,7 @@
                     unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[16];
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1081,7 +1059,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 16 );
-            mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+            ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 16; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -1100,7 +1080,9 @@
             for( i = 0; i < 16; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 16 );
 
             input  += 16;
@@ -1108,42 +1090,15 @@
             length -= 16;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
 #if defined(MBEDTLS_CIPHER_MODE_XTS)
 
-/* Endianess with 64 bits values */
-#ifndef GET_UINT64_LE
-#define GET_UINT64_LE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint64_t) (b)[(i) + 7] << 56 )             \
-        | ( (uint64_t) (b)[(i) + 6] << 48 )             \
-        | ( (uint64_t) (b)[(i) + 5] << 40 )             \
-        | ( (uint64_t) (b)[(i) + 4] << 32 )             \
-        | ( (uint64_t) (b)[(i) + 3] << 24 )             \
-        | ( (uint64_t) (b)[(i) + 2] << 16 )             \
-        | ( (uint64_t) (b)[(i) + 1] <<  8 )             \
-        | ( (uint64_t) (b)[(i)    ]       );            \
-}
-#endif
-
-#ifndef PUT_UINT64_LE
-#define PUT_UINT64_LE(n,b,i)                            \
-{                                                       \
-    (b)[(i) + 7] = (unsigned char) ( (n) >> 56 );       \
-    (b)[(i) + 6] = (unsigned char) ( (n) >> 48 );       \
-    (b)[(i) + 5] = (unsigned char) ( (n) >> 40 );       \
-    (b)[(i) + 4] = (unsigned char) ( (n) >> 32 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i)    ] = (unsigned char) ( (n)       );       \
-}
-#endif
-
 typedef unsigned char mbedtls_be128[16];
 
 /*
@@ -1151,7 +1106,7 @@
  *
  * This function multiplies a field element by x in the polynomial field
  * representation. It uses 64-bit word operations to gain speed but compensates
- * for machine endianess and hence works correctly on both big and little
+ * for machine endianness and hence works correctly on both big and little
  * endian machines.
  */
 static void mbedtls_gf128mul_x_ble( unsigned char r[16],
@@ -1159,14 +1114,14 @@
 {
     uint64_t a, b, ra, rb;
 
-    GET_UINT64_LE( a, x, 0 );
-    GET_UINT64_LE( b, x, 8 );
+    a = MBEDTLS_GET_UINT64_LE( x, 0 );
+    b = MBEDTLS_GET_UINT64_LE( x, 8 );
 
     ra = ( a << 1 )  ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
     rb = ( a >> 63 ) | ( b << 1 );
 
-    PUT_UINT64_LE( ra, r, 0 );
-    PUT_UINT64_LE( rb, r, 8 );
+    MBEDTLS_PUT_UINT64_LE( ra, r, 0 );
+    MBEDTLS_PUT_UINT64_LE( rb, r, 8 );
 }
 
 /*
@@ -1251,7 +1206,7 @@
         unsigned char *prev_output = output - 16;
 
         /* Copy ciphertext bytes from the previous block to our output for each
-         * byte of cyphertext we won't steal. At the same time, copy the
+         * byte of ciphertext we won't steal. At the same time, copy the
          * remainder of the input for this final round (since the loop bounds
          * are the same). */
         for( i = 0; i < leftover; i++ )
@@ -1292,6 +1247,7 @@
                        unsigned char *output )
 {
     int c;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1312,7 +1268,11 @@
         while( length-- )
         {
             if( n == 0 )
-                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            {
+                ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+                if( ret != 0 )
+                    goto exit;
+            }
 
             c = *input++;
             *output++ = (unsigned char)( c ^ iv[n] );
@@ -1326,7 +1286,11 @@
         while( length-- )
         {
             if( n == 0 )
-                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            {
+                ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+                if( ret != 0 )
+                    goto exit;
+            }
 
             iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
 
@@ -1335,8 +1299,10 @@
     }
 
     *iv_off = n;
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 
 /*
@@ -1349,6 +1315,7 @@
                             const unsigned char *input,
                             unsigned char *output )
 {
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char c;
     unsigned char ov[17];
 
@@ -1361,7 +1328,9 @@
     while( length-- )
     {
         memcpy( ov, iv, 16 );
-        mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+        if( ret != 0 )
+            goto exit;
 
         if( mode == MBEDTLS_AES_DECRYPT )
             ov[16] = *input;
@@ -1373,8 +1342,10 @@
 
         memcpy( iv, ov + 1, 16 );
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
@@ -1436,6 +1407,7 @@
                        unsigned char *output )
 {
     int c, i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
 
     AES_VALIDATE_RET( ctx != NULL );
@@ -1453,7 +1425,9 @@
     while( length-- )
     {
         if( n == 0 ) {
-            mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+            ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 16; i > 0; i-- )
                 if( ++nonce_counter[i - 1] != 0 )
@@ -1466,8 +1440,10 @@
     }
 
     *nc_off = n;
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
diff --git a/lib/libmbedtls/mbedtls/library/aria.c b/lib/libmbedtls/mbedtls/library/aria.c
index a5786b3..bc05c4a 100644
--- a/lib/libmbedtls/mbedtls/library/aria.c
+++ b/lib/libmbedtls/mbedtls/library/aria.c
@@ -56,29 +56,6 @@
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
 /*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE( n, b, i )                \
-{                                               \
-    (n) = ( (uint32_t) (b)[(i)    ]       )     \
-        | ( (uint32_t) (b)[(i) + 1] <<  8 )     \
-        | ( (uint32_t) (b)[(i) + 2] << 16 )     \
-        | ( (uint32_t) (b)[(i) + 3] << 24 );    \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE( n, b, i )                                \
-{                                                               \
-    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
-    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
-    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
-    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
-}
-#endif
-
-/*
  * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
  *
  * This is submatrix P1 in [1] Appendix B.1
@@ -235,22 +212,22 @@
                             const uint8_t sa[256], const uint8_t sb[256],
                             const uint8_t sc[256], const uint8_t sd[256] )
 {
-    *a = ( (uint32_t) sa[ *a        & 0xFF]       ) ^
-         (((uint32_t) sb[(*a >>  8) & 0xFF]) <<  8) ^
-         (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
-         (((uint32_t) sd[ *a >> 24        ]) << 24);
-    *b = ( (uint32_t) sa[ *b        & 0xFF]       ) ^
-         (((uint32_t) sb[(*b >>  8) & 0xFF]) <<  8) ^
-         (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
-         (((uint32_t) sd[ *b >> 24        ]) << 24);
-    *c = ( (uint32_t) sa[ *c        & 0xFF]       ) ^
-         (((uint32_t) sb[(*c >>  8) & 0xFF]) <<  8) ^
-         (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
-         (((uint32_t) sd[ *c >> 24        ]) << 24);
-    *d = ( (uint32_t) sa[ *d        & 0xFF]       ) ^
-         (((uint32_t) sb[(*d >>  8) & 0xFF]) <<  8) ^
-         (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
-         (((uint32_t) sd[ *d >> 24        ]) << 24);
+    *a = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *a ) ]       ) ^
+         (((uint32_t) sb[ MBEDTLS_BYTE_1( *a ) ]) <<  8) ^
+         (((uint32_t) sc[ MBEDTLS_BYTE_2( *a ) ]) << 16) ^
+         (((uint32_t) sd[ MBEDTLS_BYTE_3( *a ) ]) << 24);
+    *b = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *b ) ]       ) ^
+         (((uint32_t) sb[ MBEDTLS_BYTE_1( *b ) ]) <<  8) ^
+         (((uint32_t) sc[ MBEDTLS_BYTE_2( *b ) ]) << 16) ^
+         (((uint32_t) sd[ MBEDTLS_BYTE_3( *b ) ]) << 24);
+    *c = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *c ) ]       ) ^
+         (((uint32_t) sb[ MBEDTLS_BYTE_1( *c ) ]) <<  8) ^
+         (((uint32_t) sc[ MBEDTLS_BYTE_2( *c ) ]) << 16) ^
+         (((uint32_t) sd[ MBEDTLS_BYTE_3( *c ) ]) << 24);
+    *d = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *d ) ]       ) ^
+         (((uint32_t) sb[ MBEDTLS_BYTE_1( *d ) ]) <<  8) ^
+         (((uint32_t) sc[ MBEDTLS_BYTE_2( *d ) ]) << 16) ^
+         (((uint32_t) sd[ MBEDTLS_BYTE_3( *d ) ]) << 24);
 }
 
 /*
@@ -408,7 +385,8 @@
  * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
  *
  * We chose to store bytes into 32-bit words in little-endian format (see
- * GET/PUT_UINT32_LE) so we need to reverse bytes here.
+ * MBEDTLS_GET_UINT32_LE / MBEDTLS_PUT_UINT32_LE ) so we need to reverse
+ * bytes here.
  */
 static void aria_rot128( uint32_t r[4], const uint32_t a[4],
                          const uint32_t b[4], uint8_t n )
@@ -456,21 +434,21 @@
         return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
 
     /* Copy key to W0 (and potential remainder to W1) */
-    GET_UINT32_LE( w[0][0], key,  0 );
-    GET_UINT32_LE( w[0][1], key,  4 );
-    GET_UINT32_LE( w[0][2], key,  8 );
-    GET_UINT32_LE( w[0][3], key, 12 );
+    w[0][0] = MBEDTLS_GET_UINT32_LE( key,  0 );
+    w[0][1] = MBEDTLS_GET_UINT32_LE( key,  4 );
+    w[0][2] = MBEDTLS_GET_UINT32_LE( key,  8 );
+    w[0][3] = MBEDTLS_GET_UINT32_LE( key, 12 );
 
     memset( w[1], 0, 16 );
     if( keybits >= 192 )
     {
-        GET_UINT32_LE( w[1][0], key, 16 );  // 192 bit key
-        GET_UINT32_LE( w[1][1], key, 20 );
+        w[1][0] = MBEDTLS_GET_UINT32_LE( key, 16 );  // 192 bit key
+        w[1][1] = MBEDTLS_GET_UINT32_LE( key, 20 );
     }
     if( keybits == 256 )
     {
-        GET_UINT32_LE( w[1][2], key, 24 );  // 256 bit key
-        GET_UINT32_LE( w[1][3], key, 28 );
+        w[1][2] = MBEDTLS_GET_UINT32_LE( key, 24 );  // 256 bit key
+        w[1][3] = MBEDTLS_GET_UINT32_LE( key, 28 );
     }
 
     i = ( keybits - 128 ) >> 6;             // index: 0, 1, 2
@@ -547,10 +525,10 @@
     ARIA_VALIDATE_RET( input != NULL );
     ARIA_VALIDATE_RET( output != NULL );
 
-    GET_UINT32_LE( a, input,  0 );
-    GET_UINT32_LE( b, input,  4 );
-    GET_UINT32_LE( c, input,  8 );
-    GET_UINT32_LE( d, input, 12 );
+    a = MBEDTLS_GET_UINT32_LE( input,  0 );
+    b = MBEDTLS_GET_UINT32_LE( input,  4 );
+    c = MBEDTLS_GET_UINT32_LE( input,  8 );
+    d = MBEDTLS_GET_UINT32_LE( input, 12 );
 
     i = 0;
     while( 1 )
@@ -582,10 +560,10 @@
     c ^= ctx->rk[i][2];
     d ^= ctx->rk[i][3];
 
-    PUT_UINT32_LE( a, output,  0 );
-    PUT_UINT32_LE( b, output,  4 );
-    PUT_UINT32_LE( c, output,  8 );
-    PUT_UINT32_LE( d, output, 12 );
+    MBEDTLS_PUT_UINT32_LE( a, output,  0 );
+    MBEDTLS_PUT_UINT32_LE( b, output,  4 );
+    MBEDTLS_PUT_UINT32_LE( c, output,  8 );
+    MBEDTLS_PUT_UINT32_LE( d, output, 12 );
 
     return( 0 );
 }
diff --git a/lib/libmbedtls/mbedtls/library/asn1write.c b/lib/libmbedtls/mbedtls/library/asn1write.c
index deb1a2f..afa26a6 100644
--- a/lib/libmbedtls/mbedtls/library/asn1write.c
+++ b/lib/libmbedtls/mbedtls/library/asn1write.c
@@ -60,8 +60,8 @@
         if( *p - start < 3 )
             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
 
-        *--(*p) = ( len       ) & 0xFF;
-        *--(*p) = ( len >>  8 ) & 0xFF;
+        *--(*p) = MBEDTLS_BYTE_0( len );
+        *--(*p) = MBEDTLS_BYTE_1( len );
         *--(*p) = 0x82;
         return( 3 );
     }
@@ -71,9 +71,9 @@
         if( *p - start < 4 )
             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
 
-        *--(*p) = ( len       ) & 0xFF;
-        *--(*p) = ( len >>  8 ) & 0xFF;
-        *--(*p) = ( len >> 16 ) & 0xFF;
+        *--(*p) = MBEDTLS_BYTE_0( len );
+        *--(*p) = MBEDTLS_BYTE_1( len );
+        *--(*p) = MBEDTLS_BYTE_2( len );
         *--(*p) = 0x83;
         return( 4 );
     }
@@ -85,10 +85,10 @@
         if( *p - start < 5 )
             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
 
-        *--(*p) = ( len       ) & 0xFF;
-        *--(*p) = ( len >>  8 ) & 0xFF;
-        *--(*p) = ( len >> 16 ) & 0xFF;
-        *--(*p) = ( len >> 24 ) & 0xFF;
+        *--(*p) = MBEDTLS_BYTE_0( len );
+        *--(*p) = MBEDTLS_BYTE_1( len );
+        *--(*p) = MBEDTLS_BYTE_2( len );
+        *--(*p) = MBEDTLS_BYTE_3( len );
         *--(*p) = 0x84;
         return( 5 );
     }
@@ -133,6 +133,11 @@
     //
     len = mbedtls_mpi_size( X );
 
+    /* DER represents 0 with a sign bit (0=nonnegative) and 7 value bits, not
+     * as 0 digits. We need to end up with 020100, not with 0200. */
+    if( len == 0 )
+        len = 1;
+
     if( *p < start || (size_t)( *p - start ) < len )
         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
 
@@ -472,7 +477,7 @@
         cur->val.len = val_len;
     }
 
-    if( val != NULL )
+    if( val != NULL && val_len != 0 )
         memcpy( cur->val.p, val, val_len );
 
     return( cur );
diff --git a/lib/libmbedtls/mbedtls/library/base64.c b/lib/libmbedtls/mbedtls/library/base64.c
index 1a05226..83daa0b 100644
--- a/lib/libmbedtls/mbedtls/library/base64.c
+++ b/lib/libmbedtls/mbedtls/library/base64.c
@@ -22,6 +22,7 @@
 #if defined(MBEDTLS_BASE64_C)
 
 #include "mbedtls/base64.h"
+#include "constant_time_internal.h"
 
 #include <stdint.h>
 
@@ -35,130 +36,9 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-static const unsigned char base64_enc_map[64] =
-{
-    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
-    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
-    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
-    '8', '9', '+', '/'
-};
-
-static const unsigned char base64_dec_map[128] =
-{
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
-    127, 127, 127,  62, 127, 127, 127,  63,  52,  53,
-     54,  55,  56,  57,  58,  59,  60,  61, 127, 127,
-    127,  64, 127, 127, 127,   0,   1,   2,   3,   4,
-      5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
-     15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
-     25, 127, 127, 127, 127, 127, 127,  26,  27,  28,
-     29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
-     39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
-     49,  50,  51, 127, 127, 127, 127, 127
-};
-
 #define BASE64_SIZE_T_MAX   ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
 
 /*
- * Constant flow conditional assignment to unsigned char
- */
-static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
-                                       unsigned char condition )
-{
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* Generate bitmask from condition, mask will either be 0xFF or 0 */
-    unsigned char mask = ( condition | -condition );
-    mask >>= 7;
-    mask = -mask;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
-}
-
-/*
- * Constant flow conditional assignment to uint_32
- */
-static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src,
-                                       uint32_t condition )
-{
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
-    uint32_t mask = ( condition | -condition );
-    mask >>= 31;
-    mask = -mask;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    *dest = ( src & mask ) | ( ( *dest ) & ~mask );
-}
-
-/*
- * Constant flow check for equality
- */
-static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
-{
-    size_t difference = in_a ^ in_b;
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    difference |= -difference;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    /* cope with the varying size of size_t per platform */
-    difference >>= ( sizeof( difference ) * 8 - 1 );
-
-    return (unsigned char) ( 1 ^ difference );
-}
-
-/*
- * Constant flow lookup into table.
- */
-static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
-                                                 const size_t table_size, const size_t table_index )
-{
-    size_t i;
-    unsigned char result = 0;
-
-    for( i = 0; i < table_size; ++i )
-    {
-        mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) );
-    }
-
-    return result;
-}
-
-/*
  * Encode a buffer into base64 format
  */
 int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
@@ -198,17 +78,12 @@
         C2 = *src++;
         C3 = *src++;
 
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( C1 >> 2 ) & 0x3F ) );
-
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( ( ( C1 &  3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
-
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
-
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( C3 & 0x3F ) );
+        *p++ = mbedtls_ct_base64_enc_char( ( C1 >> 2 ) & 0x3F );
+        *p++ = mbedtls_ct_base64_enc_char( ( ( ( C1 &  3 ) << 4 ) + ( C2 >> 4 ) )
+                                        & 0x3F );
+        *p++ = mbedtls_ct_base64_enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) )
+                                        & 0x3F );
+        *p++ = mbedtls_ct_base64_enc_char( C3 & 0x3F );
     }
 
     if( i < slen )
@@ -216,15 +91,12 @@
         C1 = *src++;
         C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
 
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( C1 >> 2 ) & 0x3F ) );
-
-        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                            ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
+        *p++ = mbedtls_ct_base64_enc_char( ( C1 >> 2 ) & 0x3F );
+        *p++ = mbedtls_ct_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) )
+                                        & 0x3F );
 
         if( ( i + 1 ) < slen )
-             *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
-                                                 ( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
+             *p++ = mbedtls_ct_base64_enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F );
         else *p++ = '=';
 
         *p++ = '=';
@@ -242,20 +114,23 @@
 int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
                    const unsigned char *src, size_t slen )
 {
-    size_t i, n;
-    uint32_t j, x;
+    size_t i; /* index in source */
+    size_t n; /* number of digits or trailing = in source */
+    uint32_t x; /* value accumulator */
+    unsigned accumulated_digits = 0;
+    unsigned equals = 0;
+    int spaces_present = 0;
     unsigned char *p;
-    unsigned char dec_map_lookup;
 
     /* First pass: check for validity and get output length */
-    for( i = n = j = 0; i < slen; i++ )
+    for( i = n = 0; i < slen; i++ )
     {
         /* Skip spaces before checking for EOL */
-        x = 0;
+        spaces_present = 0;
         while( i < slen && src[i] == ' ' )
         {
             ++i;
-            ++x;
+            spaces_present = 1;
         }
 
         /* Spaces at end of buffer are OK */
@@ -270,20 +145,24 @@
             continue;
 
         /* Space inside a line is an error */
-        if( x != 0 )
+        if( spaces_present )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
-        if( src[i] == '=' && ++j > 2 )
+        if( src[i] > 127 )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
-        dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
-
-        if( src[i] > 127 || dec_map_lookup == 127 )
-            return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
-
-        if( dec_map_lookup < 64 && j != 0 )
-            return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
-
+        if( src[i] == '=' )
+        {
+            if( ++equals > 2 )
+                return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+        }
+        else
+        {
+            if( equals != 0 )
+                return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+            if( mbedtls_ct_base64_dec_value( src[i] ) < 0 )
+                return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+        }
         n++;
     }
 
@@ -298,7 +177,7 @@
      *     n = ( ( n * 6 ) + 7 ) >> 3;
      */
     n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
-    n -= j;
+    n -= equals;
 
     if( dst == NULL || dlen < n )
     {
@@ -306,22 +185,24 @@
         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
     }
 
-   for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
-   {
+    equals = 0;
+    for( x = 0, p = dst; i > 0; i--, src++ )
+    {
         if( *src == '\r' || *src == '\n' || *src == ' ' )
             continue;
 
-        dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
+        x = x << 6;
+        if( *src == '=' )
+            ++equals;
+        else
+            x |= mbedtls_ct_base64_dec_value( *src );
 
-        mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
-        x  = ( x << 6 ) | ( dec_map_lookup & 0x3F );
-
-        if( ++n == 4 )
+        if( ++accumulated_digits == 4 )
         {
-            n = 0;
-            if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
-            if( j > 1 ) *p++ = (unsigned char)( x >>  8 );
-            if( j > 2 ) *p++ = (unsigned char)( x       );
+            accumulated_digits = 0;
+            *p++ = MBEDTLS_BYTE_2( x );
+            if( equals <= 1 ) *p++ = MBEDTLS_BYTE_1( x );
+            if( equals <= 0 ) *p++ = MBEDTLS_BYTE_0( x );
         }
     }
 
diff --git a/lib/libmbedtls/mbedtls/library/bignum.c b/lib/libmbedtls/mbedtls/library/bignum.c
index 31ef3ee..598a78c 100644
--- a/lib/libmbedtls/mbedtls/library/bignum.c
+++ b/lib/libmbedtls/mbedtls/library/bignum.c
@@ -41,7 +41,9 @@
 #include "mbedtls/bn_mul.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "constant_time_internal.h"
 
+#include <limits.h>
 #include <string.h>
 
 #if defined(MBEDTLS_PLATFORM_C)
@@ -315,162 +317,6 @@
     memcpy(  Y, &T, sizeof( mbedtls_mpi ) );
 }
 
-/**
- * Select between two sign values in constant-time.
- *
- * This is functionally equivalent to second ? a : b but uses only bit
- * operations in order to avoid branches.
- *
- * \param[in] a         The first sign; must be either +1 or -1.
- * \param[in] b         The second sign; must be either +1 or -1.
- * \param[in] second    Must be either 1 (return b) or 0 (return a).
- *
- * \return The selected sign value.
- */
-static int mpi_safe_cond_select_sign( int a, int b, unsigned char second )
-{
-    /* In order to avoid questions about what we can reasonnably assume about
-     * the representations of signed integers, move everything to unsigned
-     * by taking advantage of the fact that a and b are either +1 or -1. */
-    unsigned ua = a + 1;
-    unsigned ub = b + 1;
-
-    /* second was 0 or 1, mask is 0 or 2 as are ua and ub */
-    const unsigned mask = second << 1;
-
-    /* select ua or ub */
-    unsigned ur = ( ua & ~mask ) | ( ub & mask );
-
-    /* ur is now 0 or 2, convert back to -1 or +1 */
-    return( (int) ur - 1 );
-}
-
-/*
- * Conditionally assign dest = src, without leaking information
- * about whether the assignment was made or not.
- * dest and src must be arrays of limbs of size n.
- * assign must be 0 or 1.
- */
-static void mpi_safe_cond_assign( size_t n,
-                                  mbedtls_mpi_uint *dest,
-                                  const mbedtls_mpi_uint *src,
-                                  unsigned char assign )
-{
-    size_t i;
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
-    const mbedtls_mpi_uint mask = -assign;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    for( i = 0; i < n; i++ )
-        dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
-}
-
-/*
- * Conditionally assign X = Y, without leaking information
- * about whether the assignment was made or not.
- * (Leaking information about the respective sizes of X and Y is ok however.)
- */
-int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
-{
-    int ret = 0;
-    size_t i;
-    mbedtls_mpi_uint limb_mask;
-    MPI_VALIDATE_RET( X != NULL );
-    MPI_VALIDATE_RET( Y != NULL );
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* make sure assign is 0 or 1 in a time-constant manner */
-    assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1);
-    /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
-    limb_mask = -assign;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
-
-    X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign );
-
-    mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
-
-    for( i = Y->n; i < X->n; i++ )
-        X->p[i] &= ~limb_mask;
-
-cleanup:
-    return( ret );
-}
-
-/*
- * Conditionally swap X and Y, without leaking information
- * about whether the swap was made or not.
- * Here it is not ok to simply swap the pointers, which whould lead to
- * different memory access patterns when X and Y are used afterwards.
- */
-int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
-{
-    int ret, s;
-    size_t i;
-    mbedtls_mpi_uint limb_mask;
-    mbedtls_mpi_uint tmp;
-    MPI_VALIDATE_RET( X != NULL );
-    MPI_VALIDATE_RET( Y != NULL );
-
-    if( X == Y )
-        return( 0 );
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* make sure swap is 0 or 1 in a time-constant manner */
-    swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1);
-    /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
-    limb_mask = -swap;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
-
-    s = X->s;
-    X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
-    Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
-
-
-    for( i = 0; i < X->n; i++ )
-    {
-        tmp = X->p[i];
-        X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
-        Y->p[i] = ( Y->p[i] & ~limb_mask ) | (     tmp & limb_mask );
-    }
-
-cleanup:
-    return( ret );
-}
-
 /*
  * Set value from integer
  */
@@ -1293,107 +1139,6 @@
     return( 0 );
 }
 
-/** Decide if an integer is less than the other, without branches.
- *
- * \param x         First integer.
- * \param y         Second integer.
- *
- * \return          1 if \p x is less than \p y, 0 otherwise
- */
-static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
-        const mbedtls_mpi_uint y )
-{
-    mbedtls_mpi_uint ret;
-    mbedtls_mpi_uint cond;
-
-    /*
-     * Check if the most significant bits (MSB) of the operands are different.
-     */
-    cond = ( x ^ y );
-    /*
-     * If the MSB are the same then the difference x-y will be negative (and
-     * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
-     */
-    ret = ( x - y ) & ~cond;
-    /*
-     * If the MSB are different, then the operand with the MSB of 1 is the
-     * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
-     * the MSB of y is 0.)
-     */
-    ret |= y & cond;
-
-
-    ret = ret >> ( biL - 1 );
-
-    return (unsigned) ret;
-}
-
-/*
- * Compare signed values in constant time
- */
-int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
-        unsigned *ret )
-{
-    size_t i;
-    /* The value of any of these variables is either 0 or 1 at all times. */
-    unsigned cond, done, X_is_negative, Y_is_negative;
-
-    MPI_VALIDATE_RET( X != NULL );
-    MPI_VALIDATE_RET( Y != NULL );
-    MPI_VALIDATE_RET( ret != NULL );
-
-    if( X->n != Y->n )
-        return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
-
-    /*
-     * Set sign_N to 1 if N >= 0, 0 if N < 0.
-     * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
-     */
-    X_is_negative = ( X->s & 2 ) >> 1;
-    Y_is_negative = ( Y->s & 2 ) >> 1;
-
-    /*
-     * If the signs are different, then the positive operand is the bigger.
-     * That is if X is negative (X_is_negative == 1), then X < Y is true and it
-     * is false if X is positive (X_is_negative == 0).
-     */
-    cond = ( X_is_negative ^ Y_is_negative );
-    *ret = cond & X_is_negative;
-
-    /*
-     * This is a constant-time function. We might have the result, but we still
-     * need to go through the loop. Record if we have the result already.
-     */
-    done = cond;
-
-    for( i = X->n; i > 0; i-- )
-    {
-        /*
-         * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
-         * X and Y are negative.
-         *
-         * Again even if we can make a decision, we just mark the result and
-         * the fact that we are done and continue looping.
-         */
-        cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
-        *ret |= cond & ( 1 - done ) & X_is_negative;
-        done |= cond;
-
-        /*
-         * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
-         * X and Y are positive.
-         *
-         * Again even if we can make a decision, we just mark the result and
-         * the fact that we are done and continue looping.
-         */
-        cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
-        *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
-        done |= cond;
-    }
-
-    return( 0 );
-}
-
 /*
  * Compare signed values
  */
@@ -1634,17 +1379,17 @@
  */
 int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
 {
-    mbedtls_mpi _B;
+    mbedtls_mpi B;
     mbedtls_mpi_uint p[1];
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
-    _B.s = ( b < 0 ) ? -1 : 1;
-    _B.n = 1;
-    _B.p = p;
+    B.s = ( b < 0 ) ? -1 : 1;
+    B.n = 1;
+    B.p = p;
 
-    return( mbedtls_mpi_add_mpi( X, A, &_B ) );
+    return( mbedtls_mpi_add_mpi( X, A, &B ) );
 }
 
 /*
@@ -1652,17 +1397,17 @@
  */
 int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
 {
-    mbedtls_mpi _B;
+    mbedtls_mpi B;
     mbedtls_mpi_uint p[1];
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
-    _B.s = ( b < 0 ) ? -1 : 1;
-    _B.n = 1;
-    _B.p = p;
+    B.s = ( b < 0 ) ? -1 : 1;
+    B.n = 1;
+    B.p = p;
 
-    return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
+    return( mbedtls_mpi_sub_mpi( X, A, &B ) );
 }
 
 /** Helper for mbedtls_mpi multiplication.
@@ -2074,16 +1819,16 @@
                          const mbedtls_mpi *A,
                          mbedtls_mpi_sint b )
 {
-    mbedtls_mpi _B;
+    mbedtls_mpi B;
     mbedtls_mpi_uint p[1];
     MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
-    _B.s = ( b < 0 ) ? -1 : 1;
-    _B.n = 1;
-    _B.p = p;
+    B.s = ( b < 0 ) ? -1 : 1;
+    B.n = 1;
+    B.p = p;
 
-    return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
+    return( mbedtls_mpi_div_mpi( Q, R, A, &B ) );
 }
 
 /*
@@ -2131,7 +1876,7 @@
     /*
      * handle trivial cases
      */
-    if( b == 1 )
+    if( b == 1 || A->n == 0 )
     {
         *r = 0;
         return( 0 );
@@ -2259,7 +2004,7 @@
      * so d[n] == 1 and we want to set A to the result of the subtraction
      * which is d - (2^biL)^n, i.e. the n least significant limbs of d.
      * This exactly corresponds to a conditional assignment. */
-    mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] );
+    mbedtls_ct_mpi_uint_cond_assign( n, A->p, d, (unsigned char) d[n] );
 }
 
 void mbedtls_mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
@@ -2291,42 +2036,6 @@
     mpi_montred( A, N, mm, T );
 }
 
-/*
- * Constant-flow boolean "equal" comparison:
- * return x == y
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations - it can be used in conjunction with
- * mbedtls_ssl_cf_mask_from_bit().
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
-{
-    /* diff = 0 if x == y, non-zero otherwise */
-    const size_t diff = x ^ y;
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* diff_msb's most significant bit is equal to x != y */
-    const size_t diff_msb = ( diff | (size_t) -diff );
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    /* diff1 = (x != y) ? 1 : 0 */
-    const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
-
-    return( 1 ^ diff1 );
-}
-
 /**
  * Select an MPI from a table without leaking the index.
  *
@@ -2349,7 +2058,7 @@
     for( size_t i = 0; i < T_size; i++ )
     {
         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
-                        (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
+                        (unsigned char) mbedtls_ct_size_bool_eq( i, idx ) ) );
     }
 
 cleanup:
@@ -2361,7 +2070,7 @@
  */
 int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
                          const mbedtls_mpi *E, const mbedtls_mpi *N,
-                         mbedtls_mpi *_RR )
+                         mbedtls_mpi *prec_RR )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t wbits, wsize, one = 1;
@@ -2430,17 +2139,17 @@
     /*
      * If 1st call, pre-compute R^2 mod N
      */
-    if( _RR == NULL || _RR->p == NULL )
+    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 ) );
 
-        if( _RR != NULL )
-            memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
+        if( prec_RR != NULL )
+            memcpy( prec_RR, &RR, sizeof( mbedtls_mpi ) );
     }
     else
-        memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
+        memcpy( &RR, prec_RR, sizeof( mbedtls_mpi ) );
 
     W = mempool_alloc( mbedtls_mpi_mempool,
                        sizeof( mbedtls_mpi ) * array_size_W );
@@ -2600,7 +2309,7 @@
     mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
     mbedtls_mpi_free( &WW );
 
-    if( _RR == NULL || _RR->p == NULL )
+    if( prec_RR == NULL || prec_RR->p == NULL )
         mbedtls_mpi_free( &RR );
 
     return( ret );
@@ -2685,7 +2394,7 @@
          * TA-TB is even so the division by 2 has an integer result.
          * Invariant (I) is preserved since any odd divisor of both TA and TB
          * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
-         * also divides TB, and any odd divisior of both TB and |TA-TB|/2 also
+         * also divides TB, and any odd divisor of both TB and |TA-TB|/2 also
          * divides TA.
          */
         if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
diff --git a/lib/libmbedtls/mbedtls/library/blowfish.c b/lib/libmbedtls/mbedtls/library/blowfish.c
index 76da448..621e9f7 100644
--- a/lib/libmbedtls/mbedtls/library/blowfish.c
+++ b/lib/libmbedtls/mbedtls/library/blowfish.c
@@ -40,29 +40,6 @@
 #define BLOWFISH_VALIDATE( cond )                                           \
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-}
-#endif
-
 static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = {
         0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
         0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
@@ -79,13 +56,13 @@
    unsigned short a, b, c, d;
    uint32_t  y;
 
-   d = (unsigned short)(x & 0xFF);
+   d = MBEDTLS_BYTE_0( x );
    x >>= 8;
-   c = (unsigned short)(x & 0xFF);
+   c = MBEDTLS_BYTE_0( x );
    x >>= 8;
-   b = (unsigned short)(x & 0xFF);
+   b = MBEDTLS_BYTE_0( x );
    x >>= 8;
-   a = (unsigned short)(x & 0xFF);
+   a = MBEDTLS_BYTE_0( x );
    y = ctx->S[0][a] + ctx->S[1][b];
    y = y ^ ctx->S[2][c];
    y = y + ctx->S[3][d];
@@ -242,8 +219,8 @@
     BLOWFISH_VALIDATE_RET( input  != NULL );
     BLOWFISH_VALIDATE_RET( output != NULL );
 
-    GET_UINT32_BE( X0, input,  0 );
-    GET_UINT32_BE( X1, input,  4 );
+    X0 = MBEDTLS_GET_UINT32_BE( input,  0 );
+    X1 = MBEDTLS_GET_UINT32_BE( input,  4 );
 
     if( mode == MBEDTLS_BLOWFISH_DECRYPT )
     {
@@ -254,8 +231,8 @@
         blowfish_enc( ctx, &X0, &X1 );
     }
 
-    PUT_UINT32_BE( X0, output,  0 );
-    PUT_UINT32_BE( X1, output,  4 );
+    MBEDTLS_PUT_UINT32_BE( X0, output,  0 );
+    MBEDTLS_PUT_UINT32_BE( X1, output,  4 );
 
     return( 0 );
 }
diff --git a/lib/libmbedtls/mbedtls/library/camellia.c b/lib/libmbedtls/mbedtls/library/camellia.c
index f7e0136..29d730a 100644
--- a/lib/libmbedtls/mbedtls/library/camellia.c
+++ b/lib/libmbedtls/mbedtls/library/camellia.c
@@ -49,29 +49,6 @@
 #define CAMELLIA_VALIDATE( cond )                                           \
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-}
-#endif
-
 static const unsigned char SIGMA_CHARS[6][8] =
 {
     { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
@@ -301,14 +278,14 @@
     I0 = x[0] ^ k[0];
     I1 = x[1] ^ k[1];
 
-    I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) |
-         ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) |
-         ((uint32_t) SBOX3((I0 >>  8) & 0xFF) <<  8) |
-         ((uint32_t) SBOX4((I0      ) & 0xFF)      );
-    I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) |
-         ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) |
-         ((uint32_t) SBOX4((I1 >>  8) & 0xFF) <<  8) |
-         ((uint32_t) SBOX1((I1      ) & 0xFF)      );
+    I0 = ((uint32_t) SBOX1( MBEDTLS_BYTE_3( I0 )) << 24) |
+         ((uint32_t) SBOX2( MBEDTLS_BYTE_2( I0 )) << 16) |
+         ((uint32_t) SBOX3( MBEDTLS_BYTE_1( I0 )) <<  8) |
+         ((uint32_t) SBOX4( MBEDTLS_BYTE_0( I0 ))      );
+    I1 = ((uint32_t) SBOX2( MBEDTLS_BYTE_3( I1 )) << 24) |
+         ((uint32_t) SBOX3( MBEDTLS_BYTE_2( I1 )) << 16) |
+         ((uint32_t) SBOX4( MBEDTLS_BYTE_1( I1 )) <<  8) |
+         ((uint32_t) SBOX1( MBEDTLS_BYTE_0( I1 ))      );
 
     I0 ^= (I1 << 8) | (I1 >> 24);
     I1 ^= (I0 << 16) | (I0 >> 16);
@@ -376,8 +353,8 @@
      * Prepare SIGMA values
      */
     for( i = 0; i < 6; i++ ) {
-        GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 );
-        GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 );
+        SIGMA[i][0] = MBEDTLS_GET_UINT32_BE( SIGMA_CHARS[i], 0 );
+        SIGMA[i][1] = MBEDTLS_GET_UINT32_BE( SIGMA_CHARS[i], 4 );
     }
 
     /*
@@ -388,7 +365,7 @@
 
     /* Store KL, KR */
     for( i = 0; i < 8; i++ )
-        GET_UINT32_BE( KC[i], t, i * 4 );
+        KC[i] = MBEDTLS_GET_UINT32_BE( t, i * 4 );
 
     /* Generate KA */
     for( i = 0; i < 4; ++i )
@@ -514,10 +491,10 @@
     NR = ctx->nr;
     RK = ctx->rk;
 
-    GET_UINT32_BE( X[0], input,  0 );
-    GET_UINT32_BE( X[1], input,  4 );
-    GET_UINT32_BE( X[2], input,  8 );
-    GET_UINT32_BE( X[3], input, 12 );
+    X[0] = MBEDTLS_GET_UINT32_BE( input,  0 );
+    X[1] = MBEDTLS_GET_UINT32_BE( input,  4 );
+    X[2] = MBEDTLS_GET_UINT32_BE( input,  8 );
+    X[3] = MBEDTLS_GET_UINT32_BE( input, 12 );
 
     X[0] ^= *RK++;
     X[1] ^= *RK++;
@@ -552,10 +529,10 @@
     X[0] ^= *RK++;
     X[1] ^= *RK++;
 
-    PUT_UINT32_BE( X[2], output,  0 );
-    PUT_UINT32_BE( X[3], output,  4 );
-    PUT_UINT32_BE( X[0], output,  8 );
-    PUT_UINT32_BE( X[1], output, 12 );
+    MBEDTLS_PUT_UINT32_BE( X[2], output,  0 );
+    MBEDTLS_PUT_UINT32_BE( X[3], output,  4 );
+    MBEDTLS_PUT_UINT32_BE( X[0], output,  8 );
+    MBEDTLS_PUT_UINT32_BE( X[1], output, 12 );
 
     return( 0 );
 }
diff --git a/lib/libmbedtls/mbedtls/library/ccm.c b/lib/libmbedtls/mbedtls/library/ccm.c
index 424ee77..a21a37f 100644
--- a/lib/libmbedtls/mbedtls/library/ccm.c
+++ b/lib/libmbedtls/mbedtls/library/ccm.c
@@ -200,7 +200,7 @@
     memcpy( b + 1, iv, iv_len );
 
     for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
-        b[15-i] = (unsigned char)( len_left & 0xFF );
+        b[15-i] = MBEDTLS_BYTE_0( len_left );
 
     if( len_left > 0 )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -221,8 +221,7 @@
         src = add;
 
         memset( b, 0, 16 );
-        b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
-        b[1] = (unsigned char)( ( add_len      ) & 0xFF );
+        MBEDTLS_PUT_UINT16_BE( add_len, b, 0 );
 
         use_len = len_left < 16 - 2 ? len_left : 16 - 2;
         memcpy( b + 2, src, use_len );
diff --git a/lib/libmbedtls/mbedtls/library/chacha20.c b/lib/libmbedtls/mbedtls/library/chacha20.c
index 78467d3..658f046 100644
--- a/lib/libmbedtls/mbedtls/library/chacha20.c
+++ b/lib/libmbedtls/mbedtls/library/chacha20.c
@@ -54,13 +54,6 @@
 #define CHACHA20_VALIDATE( cond )                                           \
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
-#define BYTES_TO_U32_LE( data, offset )                           \
-    ( (uint32_t) (data)[offset]                                   \
-      | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 )     \
-      | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 )    \
-      | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 )    \
-    )
-
 #define ROTL32( value, amount ) \
     ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
 
@@ -171,10 +164,7 @@
     {
         size_t offset = i * 4U;
 
-        keystream[offset     ] = (unsigned char)( working_state[i]       );
-        keystream[offset + 1U] = (unsigned char)( working_state[i] >>  8 );
-        keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
-        keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
+        MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset);
     }
 
     mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
@@ -212,14 +202,14 @@
     ctx->state[3] = 0x6b206574;
 
     /* Set key */
-    ctx->state[4]  = BYTES_TO_U32_LE( key, 0 );
-    ctx->state[5]  = BYTES_TO_U32_LE( key, 4 );
-    ctx->state[6]  = BYTES_TO_U32_LE( key, 8 );
-    ctx->state[7]  = BYTES_TO_U32_LE( key, 12 );
-    ctx->state[8]  = BYTES_TO_U32_LE( key, 16 );
-    ctx->state[9]  = BYTES_TO_U32_LE( key, 20 );
-    ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
-    ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
+    ctx->state[4]  = MBEDTLS_GET_UINT32_LE( key, 0 );
+    ctx->state[5]  = MBEDTLS_GET_UINT32_LE( key, 4 );
+    ctx->state[6]  = MBEDTLS_GET_UINT32_LE( key, 8 );
+    ctx->state[7]  = MBEDTLS_GET_UINT32_LE( key, 12 );
+    ctx->state[8]  = MBEDTLS_GET_UINT32_LE( key, 16 );
+    ctx->state[9]  = MBEDTLS_GET_UINT32_LE( key, 20 );
+    ctx->state[10] = MBEDTLS_GET_UINT32_LE( key, 24 );
+    ctx->state[11] = MBEDTLS_GET_UINT32_LE( key, 28 );
 
     return( 0 );
 }
@@ -235,9 +225,9 @@
     ctx->state[12] = counter;
 
     /* Nonce */
-    ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
-    ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
-    ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
+    ctx->state[13] = MBEDTLS_GET_UINT32_LE( nonce, 0 );
+    ctx->state[14] = MBEDTLS_GET_UINT32_LE( nonce, 4 );
+    ctx->state[15] = MBEDTLS_GET_UINT32_LE( nonce, 8 );
 
     mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
 
diff --git a/lib/libmbedtls/mbedtls/library/chachapoly.c b/lib/libmbedtls/mbedtls/library/chachapoly.c
index 77d5477..dc75b20 100644
--- a/lib/libmbedtls/mbedtls/library/chachapoly.c
+++ b/lib/libmbedtls/mbedtls/library/chachapoly.c
@@ -263,22 +263,8 @@
     /* The lengths of the AAD and ciphertext are processed by
      * Poly1305 as the final 128-bit block, encoded as little-endian integers.
      */
-    len_block[ 0] = (unsigned char)( ctx->aad_len       );
-    len_block[ 1] = (unsigned char)( ctx->aad_len >>  8 );
-    len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 );
-    len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 );
-    len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 );
-    len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 );
-    len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 );
-    len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 );
-    len_block[ 8] = (unsigned char)( ctx->ciphertext_len       );
-    len_block[ 9] = (unsigned char)( ctx->ciphertext_len >>  8 );
-    len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 );
-    len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 );
-    len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 );
-    len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 );
-    len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 );
-    len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 );
+    MBEDTLS_PUT_UINT64_LE(ctx->aad_len, len_block, 0);
+    MBEDTLS_PUT_UINT64_LE(ctx->ciphertext_len, len_block, 8);
 
     ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
     if( ret != 0 )
diff --git a/lib/libmbedtls/mbedtls/library/cipher.c b/lib/libmbedtls/mbedtls/library/cipher.c
index 789185c..31147df 100644
--- a/lib/libmbedtls/mbedtls/library/cipher.c
+++ b/lib/libmbedtls/mbedtls/library/cipher.c
@@ -29,6 +29,7 @@
 #include "mbedtls/cipher_internal.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -74,27 +75,6 @@
 #define CIPHER_VALIDATE( cond )        \
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-/* Compare the contents of two buffers in constant time.
- * Returns 0 if the contents are bitwise identical, otherwise returns
- * a non-zero value.
- * This is currently only used by GCM and ChaCha20+Poly1305.
- */
-static int mbedtls_constant_time_memcmp( const void *v1, const void *v2,
-                                         size_t len )
-{
-    const unsigned char *p1 = (const unsigned char*) v1;
-    const unsigned char *p2 = (const unsigned char*) v2;
-    size_t i;
-    unsigned char diff;
-
-    for( diff = 0, i = 0; i < len; i++ )
-        diff |= p1[i] ^ p2[i];
-
-    return( (int)diff );
-}
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
 static int supported_init = 0;
 
 const int *mbedtls_cipher_list( void )
@@ -445,6 +425,12 @@
 #if defined(MBEDTLS_CHACHA20_C)
     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
     {
+        /* Even though the actual_iv_size is overwritten with a correct value
+         * of 12 from the cipher info, return an error to indicate that
+         * the input iv_len is wrong. */
+        if( iv_len != 12 )
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
         if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
                                            iv,
                                            0U ) ) /* Initial counter value */
@@ -452,6 +438,11 @@
             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
         }
     }
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
+         iv_len != 12 )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#endif
 #endif
 
     if ( actual_iv_size != 0 )
@@ -1184,6 +1175,12 @@
     }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
+    /* Status to return on a non-authenticated algorithm. It would make sense
+     * to return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT or perhaps
+     * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, but at the time I write this our
+     * unit tests assume 0. */
+    ret = 0;
+
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
@@ -1198,10 +1195,11 @@
         }
 
         /* Check the tag in "constant-time" */
-        if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
-            return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
-
-        return( 0 );
+        if( mbedtls_ct_memcmp( tag, check_tag, tag_len ) != 0 )
+        {
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+            goto exit;
+        }
     }
 #endif /* MBEDTLS_GCM_C */
 
@@ -1220,14 +1218,17 @@
         }
 
         /* Check the tag in "constant-time" */
-        if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
-            return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
-
-        return( 0 );
+        if( mbedtls_ct_memcmp( tag, check_tag, tag_len ) != 0 )
+        {
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+            goto exit;
+        }
     }
 #endif /* MBEDTLS_CHACHAPOLY_C */
 
-    return( 0 );
+exit:
+    mbedtls_platform_zeroize( check_tag, tag_len );
+    return( ret );
 }
 #endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
 
@@ -1285,9 +1286,12 @@
         if( status != PSA_SUCCESS )
             return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
 
-        status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
-        if( status != PSA_SUCCESS )
-            return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+        if( ctx->cipher_info->mode != MBEDTLS_MODE_ECB )
+        {
+            status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
+            if( status != PSA_SUCCESS )
+                return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+        }
 
         status = psa_cipher_update( &cipher_op,
                                     input, ilen,
diff --git a/lib/libmbedtls/mbedtls/library/common.h b/lib/libmbedtls/mbedtls/library/common.h
index 5845766..c064724 100644
--- a/lib/libmbedtls/mbedtls/library/common.h
+++ b/lib/libmbedtls/mbedtls/library/common.h
@@ -29,6 +29,8 @@
 #include "mbedtls/config.h"
 #endif
 
+#include <stdint.h>
+
 /** Helper to define a function as static except when building invasive tests.
  *
  * If a function is only used inside its own source file and should be
@@ -50,4 +52,254 @@
 #define MBEDTLS_STATIC_TESTABLE static
 #endif
 
+/** Byte Reading Macros
+ *
+ * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
+ * byte from x, where byte 0 is the least significant byte.
+ */
+#define MBEDTLS_BYTE_0( x ) ( (uint8_t) (   ( x )         & 0xff ) )
+#define MBEDTLS_BYTE_1( x ) ( (uint8_t) ( ( ( x ) >> 8  ) & 0xff ) )
+#define MBEDTLS_BYTE_2( x ) ( (uint8_t) ( ( ( x ) >> 16 ) & 0xff ) )
+#define MBEDTLS_BYTE_3( x ) ( (uint8_t) ( ( ( x ) >> 24 ) & 0xff ) )
+#define MBEDTLS_BYTE_4( x ) ( (uint8_t) ( ( ( x ) >> 32 ) & 0xff ) )
+#define MBEDTLS_BYTE_5( x ) ( (uint8_t) ( ( ( x ) >> 40 ) & 0xff ) )
+#define MBEDTLS_BYTE_6( x ) ( (uint8_t) ( ( ( x ) >> 48 ) & 0xff ) )
+#define MBEDTLS_BYTE_7( x ) ( (uint8_t) ( ( ( x ) >> 56 ) & 0xff ) )
+
+/**
+ * Get the unsigned 32 bits integer corresponding to four bytes in
+ * big-endian order (MSB first).
+ *
+ * \param   data    Base address of the memory to get the four bytes from.
+ * \param   offset  Offset from \p base of the first and most significant
+ *                  byte of the four bytes to build the 32 bits unsigned
+ *                  integer from.
+ */
+#ifndef MBEDTLS_GET_UINT32_BE
+#define MBEDTLS_GET_UINT32_BE( data , offset )                  \
+    (                                                           \
+          ( (uint32_t) ( data )[( offset )    ] << 24 )         \
+        | ( (uint32_t) ( data )[( offset ) + 1] << 16 )         \
+        | ( (uint32_t) ( data )[( offset ) + 2] <<  8 )         \
+        | ( (uint32_t) ( data )[( offset ) + 3]       )         \
+    )
+#endif
+
+/**
+ * Put in memory a 32 bits unsigned integer in big-endian order.
+ *
+ * \param   n       32 bits unsigned integer to put in memory.
+ * \param   data    Base address of the memory where to put the 32
+ *                  bits unsigned integer in.
+ * \param   offset  Offset from \p base where to put the most significant
+ *                  byte of the 32 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT32_BE
+#define MBEDTLS_PUT_UINT32_BE( n, data, offset )                \
+{                                                               \
+    ( data )[( offset )    ] = MBEDTLS_BYTE_3( n );             \
+    ( data )[( offset ) + 1] = MBEDTLS_BYTE_2( n );             \
+    ( data )[( offset ) + 2] = MBEDTLS_BYTE_1( n );             \
+    ( data )[( offset ) + 3] = MBEDTLS_BYTE_0( n );             \
+}
+#endif
+
+/**
+ * Get the unsigned 32 bits integer corresponding to four bytes in
+ * little-endian order (LSB first).
+ *
+ * \param   data    Base address of the memory to get the four bytes from.
+ * \param   offset  Offset from \p base of the first and least significant
+ *                  byte of the four bytes to build the 32 bits unsigned
+ *                  integer from.
+ */
+#ifndef MBEDTLS_GET_UINT32_LE
+#define MBEDTLS_GET_UINT32_LE( data, offset )                   \
+    (                                                           \
+          ( (uint32_t) ( data )[( offset )    ]       )         \
+        | ( (uint32_t) ( data )[( offset ) + 1] <<  8 )         \
+        | ( (uint32_t) ( data )[( offset ) + 2] << 16 )         \
+        | ( (uint32_t) ( data )[( offset ) + 3] << 24 )         \
+    )
+#endif
+
+/**
+ * Put in memory a 32 bits unsigned integer in little-endian order.
+ *
+ * \param   n       32 bits unsigned integer to put in memory.
+ * \param   data    Base address of the memory where to put the 32
+ *                  bits unsigned integer in.
+ * \param   offset  Offset from \p base where to put the least significant
+ *                  byte of the 32 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT32_LE
+#define MBEDTLS_PUT_UINT32_LE( n, data, offset )                \
+{                                                               \
+    ( data )[( offset )    ] = MBEDTLS_BYTE_0( n );             \
+    ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n );             \
+    ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n );             \
+    ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n );             \
+}
+#endif
+
+/**
+ * Get the unsigned 16 bits integer corresponding to two bytes in
+ * little-endian order (LSB first).
+ *
+ * \param   data    Base address of the memory to get the two bytes from.
+ * \param   offset  Offset from \p base of the first and least significant
+ *                  byte of the two bytes to build the 16 bits unsigned
+ *                  integer from.
+ */
+#ifndef MBEDTLS_GET_UINT16_LE
+#define MBEDTLS_GET_UINT16_LE( data, offset )                   \
+    (                                                           \
+          ( (uint16_t) ( data )[( offset )    ]       )         \
+        | ( (uint16_t) ( data )[( offset ) + 1] <<  8 )         \
+    )
+#endif
+
+/**
+ * Put in memory a 16 bits unsigned integer in little-endian order.
+ *
+ * \param   n       16 bits unsigned integer to put in memory.
+ * \param   data    Base address of the memory where to put the 16
+ *                  bits unsigned integer in.
+ * \param   offset  Offset from \p base where to put the least significant
+ *                  byte of the 16 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT16_LE
+#define MBEDTLS_PUT_UINT16_LE( n, data, offset )                \
+{                                                               \
+    ( data )[( offset )    ] = MBEDTLS_BYTE_0( n );             \
+    ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n );             \
+}
+#endif
+
+/**
+ * Get the unsigned 16 bits integer corresponding to two bytes in
+ * big-endian order (MSB first).
+ *
+ * \param   data    Base address of the memory to get the two bytes from.
+ * \param   offset  Offset from \p base of the first and most significant
+ *                  byte of the two bytes to build the 16 bits unsigned
+ *                  integer from.
+ */
+#ifndef MBEDTLS_GET_UINT16_BE
+#define MBEDTLS_GET_UINT16_BE( data, offset )                   \
+    (                                                           \
+          ( (uint16_t) ( data )[( offset )    ] << 8 )          \
+        | ( (uint16_t) ( data )[( offset ) + 1]      )          \
+    )
+#endif
+
+/**
+ * Put in memory a 16 bits unsigned integer in big-endian order.
+ *
+ * \param   n       16 bits unsigned integer to put in memory.
+ * \param   data    Base address of the memory where to put the 16
+ *                  bits unsigned integer in.
+ * \param   offset  Offset from \p base where to put the most significant
+ *                  byte of the 16 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT16_BE
+#define MBEDTLS_PUT_UINT16_BE( n, data, offset )                \
+{                                                               \
+    ( data )[( offset )    ] = MBEDTLS_BYTE_1( n );             \
+    ( data )[( offset ) + 1] = MBEDTLS_BYTE_0( n );             \
+}
+#endif
+
+/**
+ * Get the unsigned 64 bits integer corresponding to eight bytes in
+ * big-endian order (MSB first).
+ *
+ * \param   data    Base address of the memory to get the eight bytes from.
+ * \param   offset  Offset from \p base of the first and most significant
+ *                  byte of the eight bytes to build the 64 bits unsigned
+ *                  integer from.
+ */
+#ifndef MBEDTLS_GET_UINT64_BE
+#define MBEDTLS_GET_UINT64_BE( data, offset )                   \
+    (                                                           \
+          ( (uint64_t) ( data )[( offset )    ] << 56 )         \
+        | ( (uint64_t) ( data )[( offset ) + 1] << 48 )         \
+        | ( (uint64_t) ( data )[( offset ) + 2] << 40 )         \
+        | ( (uint64_t) ( data )[( offset ) + 3] << 32 )         \
+        | ( (uint64_t) ( data )[( offset ) + 4] << 24 )         \
+        | ( (uint64_t) ( data )[( offset ) + 5] << 16 )         \
+        | ( (uint64_t) ( data )[( offset ) + 6] <<  8 )         \
+        | ( (uint64_t) ( data )[( offset ) + 7]       )         \
+    )
+#endif
+
+/**
+ * Put in memory a 64 bits unsigned integer in big-endian order.
+ *
+ * \param   n       64 bits unsigned integer to put in memory.
+ * \param   data    Base address of the memory where to put the 64
+ *                  bits unsigned integer in.
+ * \param   offset  Offset from \p base where to put the most significant
+ *                  byte of the 64 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT64_BE
+#define MBEDTLS_PUT_UINT64_BE( n, data, offset )                \
+{                                                               \
+    ( data )[( offset )    ] = MBEDTLS_BYTE_7( n );             \
+    ( data )[( offset ) + 1] = MBEDTLS_BYTE_6( n );             \
+    ( data )[( offset ) + 2] = MBEDTLS_BYTE_5( n );             \
+    ( data )[( offset ) + 3] = MBEDTLS_BYTE_4( n );             \
+    ( data )[( offset ) + 4] = MBEDTLS_BYTE_3( n );             \
+    ( data )[( offset ) + 5] = MBEDTLS_BYTE_2( n );             \
+    ( data )[( offset ) + 6] = MBEDTLS_BYTE_1( n );             \
+    ( data )[( offset ) + 7] = MBEDTLS_BYTE_0( n );             \
+}
+#endif
+
+/**
+ * Get the unsigned 64 bits integer corresponding to eight bytes in
+ * little-endian order (LSB first).
+ *
+ * \param   data    Base address of the memory to get the eight bytes from.
+ * \param   offset  Offset from \p base of the first and least significant
+ *                  byte of the eight bytes to build the 64 bits unsigned
+ *                  integer from.
+ */
+#ifndef MBEDTLS_GET_UINT64_LE
+#define MBEDTLS_GET_UINT64_LE( data, offset )                   \
+    (                                                           \
+          ( (uint64_t) ( data )[( offset ) + 7] << 56 )         \
+        | ( (uint64_t) ( data )[( offset ) + 6] << 48 )         \
+        | ( (uint64_t) ( data )[( offset ) + 5] << 40 )         \
+        | ( (uint64_t) ( data )[( offset ) + 4] << 32 )         \
+        | ( (uint64_t) ( data )[( offset ) + 3] << 24 )         \
+        | ( (uint64_t) ( data )[( offset ) + 2] << 16 )         \
+        | ( (uint64_t) ( data )[( offset ) + 1] <<  8 )         \
+        | ( (uint64_t) ( data )[( offset )    ]       )         \
+    )
+#endif
+
+/**
+ * Put in memory a 64 bits unsigned integer in little-endian order.
+ *
+ * \param   n       64 bits unsigned integer to put in memory.
+ * \param   data    Base address of the memory where to put the 64
+ *                  bits unsigned integer in.
+ * \param   offset  Offset from \p base where to put the least significant
+ *                  byte of the 64 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT64_LE
+#define MBEDTLS_PUT_UINT64_LE( n, data, offset )                \
+{                                                               \
+    ( data )[( offset )    ] = MBEDTLS_BYTE_0( n );             \
+    ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n );             \
+    ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n );             \
+    ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n );             \
+    ( data )[( offset ) + 4] = MBEDTLS_BYTE_4( n );             \
+    ( data )[( offset ) + 5] = MBEDTLS_BYTE_5( n );             \
+    ( data )[( offset ) + 6] = MBEDTLS_BYTE_6( n );             \
+    ( data )[( offset ) + 7] = MBEDTLS_BYTE_7( n );             \
+}
+#endif
+
 #endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/lib/libmbedtls/mbedtls/library/constant_time.c b/lib/libmbedtls/mbedtls/library/constant_time.c
new file mode 100644
index 0000000..e276d23
--- /dev/null
+++ b/lib/libmbedtls/mbedtls/library/constant_time.c
@@ -0,0 +1,832 @@
+/**
+ *  Constant-time functions
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+ /*
+ * The following functions are implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+
+#include "common.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "mbedtls/ssl_internal.h"
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+
+#if defined(MBEDTLS_BASE64_C)
+#include "constant_time_invasive.h"
+#endif
+
+#include <string.h>
+
+int mbedtls_ct_memcmp( const void *a,
+                       const void *b,
+                       size_t n )
+{
+    size_t i;
+    volatile const unsigned char *A = (volatile const unsigned char *) a;
+    volatile const unsigned char *B = (volatile const unsigned char *) b;
+    volatile unsigned char diff = 0;
+
+    for( i = 0; i < n; i++ )
+    {
+        /* Read volatile data in order before computing diff.
+         * This avoids IAR compiler warning:
+         * 'the order of volatile accesses is undefined ..' */
+        unsigned char x = A[i], y = B[i];
+        diff |= x ^ y;
+    }
+
+    return( (int)diff );
+}
+
+unsigned mbedtls_ct_uint_mask( unsigned value )
+{
+    /* MSVC has a warning about unary minus on unsigned, but this is
+     * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+size_t mbedtls_ct_size_mask( size_t value )
+{
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask( mbedtls_mpi_uint value )
+{
+    /* MSVC has a warning about unary minus on unsigned, but this is
+     * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Constant-flow mask generation for "less than" comparison:
+ * - if \p x < \p y, return all-bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      All-bits-one if \p x is less than \p y, otherwise zero.
+ */
+static size_t mbedtls_ct_size_mask_lt( size_t x,
+                                       size_t y )
+{
+    /* This has the most significant bit set if and only if x < y */
+    const size_t sub = x - y;
+
+    /* sub1 = (x < y) ? 1 : 0 */
+    const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 );
+
+    /* mask = (x < y) ? 0xff... : 0x00... */
+    const size_t mask = mbedtls_ct_size_mask( sub1 );
+
+    return( mask );
+}
+
+size_t mbedtls_ct_size_mask_ge( size_t x,
+                                size_t y )
+{
+    return( ~mbedtls_ct_size_mask_lt( x, y ) );
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BASE64_C)
+
+/* Return 0xff if low <= c <= high, 0 otherwise.
+ *
+ * Constant flow with respect to c.
+ */
+MBEDTLS_STATIC_TESTABLE
+unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low,
+                                              unsigned char high,
+                                              unsigned char c )
+{
+    /* low_mask is: 0 if low <= c, 0x...ff if low > c */
+    unsigned low_mask = ( (unsigned) c - low ) >> 8;
+    /* high_mask is: 0 if c <= high, 0x...ff if c > high */
+    unsigned high_mask = ( (unsigned) high - c ) >> 8;
+    return( ~( low_mask | high_mask ) & 0xff );
+}
+
+#endif /* MBEDTLS_BASE64_C */
+
+unsigned mbedtls_ct_size_bool_eq( size_t x,
+                                  size_t y )
+{
+    /* diff = 0 if x == y, non-zero otherwise */
+    const size_t diff = x ^ y;
+
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+
+    /* diff_msb's most significant bit is equal to x != y */
+    const size_t diff_msb = ( diff | (size_t) -diff );
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    /* diff1 = (x != y) ? 1 : 0 */
+    const unsigned diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
+
+    return( 1 ^ diff1 );
+}
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** Constant-flow "greater than" comparison:
+ * return x > y
+ *
+ * This is equivalent to \p x > \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      1 if \p x greater than \p y, otherwise 0.
+ */
+static unsigned mbedtls_ct_size_gt( size_t x,
+                                    size_t y )
+{
+    /* Return the sign bit (1 for negative) of (y - x). */
+    return( ( y - x ) >> ( sizeof( size_t ) * 8 - 1 ) );
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
+                                 const mbedtls_mpi_uint y )
+{
+    mbedtls_mpi_uint ret;
+    mbedtls_mpi_uint cond;
+
+    /*
+     * Check if the most significant bits (MSB) of the operands are different.
+     */
+    cond = ( x ^ y );
+    /*
+     * If the MSB are the same then the difference x-y will be negative (and
+     * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
+     */
+    ret = ( x - y ) & ~cond;
+    /*
+     * If the MSB are different, then the operand with the MSB of 1 is the
+     * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
+     * the MSB of y is 0.)
+     */
+    ret |= y & cond;
+
+
+    ret = ret >> ( sizeof( mbedtls_mpi_uint ) * 8 - 1 );
+
+    return (unsigned) ret;
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+unsigned mbedtls_ct_uint_if( unsigned condition,
+                             unsigned if1,
+                             unsigned if0 )
+{
+    unsigned mask = mbedtls_ct_uint_mask( condition );
+    return( ( mask & if1 ) | (~mask & if0 ) );
+}
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Select between two sign values without branches.
+ *
+ * This is functionally equivalent to `condition ? if1 : if0` but uses only bit
+ * operations in order to avoid branches.
+ *
+ * \note if1 and if0 must be either 1 or -1, otherwise the result
+ *       is undefined.
+ *
+ * \param condition     Condition to test.
+ * \param if1           The first sign; must be either +1 or -1.
+ * \param if0           The second sign; must be either +1 or -1.
+ *
+ * \return  \c if1 if \p condition is nonzero, otherwise \c if0.
+ * */
+static int mbedtls_ct_cond_select_sign( unsigned char condition,
+                                        int if1,
+                                        int if0 )
+{
+    /* In order to avoid questions about what we can reasonably assume about
+     * the representations of signed integers, move everything to unsigned
+     * by taking advantage of the fact that if1 and if0 are either +1 or -1. */
+    unsigned uif1 = if1 + 1;
+    unsigned uif0 = if0 + 1;
+
+    /* condition was 0 or 1, mask is 0 or 2 as are uif1 and uif0 */
+    const unsigned mask = condition << 1;
+
+    /* select uif1 or uif0 */
+    unsigned ur = ( uif0 & ~mask ) | ( uif1 & mask );
+
+    /* ur is now 0 or 2, convert back to -1 or +1 */
+    return( (int) ur - 1 );
+}
+
+void mbedtls_ct_mpi_uint_cond_assign( size_t n,
+                                      mbedtls_mpi_uint *dest,
+                                      const mbedtls_mpi_uint *src,
+                                      unsigned char condition )
+{
+    size_t i;
+
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+
+    /* all-bits 1 if condition is 1, all-bits 0 if condition is 0 */
+    const mbedtls_mpi_uint mask = -condition;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    for( i = 0; i < n; i++ )
+        dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_BASE64_C)
+
+unsigned char mbedtls_ct_base64_enc_char( unsigned char value )
+{
+    unsigned char digit = 0;
+    /* For each range of values, if value is in that range, mask digit with
+     * the corresponding value. Since value can only be in a single range,
+     * only at most one masking will change digit. */
+    digit |= mbedtls_ct_uchar_mask_of_range(  0, 25, value ) & ( 'A' + value );
+    digit |= mbedtls_ct_uchar_mask_of_range( 26, 51, value ) & ( 'a' + value - 26 );
+    digit |= mbedtls_ct_uchar_mask_of_range( 52, 61, value ) & ( '0' + value - 52 );
+    digit |= mbedtls_ct_uchar_mask_of_range( 62, 62, value ) & '+';
+    digit |= mbedtls_ct_uchar_mask_of_range( 63, 63, value ) & '/';
+    return( digit );
+}
+
+signed char mbedtls_ct_base64_dec_value( unsigned char c )
+{
+    unsigned char val = 0;
+    /* For each range of digits, if c is in that range, mask val with
+     * the corresponding value. Since c can only be in a single range,
+     * only at most one masking will change val. Set val to one plus
+     * the desired value so that it stays 0 if c is in none of the ranges. */
+    val |= mbedtls_ct_uchar_mask_of_range( 'A', 'Z', c ) & ( c - 'A' +  0 + 1 );
+    val |= mbedtls_ct_uchar_mask_of_range( 'a', 'z', c ) & ( c - 'a' + 26 + 1 );
+    val |= mbedtls_ct_uchar_mask_of_range( '0', '9', c ) & ( c - '0' + 52 + 1 );
+    val |= mbedtls_ct_uchar_mask_of_range( '+', '+', c ) & ( c - '+' + 62 + 1 );
+    val |= mbedtls_ct_uchar_mask_of_range( '/', '/', c ) & ( c - '/' + 63 + 1 );
+    /* At this point, val is 0 if c is an invalid digit and v+1 if c is
+     * a digit with the value v. */
+    return( val - 1 );
+}
+
+#endif /* MBEDTLS_BASE64_C */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** Shift some data towards the left inside a buffer.
+ *
+ * `mbedtls_ct_mem_move_to_left(start, total, offset)` is functionally
+ * equivalent to
+ * ```
+ * memmove(start, start + offset, total - offset);
+ * memset(start + offset, 0, total - offset);
+ * ```
+ * but it strives to use a memory access pattern (and thus total timing)
+ * that does not depend on \p offset. This timing independence comes at
+ * the expense of performance.
+ *
+ * \param start     Pointer to the start of the buffer.
+ * \param total     Total size of the buffer.
+ * \param offset    Offset from which to copy \p total - \p offset bytes.
+ */
+static void mbedtls_ct_mem_move_to_left( void *start,
+                                         size_t total,
+                                         size_t offset )
+{
+    volatile unsigned char *buf = start;
+    size_t i, n;
+    if( total == 0 )
+        return;
+    for( i = 0; i < total; i++ )
+    {
+        unsigned no_op = mbedtls_ct_size_gt( total - offset, i );
+        /* The first `total - offset` passes are a no-op. The last
+         * `offset` passes shift the data one byte to the left and
+         * zero out the last byte. */
+        for( n = 0; n < total - 1; n++ )
+        {
+            unsigned char current = buf[n];
+            unsigned char next = buf[n+1];
+            buf[n] = mbedtls_ct_uint_if( no_op, current, next );
+        }
+        buf[total-1] = mbedtls_ct_uint_if( no_op, buf[total-1], 0 );
+    }
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
+                              const unsigned char *src,
+                              size_t len,
+                              size_t c1,
+                              size_t c2 )
+{
+    /* mask = c1 == c2 ? 0xff : 0x00 */
+    const size_t equal = mbedtls_ct_size_bool_eq( c1, c2 );
+    const unsigned char mask = (unsigned char) mbedtls_ct_size_mask( equal );
+
+    /* dest[i] = c1 == c2 ? src[i] : dest[i] */
+    for( size_t i = 0; i < len; i++ )
+        dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
+}
+
+void mbedtls_ct_memcpy_offset( unsigned char *dest,
+                               const unsigned char *src,
+                               size_t offset,
+                               size_t offset_min,
+                               size_t offset_max,
+                               size_t len )
+{
+    size_t offsetval;
+
+    for( offsetval = offset_min; offsetval <= offset_max; offsetval++ )
+    {
+        mbedtls_ct_memcpy_if_eq( dest, src + offsetval, len,
+                                 offsetval, offset );
+    }
+}
+
+int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
+                     const unsigned char *add_data,
+                     size_t add_data_len,
+                     const unsigned char *data,
+                     size_t data_len_secret,
+                     size_t min_data_len,
+                     size_t max_data_len,
+                     unsigned char *output )
+{
+    /*
+     * This function breaks the HMAC abstraction and uses the md_clone()
+     * extension to the MD API in order to get constant-flow behaviour.
+     *
+     * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
+     * concatenation, and okey/ikey are the XOR of the key with some fixed bit
+     * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
+     *
+     * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
+     * minlen, then cloning the context, and for each byte up to maxlen
+     * finishing up the hash computation, keeping only the correct result.
+     *
+     * Then we only need to compute HASH(okey + inner_hash) and we're done.
+     */
+    const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info );
+    /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5,
+     * all of which have the same block size except SHA-384. */
+    const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
+    const unsigned char * const ikey = ctx->hmac_ctx;
+    const unsigned char * const okey = ikey + block_size;
+    const size_t hash_size = mbedtls_md_get_size( ctx->md_info );
+
+    unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
+    mbedtls_md_context_t aux;
+    size_t offset;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    mbedtls_md_init( &aux );
+
+#define MD_CHK( func_call ) \
+    do {                    \
+        ret = (func_call);  \
+        if( ret != 0 )      \
+            goto cleanup;   \
+    } while( 0 )
+
+    MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) );
+
+    /* After hmac_start() of hmac_reset(), ikey has already been hashed,
+     * so we can start directly with the message */
+    MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
+    MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
+
+    /* Fill the hash buffer in advance with something that is
+     * not a valid hash (barring an attack on the hash and
+     * deliberately-crafted input), in case the caller doesn't
+     * check the return status properly. */
+    memset( output, '!', hash_size );
+
+    /* For each possible length, compute the hash up to that point */
+    for( offset = min_data_len; offset <= max_data_len; offset++ )
+    {
+        MD_CHK( mbedtls_md_clone( &aux, ctx ) );
+        MD_CHK( mbedtls_md_finish( &aux, aux_out ) );
+        /* Keep only the correct inner_hash in the output buffer */
+        mbedtls_ct_memcpy_if_eq( output, aux_out, hash_size,
+                                 offset, data_len_secret );
+
+        if( offset < max_data_len )
+            MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
+    }
+
+    /* The context needs to finish() before it starts() again */
+    MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
+
+    /* Now compute HASH(okey + inner_hash) */
+    MD_CHK( mbedtls_md_starts( ctx ) );
+    MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
+    MD_CHK( mbedtls_md_update( ctx, output, hash_size ) );
+    MD_CHK( mbedtls_md_finish( ctx, output ) );
+
+    /* Done, get ready for next time */
+    MD_CHK( mbedtls_md_hmac_reset( ctx ) );
+
+#undef MD_CHK
+
+cleanup:
+    mbedtls_md_free( &aux );
+    return( ret );
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#define MPI_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+
+/*
+ * Conditionally assign X = Y, without leaking information
+ * about whether the assignment was made or not.
+ * (Leaking information about the respective sizes of X and Y is ok however.)
+ */
+#if defined(_MSC_VER) && defined(_M_ARM64) && (_MSC_FULL_VER < 193131103)
+/*
+ * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
+ * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
+ */
+__declspec(noinline)
+#endif
+int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X,
+                                  const mbedtls_mpi *Y,
+                                  unsigned char assign )
+{
+    int ret = 0;
+    size_t i;
+    mbedtls_mpi_uint limb_mask;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
+    limb_mask = mbedtls_ct_mpi_uint_mask( assign );;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+
+    X->s = mbedtls_ct_cond_select_sign( assign, Y->s, X->s );
+
+    mbedtls_ct_mpi_uint_cond_assign( Y->n, X->p, Y->p, assign );
+
+    for( i = Y->n; i < X->n; i++ )
+        X->p[i] &= ~limb_mask;
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Conditionally swap X and Y, without leaking information
+ * about whether the swap was made or not.
+ * Here it is not ok to simply swap the pointers, which would lead to
+ * different memory access patterns when X and Y are used afterwards.
+ */
+int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
+                                mbedtls_mpi *Y,
+                                unsigned char swap )
+{
+    int ret, s;
+    size_t i;
+    mbedtls_mpi_uint limb_mask;
+    mbedtls_mpi_uint tmp;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    if( X == Y )
+        return( 0 );
+
+    /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
+    limb_mask = mbedtls_ct_mpi_uint_mask( swap );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
+
+    s = X->s;
+    X->s = mbedtls_ct_cond_select_sign( swap, Y->s, X->s );
+    Y->s = mbedtls_ct_cond_select_sign( swap, s, Y->s );
+
+
+    for( i = 0; i < X->n; i++ )
+    {
+        tmp = X->p[i];
+        X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
+        Y->p[i] = ( Y->p[i] & ~limb_mask ) | (     tmp & limb_mask );
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Compare signed values in constant time
+ */
+int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X,
+                           const mbedtls_mpi *Y,
+                           unsigned *ret )
+{
+    size_t i;
+    /* The value of any of these variables is either 0 or 1 at all times. */
+    unsigned cond, done, X_is_negative, Y_is_negative;
+
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+    MPI_VALIDATE_RET( ret != NULL );
+
+    if( X->n != Y->n )
+        return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+
+    /*
+     * Set sign_N to 1 if N >= 0, 0 if N < 0.
+     * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
+     */
+    X_is_negative = ( X->s & 2 ) >> 1;
+    Y_is_negative = ( Y->s & 2 ) >> 1;
+
+    /*
+     * If the signs are different, then the positive operand is the bigger.
+     * That is if X is negative (X_is_negative == 1), then X < Y is true and it
+     * is false if X is positive (X_is_negative == 0).
+     */
+    cond = ( X_is_negative ^ Y_is_negative );
+    *ret = cond & X_is_negative;
+
+    /*
+     * This is a constant-time function. We might have the result, but we still
+     * need to go through the loop. Record if we have the result already.
+     */
+    done = cond;
+
+    for( i = X->n; i > 0; i-- )
+    {
+        /*
+         * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
+         * X and Y are negative.
+         *
+         * Again even if we can make a decision, we just mark the result and
+         * the fact that we are done and continue looping.
+         */
+        cond = mbedtls_ct_mpi_uint_lt( Y->p[i - 1], X->p[i - 1] );
+        *ret |= cond & ( 1 - done ) & X_is_negative;
+        done |= cond;
+
+        /*
+         * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
+         * X and Y are positive.
+         *
+         * Again even if we can make a decision, we just mark the result and
+         * the fact that we are done and continue looping.
+         */
+        cond = mbedtls_ct_mpi_uint_lt( X->p[i - 1], Y->p[i - 1] );
+        *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
+        done |= cond;
+    }
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+int mbedtls_ct_rsaes_pkcs1_v15_unpadding( int mode,
+                                          unsigned char *input,
+                                          size_t ilen,
+                                          unsigned char *output,
+                                          size_t output_max_len,
+                                          size_t *olen )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t i, plaintext_max_size;
+
+    /* The following variables take sensitive values: their value must
+     * not leak into the observable behavior of the function other than
+     * the designated outputs (output, olen, return value). Otherwise
+     * this would open the execution of the function to
+     * side-channel-based variants of the Bleichenbacher padding oracle
+     * attack. Potential side channels include overall timing, memory
+     * access patterns (especially visible to an adversary who has access
+     * to a shared memory cache), and branches (especially visible to
+     * an adversary who has access to a shared code cache or to a shared
+     * branch predictor). */
+    size_t pad_count = 0;
+    unsigned bad = 0;
+    unsigned char pad_done = 0;
+    size_t plaintext_size = 0;
+    unsigned output_too_large;
+
+    plaintext_max_size = ( output_max_len > ilen - 11 ) ? ilen - 11
+                                                        : output_max_len;
+
+    /* Check and get padding length in constant time and constant
+     * memory trace. The first byte must be 0. */
+    bad |= input[0];
+
+    if( mode == MBEDTLS_RSA_PRIVATE )
+    {
+        /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
+         * where PS must be at least 8 nonzero bytes. */
+        bad |= input[1] ^ MBEDTLS_RSA_CRYPT;
+
+        /* Read the whole buffer. Set pad_done to nonzero if we find
+         * the 0x00 byte and remember the padding length in pad_count. */
+        for( i = 2; i < ilen; i++ )
+        {
+            pad_done  |= ((input[i] | (unsigned char)-input[i]) >> 7) ^ 1;
+            pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
+        }
+    }
+    else
+    {
+        /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
+         * where PS must be at least 8 bytes with the value 0xFF. */
+        bad |= input[1] ^ MBEDTLS_RSA_SIGN;
+
+        /* Read the whole buffer. Set pad_done to nonzero if we find
+         * the 0x00 byte and remember the padding length in pad_count.
+         * If there's a non-0xff byte in the padding, the padding is bad. */
+        for( i = 2; i < ilen; i++ )
+        {
+            pad_done |= mbedtls_ct_uint_if( input[i], 0, 1 );
+            pad_count += mbedtls_ct_uint_if( pad_done, 0, 1 );
+            bad |= mbedtls_ct_uint_if( pad_done, 0, input[i] ^ 0xFF );
+        }
+    }
+
+    /* If pad_done is still zero, there's no data, only unfinished padding. */
+    bad |= mbedtls_ct_uint_if( pad_done, 0, 1 );
+
+    /* There must be at least 8 bytes of padding. */
+    bad |= mbedtls_ct_size_gt( 8, pad_count );
+
+    /* If the padding is valid, set plaintext_size to the number of
+     * remaining bytes after stripping the padding. If the padding
+     * is invalid, avoid leaking this fact through the size of the
+     * output: use the maximum message size that fits in the output
+     * buffer. Do it without branches to avoid leaking the padding
+     * validity through timing. RSA keys are small enough that all the
+     * size_t values involved fit in unsigned int. */
+    plaintext_size = mbedtls_ct_uint_if(
+                        bad, (unsigned) plaintext_max_size,
+                        (unsigned) ( ilen - pad_count - 3 ) );
+
+    /* Set output_too_large to 0 if the plaintext fits in the output
+     * buffer and to 1 otherwise. */
+    output_too_large = mbedtls_ct_size_gt( plaintext_size,
+                                           plaintext_max_size );
+
+    /* Set ret without branches to avoid timing attacks. Return:
+     * - INVALID_PADDING if the padding is bad (bad != 0).
+     * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
+     *   plaintext does not fit in the output buffer.
+     * - 0 if the padding is correct. */
+    ret = - (int) mbedtls_ct_uint_if(
+                    bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
+                    mbedtls_ct_uint_if( output_too_large,
+                                        - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
+                                        0 ) );
+
+    /* If the padding is bad or the plaintext is too large, zero the
+     * data that we're about to copy to the output buffer.
+     * We need to copy the same amount of data
+     * from the same buffer whether the padding is good or not to
+     * avoid leaking the padding validity through overall timing or
+     * through memory or cache access patterns. */
+    bad = mbedtls_ct_uint_mask( bad | output_too_large );
+    for( i = 11; i < ilen; i++ )
+        input[i] &= ~bad;
+
+    /* If the plaintext is too large, truncate it to the buffer size.
+     * Copy anyway to avoid revealing the length through timing, because
+     * revealing the length is as bad as revealing the padding validity
+     * for a Bleichenbacher attack. */
+    plaintext_size = mbedtls_ct_uint_if( output_too_large,
+                                         (unsigned) plaintext_max_size,
+                                         (unsigned) plaintext_size );
+
+    /* Move the plaintext to the leftmost position where it can start in
+     * the working buffer, i.e. make it start plaintext_max_size from
+     * the end of the buffer. Do this with a memory access trace that
+     * does not depend on the plaintext size. After this move, the
+     * starting location of the plaintext is no longer sensitive
+     * information. */
+    mbedtls_ct_mem_move_to_left( input + ilen - plaintext_max_size,
+                                 plaintext_max_size,
+                                 plaintext_max_size - plaintext_size );
+
+    /* Finally copy the decrypted plaintext plus trailing zeros into the output
+     * buffer. If output_max_len is 0, then output may be an invalid pointer
+     * and the result of memcpy() would be undefined; prevent undefined
+     * behavior making sure to depend only on output_max_len (the size of the
+     * user-provided output buffer), which is independent from plaintext
+     * length, validity of padding, success of the decryption, and other
+     * secrets. */
+    if( output_max_len != 0 )
+        memcpy( output, input + ilen - plaintext_max_size, plaintext_max_size );
+
+    /* Report the amount of data we copied to the output buffer. In case
+     * of errors (bad padding or output too large), the value of *olen
+     * when this function returns is not specified. Making it equivalent
+     * to the good case limits the risks of leaking the padding validity. */
+    *olen = plaintext_size;
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
diff --git a/lib/libmbedtls/mbedtls/library/constant_time_internal.h b/lib/libmbedtls/mbedtls/library/constant_time_internal.h
new file mode 100644
index 0000000..a550b38
--- /dev/null
+++ b/lib/libmbedtls/mbedtls/library/constant_time_internal.h
@@ -0,0 +1,336 @@
+/**
+ *  Constant-time functions
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
+#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "mbedtls/ssl_internal.h"
+#endif
+
+#include <stddef.h>
+
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (unsigned) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value     The value to analyze.
+ *
+ * \return          Zero if \p value is zero, otherwise all-bits-one.
+ */
+unsigned mbedtls_ct_uint_mask( unsigned value );
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (size_t) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value     The value to analyze.
+ *
+ * \return          Zero if \p value is zero, otherwise all-bits-one.
+ */
+size_t mbedtls_ct_size_mask( size_t value );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (mbedtls_mpi_uint) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value     The value to analyze.
+ *
+ * \return          Zero if \p value is zero, otherwise all-bits-one.
+ */
+mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask( mbedtls_mpi_uint value );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Constant-flow mask generation for "greater or equal" comparison:
+ * - if \p x >= \p y, return all-bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      All-bits-one if \p x is greater or equal than \p y,
+ *              otherwise zero.
+ */
+size_t mbedtls_ct_size_mask_ge( size_t x,
+                                size_t y );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+/** Constant-flow boolean "equal" comparison:
+ * return x == y
+ *
+ * This is equivalent to \p x == \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      1 if \p x equals to \p y, otherwise 0.
+ */
+unsigned mbedtls_ct_size_bool_eq( size_t x,
+                                  size_t y );
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Decide if an integer is less than the other, without branches.
+ *
+ * This is equivalent to \p x < \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      1 if \p x is less than \p y, otherwise 0.
+ */
+unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
+                                 const mbedtls_mpi_uint y );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+/** Choose between two integer values without branches.
+ *
+ * This is equivalent to `condition ? if1 : if0`, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param condition     Condition to test.
+ * \param if1           Value to use if \p condition is nonzero.
+ * \param if0           Value to use if \p condition is zero.
+ *
+ * \return  \c if1 if \p condition is nonzero, otherwise \c if0.
+ */
+unsigned mbedtls_ct_uint_if( unsigned condition,
+                             unsigned if1,
+                             unsigned if0 );
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Conditionally assign a value without branches.
+ *
+ * This is equivalent to `if ( condition ) dest = src`, but is likely
+ * to be compiled to code using bitwise operation rather than a branch.
+ *
+ * \param n             \p dest and \p src must be arrays of limbs of size n.
+ * \param dest          The MPI to conditionally assign to. This must point
+ *                      to an initialized MPI.
+ * \param src           The MPI to be assigned from. This must point to an
+ *                      initialized MPI.
+ * \param condition     Condition to test, must be 0 or 1.
+ */
+void mbedtls_ct_mpi_uint_cond_assign( size_t n,
+                                      mbedtls_mpi_uint *dest,
+                                      const mbedtls_mpi_uint *src,
+                                      unsigned char condition );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_BASE64_C)
+
+/** Given a value in the range 0..63, return the corresponding Base64 digit.
+ *
+ * The implementation assumes that letters are consecutive (e.g. ASCII
+ * but not EBCDIC).
+ *
+ * \param value     A value in the range 0..63.
+ *
+ * \return          A base64 digit converted from \p value.
+ */
+unsigned char mbedtls_ct_base64_enc_char( unsigned char value );
+
+/** Given a Base64 digit, return its value.
+ *
+ * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
+ * return -1.
+ *
+ * The implementation assumes that letters are consecutive (e.g. ASCII
+ * but not EBCDIC).
+ *
+ * \param c     A base64 digit.
+ *
+ * \return      The value of the base64 digit \p c.
+ */
+signed char mbedtls_ct_base64_dec_value( unsigned char c );
+
+#endif /* MBEDTLS_BASE64_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Conditional memcpy without branches.
+ *
+ * This is equivalent to `if ( c1 == c2 ) memcpy(dest, src, len)`, but is likely
+ * to be compiled to code using bitwise operation rather than a branch.
+ *
+ * \param dest      The pointer to conditionally copy to.
+ * \param src       The pointer to copy from. Shouldn't overlap with \p dest.
+ * \param len       The number of bytes to copy.
+ * \param c1        The first value to analyze in the condition.
+ * \param c2        The second value to analyze in the condition.
+ */
+void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
+                              const unsigned char *src,
+                              size_t len,
+                              size_t c1, size_t c2 );
+
+/** Copy data from a secret position with constant flow.
+ *
+ * This function copies \p len bytes from \p src_base + \p offset_secret to \p
+ * dst, with a code flow and memory access pattern that does not depend on \p
+ * offset_secret, but only on \p offset_min, \p offset_max and \p len.
+ * Functionally equivalent to `memcpy(dst, src + offset_secret, len)`.
+ *
+ * \note                This function reads from \p dest, but the value that
+ *                      is read does not influence the result and this
+ *                      function's behavior is well-defined regardless of the
+ *                      contents of the buffers. This may result in false
+ *                      positives from static or dynamic analyzers, especially
+ *                      if \p dest is not initialized.
+ *
+ * \param dest          The destination buffer. This must point to a writable
+ *                      buffer of at least \p len bytes.
+ * \param src           The base of the source buffer. This must point to a
+ *                      readable buffer of at least \p offset_max + \p len
+ *                      bytes. Shouldn't overlap with \p dest.
+ * \param offset        The offset in the source buffer from which to copy.
+ *                      This must be no less than \p offset_min and no greater
+ *                      than \p offset_max.
+ * \param offset_min    The minimal value of \p offset.
+ * \param offset_max    The maximal value of \p offset.
+ * \param len           The number of bytes to copy.
+ */
+void mbedtls_ct_memcpy_offset( unsigned char *dest,
+                               const unsigned char *src,
+                               size_t offset,
+                               size_t offset_min,
+                               size_t offset_max,
+                               size_t len );
+
+/** Compute the HMAC of variable-length data with constant flow.
+ *
+ * This function computes the HMAC of the concatenation of \p add_data and \p
+ * data, and does with a code flow and memory access pattern that does not
+ * depend on \p data_len_secret, but only on \p min_data_len and \p
+ * max_data_len. In particular, this function always reads exactly \p
+ * max_data_len bytes from \p data.
+ *
+ * \param ctx               The HMAC context. It must have keys configured
+ *                          with mbedtls_md_hmac_starts() and use one of the
+ *                          following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
+ *                          It is reset using mbedtls_md_hmac_reset() after
+ *                          the computation is complete to prepare for the
+ *                          next computation.
+ * \param add_data          The first part of the message whose HMAC is being
+ *                          calculated. This must point to a readable buffer
+ *                          of \p add_data_len bytes.
+ * \param add_data_len      The length of \p add_data in bytes.
+ * \param data              The buffer containing the second part of the
+ *                          message. This must point to a readable buffer
+ *                          of \p max_data_len bytes.
+ * \param data_len_secret   The length of the data to process in \p data.
+ *                          This must be no less than \p min_data_len and no
+ *                          greater than \p max_data_len.
+ * \param min_data_len      The minimal length of the second part of the
+ *                          message, read from \p data.
+ * \param max_data_len      The maximal length of the second part of the
+ *                          message, read from \p data.
+ * \param output            The HMAC will be written here. This must point to
+ *                          a writable buffer of sufficient size to hold the
+ *                          HMAC value.
+ *
+ * \retval 0 on success.
+ * \retval #MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
+ *         The hardware accelerator failed.
+ */
+int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
+                     const unsigned char *add_data,
+                     size_t add_data_len,
+                     const unsigned char *data,
+                     size_t data_len_secret,
+                     size_t min_data_len,
+                     size_t max_data_len,
+                     unsigned char *output );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** This function performs the unpadding part of a PKCS#1 v1.5 decryption
+ *  operation (EME-PKCS1-v1_5 decoding).
+ *
+ * \note The return value from this function is a sensitive value
+ *       (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
+ *       in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
+ *       is often a situation that an attacker can provoke and leaking which
+ *       one is the result is precisely the information the attacker wants.
+ *
+ * \param mode           The mode of operation. This must be either
+ *                       #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param input          The input buffer which is the payload inside PKCS#1v1.5
+ *                       encryption padding, called the "encoded message EM"
+ *                       by the terminology.
+ * \param ilen           The length of the payload in the \p input buffer.
+ * \param output         The buffer for the payload, called "message M" by the
+ *                       PKCS#1 terminology. This must be a writable buffer of
+ *                       length \p output_max_len bytes.
+ * \param olen           The address at which to store the length of
+ *                       the payload. This must not be \c NULL.
+ * \param output_max_len The length in bytes of the output buffer \p output.
+ *
+ * \return      \c 0 on success.
+ * \return      #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
+ *              The output buffer is too small for the unpadded payload.
+ * \return      #MBEDTLS_ERR_RSA_INVALID_PADDING
+ *              The input doesn't contain properly formatted padding.
+ */
+int mbedtls_ct_rsaes_pkcs1_v15_unpadding( int mode,
+                                          unsigned char *input,
+                                          size_t ilen,
+                                          unsigned char *output,
+                                          size_t output_max_len,
+                                          size_t *olen );
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */
diff --git a/lib/libmbedtls/mbedtls/library/constant_time_invasive.h b/lib/libmbedtls/mbedtls/library/constant_time_invasive.h
new file mode 100644
index 0000000..4620ca1
--- /dev/null
+++ b/lib/libmbedtls/mbedtls/library/constant_time_invasive.h
@@ -0,0 +1,51 @@
+/**
+ * \file constant_time_invasive.h
+ *
+ * \brief Constant-time module: interfaces for invasive testing only.
+ *
+ * The interfaces in this file are intended for testing purposes only.
+ * They SHOULD NOT be made available in library integrations except when
+ * building the library for testing.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_INVASIVE_H
+#define MBEDTLS_CONSTANT_TIME_INVASIVE_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_TEST_HOOKS)
+
+/** Turn a value into a mask:
+ * - if \p low <= \p c <= \p high,
+ *   return the all-bits 1 mask, aka (unsigned) -1
+ * - otherwise, return the all-bits 0 mask, aka 0
+ *
+ * \param low   The value to analyze.
+ * \param high  The value to analyze.
+ * \param c     The value to analyze.
+ *
+ * \return      All-bits-one if \p low <= \p c <= \p high, otherwise zero.
+ */
+unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low,
+                                              unsigned char high,
+                                              unsigned char c );
+
+#endif /* MBEDTLS_TEST_HOOKS */
+
+#endif /* MBEDTLS_CONSTANT_TIME_INVASIVE_H */
diff --git a/lib/libmbedtls/mbedtls/library/ctr_drbg.c b/lib/libmbedtls/mbedtls/library/ctr_drbg.c
index ab52861..a00d66c 100644
--- a/lib/libmbedtls/mbedtls/library/ctr_drbg.c
+++ b/lib/libmbedtls/mbedtls/library/ctr_drbg.c
@@ -152,11 +152,8 @@
      *     (Total is padded to a multiple of 16-bytes with zeroes)
      */
     p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
-    *p++ = ( data_len >> 24 ) & 0xff;
-    *p++ = ( data_len >> 16 ) & 0xff;
-    *p++ = ( data_len >> 8  ) & 0xff;
-    *p++ = ( data_len       ) & 0xff;
-    p += 3;
+    MBEDTLS_PUT_UINT32_BE( data_len, p, 0);
+    p += 4 + 3;
     *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
     memcpy( p, data, data_len );
     p[data_len] = 0x80;
@@ -831,7 +828,7 @@
                         return( 1 );                        \
                     }
 
-#define SELF_TEST_OUPUT_DISCARD_LENGTH 64
+#define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
 
 /*
  * Checkup routine
@@ -857,7 +854,7 @@
                                 (void *) entropy_source_pr,
                                 pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
-    CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+    CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) );
     CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) );
 
@@ -882,7 +879,7 @@
                                 (void *) entropy_source_nopr,
                                 pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
     CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
-    CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+    CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) );
     CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) );
 
diff --git a/lib/libmbedtls/mbedtls/library/des.c b/lib/libmbedtls/mbedtls/library/des.c
index eddf55e..91d22b5 100644
--- a/lib/libmbedtls/mbedtls/library/des.c
+++ b/lib/libmbedtls/mbedtls/library/des.c
@@ -28,6 +28,7 @@
 #if defined(MBEDTLS_DES_C)
 
 #include "mbedtls/des.h"
+#include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
 
 #include <string.h>
@@ -44,29 +45,6 @@
 #if !defined(MBEDTLS_DES_ALT)
 
 /*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-}
-#endif
-
-/*
  * Expanded DES S-boxes
  */
 static const uint32_t SB1[64] =
@@ -423,8 +401,8 @@
     int i;
     uint32_t X, Y, T;
 
-    GET_UINT32_BE( X, key, 0 );
-    GET_UINT32_BE( Y, key, 4 );
+    X = MBEDTLS_GET_UINT32_BE( key, 0 );
+    Y = MBEDTLS_GET_UINT32_BE( key, 4 );
 
     /*
      * Permuted Choice 1
@@ -633,8 +611,8 @@
 
     SK = ctx->sk;
 
-    GET_UINT32_BE( X, input, 0 );
-    GET_UINT32_BE( Y, input, 4 );
+    X = MBEDTLS_GET_UINT32_BE( input, 0 );
+    Y = MBEDTLS_GET_UINT32_BE( input, 4 );
 
     DES_IP( X, Y );
 
@@ -646,8 +624,8 @@
 
     DES_FP( Y, X );
 
-    PUT_UINT32_BE( Y, output, 0 );
-    PUT_UINT32_BE( X, output, 4 );
+    MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
+    MBEDTLS_PUT_UINT32_BE( X, output, 4 );
 
     return( 0 );
 }
@@ -665,6 +643,7 @@
                     unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[8];
 
     if( length % 8 )
@@ -677,7 +656,9 @@
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_des_crypt_ecb( ctx, output, output );
+            ret = mbedtls_des_crypt_ecb( ctx, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 8 );
 
             input  += 8;
@@ -690,7 +671,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 8 );
-            mbedtls_des_crypt_ecb( ctx, input, output );
+            ret = mbedtls_des_crypt_ecb( ctx, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -702,8 +685,10 @@
             length -= 8;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -720,8 +705,8 @@
 
     SK = ctx->sk;
 
-    GET_UINT32_BE( X, input, 0 );
-    GET_UINT32_BE( Y, input, 4 );
+    X = MBEDTLS_GET_UINT32_BE( input, 0 );
+    Y = MBEDTLS_GET_UINT32_BE( input, 4 );
 
     DES_IP( X, Y );
 
@@ -745,8 +730,8 @@
 
     DES_FP( Y, X );
 
-    PUT_UINT32_BE( Y, output, 0 );
-    PUT_UINT32_BE( X, output, 4 );
+    MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
+    MBEDTLS_PUT_UINT32_BE( X, output, 4 );
 
     return( 0 );
 }
@@ -764,6 +749,7 @@
                      unsigned char *output )
 {
     int i;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char temp[8];
 
     if( length % 8 )
@@ -776,7 +762,9 @@
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( input[i] ^ iv[i] );
 
-            mbedtls_des3_crypt_ecb( ctx, output, output );
+            ret = mbedtls_des3_crypt_ecb( ctx, output, output );
+            if( ret != 0 )
+                goto exit;
             memcpy( iv, output, 8 );
 
             input  += 8;
@@ -789,7 +777,9 @@
         while( length > 0 )
         {
             memcpy( temp, input, 8 );
-            mbedtls_des3_crypt_ecb( ctx, input, output );
+            ret = mbedtls_des3_crypt_ecb( ctx, input, output );
+            if( ret != 0 )
+                goto exit;
 
             for( i = 0; i < 8; i++ )
                 output[i] = (unsigned char)( output[i] ^ iv[i] );
@@ -801,8 +791,10 @@
             length -= 8;
         }
     }
+    ret = 0;
 
-    return( 0 );
+exit:
+    return( ret );
 }
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 
@@ -895,39 +887,43 @@
         switch( i )
         {
         case 0:
-            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
             break;
 
         case 1:
-            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
             break;
 
         case 2:
-            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
             break;
 
         case 3:
-            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
             break;
 
         case 4:
-            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
             break;
 
         case 5:
-            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
             break;
 
         default:
             return( 1 );
         }
+        if( ret != 0 )
+            goto exit;
 
         for( j = 0; j < 100; j++ )
         {
             if( u == 0 )
-                mbedtls_des_crypt_ecb( &ctx, buf, buf );
+                ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
             else
-                mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+                ret = mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+            if( ret != 0 )
+                goto exit;
         }
 
         if( ( v == MBEDTLS_DES_DECRYPT &&
@@ -970,41 +966,45 @@
         switch( i )
         {
         case 0:
-            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_dec( &ctx, des3_test_keys );
             break;
 
         case 1:
-            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            ret = mbedtls_des_setkey_enc( &ctx, des3_test_keys );
             break;
 
         case 2:
-            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
             break;
 
         case 3:
-            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
             break;
 
         case 4:
-            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
             break;
 
         case 5:
-            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            ret = mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
             break;
 
         default:
             return( 1 );
         }
+        if( ret != 0 )
+            goto exit;
 
         if( v == MBEDTLS_DES_DECRYPT )
         {
             for( j = 0; j < 100; j++ )
             {
                 if( u == 0 )
-                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                    ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
                 else
-                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                    ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                if( ret != 0 )
+                    goto exit;
             }
         }
         else
@@ -1014,9 +1014,11 @@
                 unsigned char tmp[8];
 
                 if( u == 0 )
-                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                    ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
                 else
-                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                    ret = mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+                if( ret != 0 )
+                    goto exit;
 
                 memcpy( tmp, prv, 8 );
                 memcpy( prv, buf, 8 );
@@ -1050,6 +1052,8 @@
     mbedtls_des_free( &ctx );
     mbedtls_des3_free( &ctx3 );
 
+    if( ret != 0 )
+        ret = 1;
     return( ret );
 }
 
diff --git a/lib/libmbedtls/mbedtls/library/dhm.c b/lib/libmbedtls/mbedtls/library/dhm.c
index accd5a8..88e148b 100644
--- a/lib/libmbedtls/mbedtls/library/dhm.c
+++ b/lib/libmbedtls/mbedtls/library/dhm.c
@@ -231,8 +231,8 @@
         MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ),               \
                                                    p + 2,               \
                                                    ( n ) ) );           \
-        *p++ = (unsigned char)( ( n ) >> 8 );                           \
-        *p++ = (unsigned char)( ( n )      );                           \
+        *p++ = MBEDTLS_BYTE_1( n );                                     \
+        *p++ = MBEDTLS_BYTE_0( n );                                     \
         p += ( n );                                                     \
     } while( 0 )
 
diff --git a/lib/libmbedtls/mbedtls/library/ecdh.c b/lib/libmbedtls/mbedtls/library/ecdh.c
index 9dfa868..60c6e42 100644
--- a/lib/libmbedtls/mbedtls/library/ecdh.c
+++ b/lib/libmbedtls/mbedtls/library/ecdh.c
@@ -399,7 +399,7 @@
 }
 
 /*
- * Read the ServerKeyExhange parameters (RFC 4492)
+ * Read the ServerKeyExchange parameters (RFC 4492)
  *      struct {
  *          ECParameters    curve_params;
  *          ECPoint         public;
diff --git a/lib/libmbedtls/mbedtls/library/ecjpake.c b/lib/libmbedtls/mbedtls/library/ecjpake.c
index 464ff51..0b9bffb 100644
--- a/lib/libmbedtls/mbedtls/library/ecjpake.c
+++ b/lib/libmbedtls/mbedtls/library/ecjpake.c
@@ -166,10 +166,7 @@
     if( ret != 0 )
         return( ret );
 
-    (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
-    (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
-    (*p)[2] = (unsigned char)( ( len >>  8 ) & 0xFF );
-    (*p)[3] = (unsigned char)( ( len       ) & 0xFF );
+    MBEDTLS_PUT_UINT32_BE( len, *p, 0 );
 
     *p += 4 + len;
 
@@ -209,10 +206,8 @@
     if( end - p < 4 )
         return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
 
-    *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
-    *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
-    *p++ = (unsigned char)( ( id_len >>  8 ) & 0xFF );
-    *p++ = (unsigned char)( ( id_len       ) & 0xFF );
+    MBEDTLS_PUT_UINT32_BE( id_len, p, 0 );
+    p += 4;
 
     if( end < p || (size_t)( end - p ) < id_len )
         return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
@@ -352,7 +347,7 @@
         goto cleanup;
     }
 
-    *(*p)++ = (unsigned char)( len & 0xFF );
+    *(*p)++ = MBEDTLS_BYTE_0( len );
     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
     *p += len;
 
@@ -440,7 +435,7 @@
 
 /*
  * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
- * Ouputs: verified peer public keys Xa, Xb
+ * Outputs: verified peer public keys Xa, Xb
  */
 static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
                               const mbedtls_ecp_group *grp,
diff --git a/lib/libmbedtls/mbedtls/library/ecp.c b/lib/libmbedtls/mbedtls/library/ecp.c
index 4aaac7e..192ce6f 100644
--- a/lib/libmbedtls/mbedtls/library/ecp.c
+++ b/lib/libmbedtls/mbedtls/library/ecp.c
@@ -1164,8 +1164,7 @@
     /*
      * Next two bytes are the namedcurve value
      */
-    buf[0] = curve_info->tls_id >> 8;
-    buf[1] = curve_info->tls_id & 0xFF;
+    MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, buf, 0 );
 
     return( 0 );
 }
@@ -1312,7 +1311,7 @@
  * For curves in short Weierstrass form, we do all the internal operations in
  * Jacobian coordinates.
  *
- * For multiplication, we'll use a comb method with coutermeasueres against
+ * For multiplication, we'll use a comb method with countermeasures against
  * SPA, hence timing attacks.
  */
 
@@ -2256,7 +2255,7 @@
  * This function is mainly responsible for administrative work:
  * - managing the restart context if enabled
  * - managing the table of precomputed points (passed between the below two
- *   functions): allocation, computation, ownership tranfer, freeing.
+ *   functions): allocation, computation, ownership transfer, freeing.
  *
  * It delegates the actual arithmetic work to:
  *      ecp_precompute_comb() and ecp_mul_comb_with_precomp()
@@ -2427,7 +2426,7 @@
 /*
  * For Montgomery curves, we do all the internal arithmetic in projective
  * coordinates. Import/export of points uses only the x coordinates, which is
- * internaly represented as X / Z.
+ * internally represented as X / Z.
  *
  * For scalar multiplication, we'll use a Montgomery ladder.
  */
@@ -2597,7 +2596,7 @@
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) );
     mbedtls_mpi_free( &R->Y );
 
-    /* RP.X might be sligtly larger than P, so reduce it */
+    /* RP.X might be slightly larger than P, so reduce it */
     MOD_ADD( RP.X );
 
     /* Randomize coordinates of the starting point */
diff --git a/lib/libmbedtls/mbedtls/library/ecp_curves.c b/lib/libmbedtls/mbedtls/library/ecp_curves.c
index 537ad38..ea43e1f 100644
--- a/lib/libmbedtls/mbedtls/library/ecp_curves.c
+++ b/lib/libmbedtls/mbedtls/library/ecp_curves.c
@@ -796,6 +796,8 @@
     ECP_VALIDATE_RET( grp != NULL );
     mbedtls_ecp_group_free( grp );
 
+    mbedtls_ecp_group_init( grp );
+
     grp->id = id;
 
     switch( id )
diff --git a/lib/libmbedtls/mbedtls/library/gcm.c b/lib/libmbedtls/mbedtls/library/gcm.c
index f237bab..43a5e1b 100644
--- a/lib/libmbedtls/mbedtls/library/gcm.c
+++ b/lib/libmbedtls/mbedtls/library/gcm.c
@@ -59,29 +59,6 @@
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
 /*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-}
-#endif
-
-/*
  * Initialize a context
  */
 void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
@@ -111,12 +88,12 @@
         return( ret );
 
     /* pack h as two 64-bits ints, big-endian */
-    GET_UINT32_BE( hi, h,  0  );
-    GET_UINT32_BE( lo, h,  4  );
+    hi = MBEDTLS_GET_UINT32_BE( h,  0  );
+    lo = MBEDTLS_GET_UINT32_BE( h,  4  );
     vh = (uint64_t) hi << 32 | lo;
 
-    GET_UINT32_BE( hi, h,  8  );
-    GET_UINT32_BE( lo, h,  12 );
+    hi = MBEDTLS_GET_UINT32_BE( h,  8  );
+    lo = MBEDTLS_GET_UINT32_BE( h,  12 );
     vl = (uint64_t) hi << 32 | lo;
 
     /* 8 = 1000 corresponds to 1 in GF(2^128) */
@@ -223,10 +200,10 @@
     if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
         unsigned char h[16];
 
-        PUT_UINT32_BE( ctx->HH[8] >> 32, h,  0 );
-        PUT_UINT32_BE( ctx->HH[8],       h,  4 );
-        PUT_UINT32_BE( ctx->HL[8] >> 32, h,  8 );
-        PUT_UINT32_BE( ctx->HL[8],       h, 12 );
+        MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h,  0 );
+        MBEDTLS_PUT_UINT32_BE( ctx->HH[8],       h,  4 );
+        MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h,  8 );
+        MBEDTLS_PUT_UINT32_BE( ctx->HL[8],       h, 12 );
 
         mbedtls_aesni_gcm_mult( output, x, h );
         return;
@@ -262,10 +239,10 @@
         zl ^= ctx->HL[hi];
     }
 
-    PUT_UINT32_BE( zh >> 32, output, 0 );
-    PUT_UINT32_BE( zh, output, 4 );
-    PUT_UINT32_BE( zl >> 32, output, 8 );
-    PUT_UINT32_BE( zl, output, 12 );
+    MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
+    MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
+    MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
+    MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
 }
 
 int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
@@ -280,6 +257,7 @@
     size_t i;
     const unsigned char *p;
     size_t use_len, olen = 0;
+    uint64_t iv_bits;
 
     GCM_VALIDATE_RET( ctx != NULL );
     GCM_VALIDATE_RET( iv != NULL );
@@ -309,7 +287,8 @@
     else
     {
         memset( work_buf, 0x00, 16 );
-        PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
+        iv_bits = (uint64_t)iv_len * 8;
+        MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
 
         p = iv;
         while( iv_len > 0 )
@@ -442,10 +421,10 @@
     {
         memset( work_buf, 0x00, 16 );
 
-        PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0  );
-        PUT_UINT32_BE( ( orig_add_len       ), work_buf, 4  );
-        PUT_UINT32_BE( ( orig_len     >> 32 ), work_buf, 8  );
-        PUT_UINT32_BE( ( orig_len           ), work_buf, 12 );
+        MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0  );
+        MBEDTLS_PUT_UINT32_BE( ( orig_add_len       ), work_buf, 4  );
+        MBEDTLS_PUT_UINT32_BE( ( orig_len     >> 32 ), work_buf, 8  );
+        MBEDTLS_PUT_UINT32_BE( ( orig_len           ), work_buf, 12 );
 
         for( i = 0; i < 16; i++ )
             ctx->buf[i] ^= work_buf[i];
diff --git a/lib/libmbedtls/mbedtls/library/md4.c b/lib/libmbedtls/mbedtls/library/md4.c
index 4fd6bc3..eaa679a 100644
--- a/lib/libmbedtls/mbedtls/library/md4.c
+++ b/lib/libmbedtls/mbedtls/library/md4.c
@@ -44,29 +44,6 @@
 
 #if !defined(MBEDTLS_MD4_ALT)
 
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ]       )             \
-        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i)                                    \
-{                                                               \
-    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
-    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
-    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
-    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
-}
-#endif
-
 void mbedtls_md4_init( mbedtls_md4_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_md4_context ) );
@@ -118,22 +95,22 @@
         uint32_t X[16], A, B, C, D;
     } local;
 
-    GET_UINT32_LE( local.X[ 0], data,  0 );
-    GET_UINT32_LE( local.X[ 1], data,  4 );
-    GET_UINT32_LE( local.X[ 2], data,  8 );
-    GET_UINT32_LE( local.X[ 3], data, 12 );
-    GET_UINT32_LE( local.X[ 4], data, 16 );
-    GET_UINT32_LE( local.X[ 5], data, 20 );
-    GET_UINT32_LE( local.X[ 6], data, 24 );
-    GET_UINT32_LE( local.X[ 7], data, 28 );
-    GET_UINT32_LE( local.X[ 8], data, 32 );
-    GET_UINT32_LE( local.X[ 9], data, 36 );
-    GET_UINT32_LE( local.X[10], data, 40 );
-    GET_UINT32_LE( local.X[11], data, 44 );
-    GET_UINT32_LE( local.X[12], data, 48 );
-    GET_UINT32_LE( local.X[13], data, 52 );
-    GET_UINT32_LE( local.X[14], data, 56 );
-    GET_UINT32_LE( local.X[15], data, 60 );
+    local.X[ 0] = MBEDTLS_GET_UINT32_LE( data,  0 );
+    local.X[ 1] = MBEDTLS_GET_UINT32_LE( data,  4 );
+    local.X[ 2] = MBEDTLS_GET_UINT32_LE( data,  8 );
+    local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+    local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+    local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+    local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+    local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+    local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+    local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+    local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+    local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+    local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+    local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+    local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+    local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
 
 #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
 
@@ -333,8 +310,8 @@
          | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
-    PUT_UINT32_LE( low,  msglen, 0 );
-    PUT_UINT32_LE( high, msglen, 4 );
+    MBEDTLS_PUT_UINT32_LE( low,  msglen, 0 );
+    MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
 
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
@@ -347,10 +324,10 @@
         return( ret );
 
 
-    PUT_UINT32_LE( ctx->state[0], output,  0 );
-    PUT_UINT32_LE( ctx->state[1], output,  4 );
-    PUT_UINT32_LE( ctx->state[2], output,  8 );
-    PUT_UINT32_LE( ctx->state[3], output, 12 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[0], output,  0 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[1], output,  4 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[2], output,  8 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
 
     return( 0 );
 }
diff --git a/lib/libmbedtls/mbedtls/library/md5.c b/lib/libmbedtls/mbedtls/library/md5.c
index c4f2dbf..4b53fcf 100644
--- a/lib/libmbedtls/mbedtls/library/md5.c
+++ b/lib/libmbedtls/mbedtls/library/md5.c
@@ -43,29 +43,6 @@
 
 #if !defined(MBEDTLS_MD5_ALT)
 
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ]       )             \
-        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i)                                    \
-{                                                               \
-    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
-    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
-    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
-    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
-}
-#endif
-
 void mbedtls_md5_init( mbedtls_md5_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_md5_context ) );
@@ -117,22 +94,22 @@
         uint32_t X[16], A, B, C, D;
     } local;
 
-    GET_UINT32_LE( local.X[ 0], data,  0 );
-    GET_UINT32_LE( local.X[ 1], data,  4 );
-    GET_UINT32_LE( local.X[ 2], data,  8 );
-    GET_UINT32_LE( local.X[ 3], data, 12 );
-    GET_UINT32_LE( local.X[ 4], data, 16 );
-    GET_UINT32_LE( local.X[ 5], data, 20 );
-    GET_UINT32_LE( local.X[ 6], data, 24 );
-    GET_UINT32_LE( local.X[ 7], data, 28 );
-    GET_UINT32_LE( local.X[ 8], data, 32 );
-    GET_UINT32_LE( local.X[ 9], data, 36 );
-    GET_UINT32_LE( local.X[10], data, 40 );
-    GET_UINT32_LE( local.X[11], data, 44 );
-    GET_UINT32_LE( local.X[12], data, 48 );
-    GET_UINT32_LE( local.X[13], data, 52 );
-    GET_UINT32_LE( local.X[14], data, 56 );
-    GET_UINT32_LE( local.X[15], data, 60 );
+    local.X[ 0] = MBEDTLS_GET_UINT32_LE( data,  0 );
+    local.X[ 1] = MBEDTLS_GET_UINT32_LE( data,  4 );
+    local.X[ 2] = MBEDTLS_GET_UINT32_LE( data,  8 );
+    local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+    local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+    local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+    local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+    local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+    local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+    local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+    local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+    local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+    local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+    local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+    local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+    local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
 
 #define S(x,n)                                                          \
     ( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) )
@@ -353,8 +330,8 @@
          | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
-    PUT_UINT32_LE( low,  ctx->buffer, 56 );
-    PUT_UINT32_LE( high, ctx->buffer, 60 );
+    MBEDTLS_PUT_UINT32_LE( low,  ctx->buffer, 56 );
+    MBEDTLS_PUT_UINT32_LE( high, ctx->buffer, 60 );
 
     if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
         return( ret );
@@ -362,10 +339,10 @@
     /*
      * Output final state
      */
-    PUT_UINT32_LE( ctx->state[0], output,  0 );
-    PUT_UINT32_LE( ctx->state[1], output,  4 );
-    PUT_UINT32_LE( ctx->state[2], output,  8 );
-    PUT_UINT32_LE( ctx->state[3], output, 12 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[0], output,  0 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[1], output,  4 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[2], output,  8 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
 
     return( 0 );
 }
diff --git a/lib/libmbedtls/mbedtls/library/memory_buffer_alloc.c b/lib/libmbedtls/mbedtls/library/memory_buffer_alloc.c
index 0d5d27d..cc62324 100644
--- a/lib/libmbedtls/mbedtls/library/memory_buffer_alloc.c
+++ b/lib/libmbedtls/mbedtls/library/memory_buffer_alloc.c
@@ -555,8 +555,8 @@
 
 static void buffer_alloc_free_mutexed( void *ptr )
 {
-    /* We have to good option here, but corrupting the heap seems
-     * worse than loosing memory. */
+    /* We have no good option here, but corrupting the heap seems
+     * worse than losing memory. */
     if( mbedtls_mutex_lock( &heap.mutex ) )
         return;
     buffer_alloc_free( ptr );
diff --git a/lib/libmbedtls/mbedtls/library/net_sockets.c b/lib/libmbedtls/mbedtls/library/net_sockets.c
index 5fbe1f7..8c765e1 100644
--- a/lib/libmbedtls/mbedtls/library/net_sockets.c
+++ b/lib/libmbedtls/mbedtls/library/net_sockets.c
@@ -107,7 +107,9 @@
 
 #include <stdio.h>
 
+#if defined(MBEDTLS_HAVE_TIME)
 #include <time.h>
+#endif
 
 #include <stdint.h>
 
diff --git a/lib/libmbedtls/mbedtls/library/nist_kw.c b/lib/libmbedtls/mbedtls/library/nist_kw.c
index 5054ca2..1aea0b6 100644
--- a/lib/libmbedtls/mbedtls/library/nist_kw.c
+++ b/lib/libmbedtls/mbedtls/library/nist_kw.c
@@ -34,6 +34,7 @@
 #include "mbedtls/nist_kw.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
 
 #include <stdint.h>
 #include <string.h>
@@ -52,51 +53,11 @@
 #define KW_SEMIBLOCK_LENGTH    8
 #define MIN_SEMIBLOCKS_COUNT   3
 
-/* constant-time buffer comparison */
-static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n )
-{
-    size_t i;
-    volatile const unsigned char *A = (volatile const unsigned char *) a;
-    volatile const unsigned char *B = (volatile const unsigned char *) b;
-    volatile unsigned char diff = 0;
-
-    for( i = 0; i < n; i++ )
-    {
-        /* Read volatile data in order before computing diff.
-         * This avoids IAR compiler warning:
-         * 'the order of volatile accesses is undefined ..' */
-        unsigned char x = A[i], y = B[i];
-        diff |= x ^ y;
-    }
-
-    return( diff );
-}
-
 /*! The 64-bit default integrity check value (ICV) for KW mode. */
 static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
 /*! The 32-bit default integrity check value (ICV) for KWP mode. */
 static const  unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6};
 
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-do {                                                    \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-} while( 0 )
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-do {                                                    \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-} while( 0 )
-#endif
-
 /*
  * Initialize context
  */
@@ -243,7 +204,7 @@
         }
 
         memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 );
-        PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
+        MBEDTLS_PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
                        KW_SEMIBLOCK_LENGTH / 2 );
 
         memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len );
@@ -418,7 +379,7 @@
             goto cleanup;
 
         /* Check ICV in "constant-time" */
-        diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
+        diff = mbedtls_ct_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
 
         if( diff != 0 )
         {
@@ -467,14 +428,14 @@
         }
 
         /* Check ICV in "constant-time" */
-        diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
+        diff = mbedtls_ct_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
 
         if( diff != 0 )
         {
             ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
         }
 
-        GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 );
+        Plen = MBEDTLS_GET_UINT32_BE( A, KW_SEMIBLOCK_LENGTH / 2 );
 
         /*
          * Plen is the length of the plaintext, when the input is valid.
diff --git a/lib/libmbedtls/mbedtls/library/pkcs12.c b/lib/libmbedtls/mbedtls/library/pkcs12.c
index 9823d96..cacf7db 100644
--- a/lib/libmbedtls/mbedtls/library/pkcs12.c
+++ b/lib/libmbedtls/mbedtls/library/pkcs12.c
@@ -179,6 +179,9 @@
     mbedtls_cipher_context_t cipher_ctx;
     size_t olen = 0;
 
+    if( pwd == NULL && pwdlen != 0 )
+        return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
+
     cipher_info = mbedtls_cipher_info_from_type( cipher_type );
     if( cipher_info == NULL )
         return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
@@ -231,12 +234,23 @@
     unsigned char *p = data;
     size_t use_len;
 
-    while( data_len > 0 )
+    if( filler != NULL && fill_len != 0 )
     {
-        use_len = ( data_len > fill_len ) ? fill_len : data_len;
-        memcpy( p, filler, use_len );
-        p += use_len;
-        data_len -= use_len;
+        while( data_len > 0 )
+        {
+            use_len = ( data_len > fill_len ) ? fill_len : data_len;
+            memcpy( p, filler, use_len );
+            p += use_len;
+            data_len -= use_len;
+        }
+    }
+    else
+    {
+        /* If either of the above are not true then clearly there is nothing
+         * that this function can do. The function should *not* be called
+         * under either of those circumstances, as you could end up with an
+         * incorrect output but for safety's sake, leaving the check in as
+         * otherwise we could end up with memory corruption.*/
     }
 }
 
@@ -253,6 +267,8 @@
     unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
     unsigned char *p;
     unsigned char c;
+    int           use_password = 0;
+    int           use_salt = 0;
 
     size_t hlen, use_len, v, i;
 
@@ -263,6 +279,15 @@
     if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
         return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
 
+    if( pwd == NULL && pwdlen != 0 )
+        return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
+
+    if( salt == NULL && saltlen != 0 )
+        return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
+
+    use_password = ( pwd && pwdlen != 0 );
+    use_salt = ( salt && saltlen != 0 );
+
     md_info = mbedtls_md_info_from_type( md_type );
     if( md_info == NULL )
         return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
@@ -280,8 +305,15 @@
 
     memset( diversifier, (unsigned char) id, v );
 
-    pkcs12_fill_buffer( salt_block, v, salt, saltlen );
-    pkcs12_fill_buffer( pwd_block,  v, pwd,  pwdlen  );
+    if( use_salt != 0 )
+    {
+        pkcs12_fill_buffer( salt_block, v, salt, saltlen );
+    }
+
+    if( use_password != 0 )
+    {
+        pkcs12_fill_buffer( pwd_block,  v, pwd,  pwdlen  );
+    }
 
     p = data;
     while( datalen > 0 )
@@ -293,11 +325,17 @@
         if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
             goto exit;
 
-        if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 )
-            goto exit;
+        if( use_salt != 0 )
+        {
+            if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v )) != 0 )
+                goto exit;
+        }
 
-        if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 )
-            goto exit;
+        if( use_password != 0)
+        {
+            if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v )) != 0 )
+                goto exit;
+        }
 
         if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
             goto exit;
@@ -325,22 +363,28 @@
             if( ++hash_block[i - 1] != 0 )
                 break;
 
-        // salt_block += B
-        c = 0;
-        for( i = v; i > 0; i-- )
+        if( use_salt != 0 )
         {
-            j = salt_block[i - 1] + hash_block[i - 1] + c;
-            c = (unsigned char) (j >> 8);
-            salt_block[i - 1] = j & 0xFF;
+            // salt_block += B
+            c = 0;
+            for( i = v; i > 0; i-- )
+            {
+                j = salt_block[i - 1] + hash_block[i - 1] + c;
+                c = MBEDTLS_BYTE_1( j );
+                salt_block[i - 1] = MBEDTLS_BYTE_0( j );
+            }
         }
 
-        // pwd_block  += B
-        c = 0;
-        for( i = v; i > 0; i-- )
+        if( use_password != 0 )
         {
-            j = pwd_block[i - 1] + hash_block[i - 1] + c;
-            c = (unsigned char) (j >> 8);
-            pwd_block[i - 1] = j & 0xFF;
+            // pwd_block  += B
+            c = 0;
+            for( i = v; i > 0; i-- )
+            {
+                j = pwd_block[i - 1] + hash_block[i - 1] + c;
+                c = MBEDTLS_BYTE_1( j );
+                pwd_block[i - 1] = MBEDTLS_BYTE_0( j );
+            }
         }
     }
 
diff --git a/lib/libmbedtls/mbedtls/library/pkparse.c b/lib/libmbedtls/mbedtls/library/pkparse.c
index 3222ca2..ea5c6b6 100644
--- a/lib/libmbedtls/mbedtls/library/pkparse.c
+++ b/lib/libmbedtls/mbedtls/library/pkparse.c
@@ -474,7 +474,7 @@
     }
 
     /*
-     * grp may already be initilialized; if so, make sure IDs match
+     * grp may already be initialized; if so, make sure IDs match
      */
     if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id )
         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
@@ -807,7 +807,7 @@
        goto cleanup;
 
 #else
-    /* Verify existance of the CRT params */
+    /* Verify existence of the CRT params */
     if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
         ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
         ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 )
@@ -1380,8 +1380,11 @@
     }
 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
 
-    if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
+    ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen );
+    if( ret == 0 )
+    {
         return( 0 );
+    }
 
     mbedtls_pk_free( pk );
     mbedtls_pk_init( pk );
@@ -1460,10 +1463,16 @@
     {
         p = pem.buf;
         if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
+        {
+            mbedtls_pem_free( &pem );
             return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+        }
 
         if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
+        {
+            mbedtls_pem_free( &pem );
             return( ret );
+        }
 
         if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 )
             mbedtls_pk_free( ctx );
diff --git a/lib/libmbedtls/mbedtls/library/poly1305.c b/lib/libmbedtls/mbedtls/library/poly1305.c
index 492d145..7375a0c 100644
--- a/lib/libmbedtls/mbedtls/library/poly1305.c
+++ b/lib/libmbedtls/mbedtls/library/poly1305.c
@@ -52,13 +52,6 @@
 
 #define POLY1305_BLOCK_SIZE_BYTES ( 16U )
 
-#define BYTES_TO_U32_LE( data, offset )                           \
-    ( (uint32_t) (data)[offset]                                     \
-          | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 )   \
-          | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 )  \
-          | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 )  \
-    )
-
 /*
  * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
  * However we provided an alternative for platforms without such a multiplier.
@@ -129,10 +122,10 @@
     for( i = 0U; i < nblocks; i++ )
     {
         /* The input block is treated as a 128-bit little-endian integer */
-        d0   = BYTES_TO_U32_LE( input, offset + 0  );
-        d1   = BYTES_TO_U32_LE( input, offset + 4  );
-        d2   = BYTES_TO_U32_LE( input, offset + 8  );
-        d3   = BYTES_TO_U32_LE( input, offset + 12 );
+        d0   = MBEDTLS_GET_UINT32_LE( input, offset + 0  );
+        d1   = MBEDTLS_GET_UINT32_LE( input, offset + 4  );
+        d2   = MBEDTLS_GET_UINT32_LE( input, offset + 8  );
+        d3   = MBEDTLS_GET_UINT32_LE( input, offset + 12 );
 
         /* Compute: acc += (padded) block as a 130-bit integer */
         d0  += (uint64_t) acc0;
@@ -257,22 +250,10 @@
     acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
 
     /* Compute MAC (128 least significant bits of the accumulator) */
-    mac[ 0] = (unsigned char)( acc0       );
-    mac[ 1] = (unsigned char)( acc0 >>  8 );
-    mac[ 2] = (unsigned char)( acc0 >> 16 );
-    mac[ 3] = (unsigned char)( acc0 >> 24 );
-    mac[ 4] = (unsigned char)( acc1       );
-    mac[ 5] = (unsigned char)( acc1 >>  8 );
-    mac[ 6] = (unsigned char)( acc1 >> 16 );
-    mac[ 7] = (unsigned char)( acc1 >> 24 );
-    mac[ 8] = (unsigned char)( acc2       );
-    mac[ 9] = (unsigned char)( acc2 >>  8 );
-    mac[10] = (unsigned char)( acc2 >> 16 );
-    mac[11] = (unsigned char)( acc2 >> 24 );
-    mac[12] = (unsigned char)( acc3       );
-    mac[13] = (unsigned char)( acc3 >>  8 );
-    mac[14] = (unsigned char)( acc3 >> 16 );
-    mac[15] = (unsigned char)( acc3 >> 24 );
+    MBEDTLS_PUT_UINT32_LE( acc0, mac,  0 );
+    MBEDTLS_PUT_UINT32_LE( acc1, mac,  4 );
+    MBEDTLS_PUT_UINT32_LE( acc2, mac,  8 );
+    MBEDTLS_PUT_UINT32_LE( acc3, mac, 12 );
 }
 
 void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
@@ -297,15 +278,15 @@
     POLY1305_VALIDATE_RET( key != NULL );
 
     /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
-    ctx->r[0] = BYTES_TO_U32_LE( key, 0 )  & 0x0FFFFFFFU;
-    ctx->r[1] = BYTES_TO_U32_LE( key, 4 )  & 0x0FFFFFFCU;
-    ctx->r[2] = BYTES_TO_U32_LE( key, 8 )  & 0x0FFFFFFCU;
-    ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
+    ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 )  & 0x0FFFFFFFU;
+    ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 )  & 0x0FFFFFFCU;
+    ctx->r[2] = MBEDTLS_GET_UINT32_LE( key, 8 )  & 0x0FFFFFFCU;
+    ctx->r[3] = MBEDTLS_GET_UINT32_LE( key, 12 ) & 0x0FFFFFFCU;
 
-    ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
-    ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
-    ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
-    ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
+    ctx->s[0] = MBEDTLS_GET_UINT32_LE( key, 16 );
+    ctx->s[1] = MBEDTLS_GET_UINT32_LE( key, 20 );
+    ctx->s[2] = MBEDTLS_GET_UINT32_LE( key, 24 );
+    ctx->s[3] = MBEDTLS_GET_UINT32_LE( key, 28 );
 
     /* Initial accumulator state */
     ctx->acc[0] = 0U;
diff --git a/lib/libmbedtls/mbedtls/library/ripemd160.c b/lib/libmbedtls/mbedtls/library/ripemd160.c
index ae4dee4..aed7322 100644
--- a/lib/libmbedtls/mbedtls/library/ripemd160.c
+++ b/lib/libmbedtls/mbedtls/library/ripemd160.c
@@ -44,29 +44,6 @@
 
 #if !defined(MBEDTLS_RIPEMD160_ALT)
 
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ]       )             \
-        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i)                                    \
-{                                                               \
-    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
-    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
-    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
-    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
-}
-#endif
-
 void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
@@ -122,22 +99,22 @@
         uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
     } local;
 
-    GET_UINT32_LE( local.X[ 0], data,  0 );
-    GET_UINT32_LE( local.X[ 1], data,  4 );
-    GET_UINT32_LE( local.X[ 2], data,  8 );
-    GET_UINT32_LE( local.X[ 3], data, 12 );
-    GET_UINT32_LE( local.X[ 4], data, 16 );
-    GET_UINT32_LE( local.X[ 5], data, 20 );
-    GET_UINT32_LE( local.X[ 6], data, 24 );
-    GET_UINT32_LE( local.X[ 7], data, 28 );
-    GET_UINT32_LE( local.X[ 8], data, 32 );
-    GET_UINT32_LE( local.X[ 9], data, 36 );
-    GET_UINT32_LE( local.X[10], data, 40 );
-    GET_UINT32_LE( local.X[11], data, 44 );
-    GET_UINT32_LE( local.X[12], data, 48 );
-    GET_UINT32_LE( local.X[13], data, 52 );
-    GET_UINT32_LE( local.X[14], data, 56 );
-    GET_UINT32_LE( local.X[15], data, 60 );
+    local.X[ 0] = MBEDTLS_GET_UINT32_LE( data,  0 );
+    local.X[ 1] = MBEDTLS_GET_UINT32_LE( data,  4 );
+    local.X[ 2] = MBEDTLS_GET_UINT32_LE( data,  8 );
+    local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+    local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+    local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+    local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+    local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+    local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+    local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+    local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+    local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+    local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+    local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+    local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+    local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
 
     local.A = local.Ap = ctx->state[0];
     local.B = local.Bp = ctx->state[1];
@@ -400,8 +377,8 @@
          | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
-    PUT_UINT32_LE( low,  msglen, 0 );
-    PUT_UINT32_LE( high, msglen, 4 );
+    MBEDTLS_PUT_UINT32_LE( low,  msglen, 0 );
+    MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
 
     last = ctx->total[0] & 0x3F;
     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
@@ -414,11 +391,11 @@
     if( ret != 0 )
         return( ret );
 
-    PUT_UINT32_LE( ctx->state[0], output,  0 );
-    PUT_UINT32_LE( ctx->state[1], output,  4 );
-    PUT_UINT32_LE( ctx->state[2], output,  8 );
-    PUT_UINT32_LE( ctx->state[3], output, 12 );
-    PUT_UINT32_LE( ctx->state[4], output, 16 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[0], output,  0 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[1], output,  4 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[2], output,  8 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
+    MBEDTLS_PUT_UINT32_LE( ctx->state[4], output, 16 );
 
     return( 0 );
 }
diff --git a/lib/libmbedtls/mbedtls/library/rsa.c b/lib/libmbedtls/mbedtls/library/rsa.c
index f438b2a..497f011 100644
--- a/lib/libmbedtls/mbedtls/library/rsa.c
+++ b/lib/libmbedtls/mbedtls/library/rsa.c
@@ -44,6 +44,8 @@
 #include "mbedtls/oid.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -72,22 +74,6 @@
 #define RSA_VALIDATE( cond )                                           \
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
-#if defined(MBEDTLS_PKCS1_V15)
-/* constant-time buffer comparison */
-static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
-{
-    size_t i;
-    const unsigned char *A = (const unsigned char *) a;
-    const unsigned char *B = (const unsigned char *) b;
-    unsigned char diff = 0;
-
-    for( i = 0; i < n; i++ )
-        diff |= A[i] ^ B[i];
-
-    return( diff );
-}
-#endif /* MBEDTLS_PKCS1_V15 */
-
 int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
                         const mbedtls_mpi *N,
                         const mbedtls_mpi *P, const mbedtls_mpi *Q,
@@ -846,10 +832,10 @@
  * the more bits of the key can be recovered. See [3].
  *
  * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
- * observations on avarage.
+ * observations on average.
  *
  * For example with 28 byte blinding to achieve 2 collisions the adversary has
- * to make 2^112 observations on avarage.
+ * to make 2^112 observations on average.
  *
  * (With the currently (as of 2017 April) known best algorithms breaking 2048
  * bit RSA requires approximately as much time as trying out 2^112 random keys.
@@ -1499,126 +1485,21 @@
 #endif /* MBEDTLS_PKCS1_V21 */
 
 #if defined(MBEDTLS_PKCS1_V15)
-/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
- *
- * \param value     The value to analyze.
- * \return          Zero if \p value is zero, otherwise all-bits-one.
- */
-static unsigned all_or_nothing_int( unsigned value )
-{
-    /* MSVC has a warning about unary minus on unsigned, but this is
-     * well-defined and precisely what we want to do here */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-}
-
-/** Check whether a size is out of bounds, without branches.
- *
- * This is equivalent to `size > max`, but is likely to be compiled to
- * to code using bitwise operation rather than a branch.
- *
- * \param size      Size to check.
- * \param max       Maximum desired value for \p size.
- * \return          \c 0 if `size <= max`.
- * \return          \c 1 if `size > max`.
- */
-static unsigned size_greater_than( size_t size, size_t max )
-{
-    /* Return the sign bit (1 for negative) of (max - size). */
-    return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
-}
-
-/** Choose between two integer values, without branches.
- *
- * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
- * to code using bitwise operation rather than a branch.
- *
- * \param cond      Condition to test.
- * \param if1       Value to use if \p cond is nonzero.
- * \param if0       Value to use if \p cond is zero.
- * \return          \c if1 if \p cond is nonzero, otherwise \c if0.
- */
-static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
-{
-    unsigned mask = all_or_nothing_int( cond );
-    return( ( mask & if1 ) | (~mask & if0 ) );
-}
-
-/** Shift some data towards the left inside a buffer without leaking
- * the length of the data through side channels.
- *
- * `mem_move_to_left(start, total, offset)` is functionally equivalent to
- * ```
- * memmove(start, start + offset, total - offset);
- * memset(start + offset, 0, total - offset);
- * ```
- * but it strives to use a memory access pattern (and thus total timing)
- * that does not depend on \p offset. This timing independence comes at
- * the expense of performance.
- *
- * \param start     Pointer to the start of the buffer.
- * \param total     Total size of the buffer.
- * \param offset    Offset from which to copy \p total - \p offset bytes.
- */
-static void mem_move_to_left( void *start,
-                              size_t total,
-                              size_t offset )
-{
-    volatile unsigned char *buf = start;
-    size_t i, n;
-    if( total == 0 )
-        return;
-    for( i = 0; i < total; i++ )
-    {
-        unsigned no_op = size_greater_than( total - offset, i );
-        /* The first `total - offset` passes are a no-op. The last
-         * `offset` passes shift the data one byte to the left and
-         * zero out the last byte. */
-        for( n = 0; n < total - 1; n++ )
-        {
-            unsigned char current = buf[n];
-            unsigned char next = buf[n+1];
-            buf[n] = if_int( no_op, current, next );
-        }
-        buf[total-1] = if_int( no_op, buf[total-1], 0 );
-    }
-}
-
 /*
  * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
                                  int (*f_rng)(void *, unsigned char *, size_t),
                                  void *p_rng,
-                                 int mode, size_t *olen,
+                                 int mode,
+                                 size_t *olen,
                                  const unsigned char *input,
                                  unsigned char *output,
                                  size_t output_max_len )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t ilen, i, plaintext_max_size;
+    size_t ilen;
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
-    /* The following variables take sensitive values: their value must
-     * not leak into the observable behavior of the function other than
-     * the designated outputs (output, olen, return value). Otherwise
-     * this would open the execution of the function to
-     * side-channel-based variants of the Bleichenbacher padding oracle
-     * attack. Potential side channels include overall timing, memory
-     * access patterns (especially visible to an adversary who has access
-     * to a shared memory cache), and branches (especially visible to
-     * an adversary who has access to a shared code cache or to a shared
-     * branch predictor). */
-    size_t pad_count = 0;
-    unsigned bad = 0;
-    unsigned char pad_done = 0;
-    size_t plaintext_size = 0;
-    unsigned output_too_large;
 
     RSA_VALIDATE_RET( ctx != NULL );
     RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
@@ -1628,9 +1509,6 @@
     RSA_VALIDATE_RET( olen != NULL );
 
     ilen = ctx->len;
-    plaintext_max_size = ( output_max_len > ilen - 11 ?
-                           ilen - 11 :
-                           output_max_len );
 
     if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1645,115 +1523,8 @@
     if( ret != 0 )
         goto cleanup;
 
-    /* Check and get padding length in constant time and constant
-     * memory trace. The first byte must be 0. */
-    bad |= buf[0];
-
-    if( mode == MBEDTLS_RSA_PRIVATE )
-    {
-        /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
-         * where PS must be at least 8 nonzero bytes. */
-        bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
-
-        /* Read the whole buffer. Set pad_done to nonzero if we find
-         * the 0x00 byte and remember the padding length in pad_count. */
-        for( i = 2; i < ilen; i++ )
-        {
-            pad_done  |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
-            pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
-        }
-    }
-    else
-    {
-        /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
-         * where PS must be at least 8 bytes with the value 0xFF. */
-        bad |= buf[1] ^ MBEDTLS_RSA_SIGN;
-
-        /* Read the whole buffer. Set pad_done to nonzero if we find
-         * the 0x00 byte and remember the padding length in pad_count.
-         * If there's a non-0xff byte in the padding, the padding is bad. */
-        for( i = 2; i < ilen; i++ )
-        {
-            pad_done |= if_int( buf[i], 0, 1 );
-            pad_count += if_int( pad_done, 0, 1 );
-            bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
-        }
-    }
-
-    /* If pad_done is still zero, there's no data, only unfinished padding. */
-    bad |= if_int( pad_done, 0, 1 );
-
-    /* There must be at least 8 bytes of padding. */
-    bad |= size_greater_than( 8, pad_count );
-
-    /* If the padding is valid, set plaintext_size to the number of
-     * remaining bytes after stripping the padding. If the padding
-     * is invalid, avoid leaking this fact through the size of the
-     * output: use the maximum message size that fits in the output
-     * buffer. Do it without branches to avoid leaking the padding
-     * validity through timing. RSA keys are small enough that all the
-     * size_t values involved fit in unsigned int. */
-    plaintext_size = if_int( bad,
-                             (unsigned) plaintext_max_size,
-                             (unsigned) ( ilen - pad_count - 3 ) );
-
-    /* Set output_too_large to 0 if the plaintext fits in the output
-     * buffer and to 1 otherwise. */
-    output_too_large = size_greater_than( plaintext_size,
-                                          plaintext_max_size );
-
-    /* Set ret without branches to avoid timing attacks. Return:
-     * - INVALID_PADDING if the padding is bad (bad != 0).
-     * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
-     *   plaintext does not fit in the output buffer.
-     * - 0 if the padding is correct. */
-    ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
-                  if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
-                          0 ) );
-
-    /* If the padding is bad or the plaintext is too large, zero the
-     * data that we're about to copy to the output buffer.
-     * We need to copy the same amount of data
-     * from the same buffer whether the padding is good or not to
-     * avoid leaking the padding validity through overall timing or
-     * through memory or cache access patterns. */
-    bad = all_or_nothing_int( bad | output_too_large );
-    for( i = 11; i < ilen; i++ )
-        buf[i] &= ~bad;
-
-    /* If the plaintext is too large, truncate it to the buffer size.
-     * Copy anyway to avoid revealing the length through timing, because
-     * revealing the length is as bad as revealing the padding validity
-     * for a Bleichenbacher attack. */
-    plaintext_size = if_int( output_too_large,
-                             (unsigned) plaintext_max_size,
-                             (unsigned) plaintext_size );
-
-    /* Move the plaintext to the leftmost position where it can start in
-     * the working buffer, i.e. make it start plaintext_max_size from
-     * the end of the buffer. Do this with a memory access trace that
-     * does not depend on the plaintext size. After this move, the
-     * starting location of the plaintext is no longer sensitive
-     * information. */
-    mem_move_to_left( buf + ilen - plaintext_max_size,
-                      plaintext_max_size,
-                      plaintext_max_size - plaintext_size );
-
-    /* Finally copy the decrypted plaintext plus trailing zeros into the output
-     * buffer. If output_max_len is 0, then output may be an invalid pointer
-     * and the result of memcpy() would be undefined; prevent undefined
-     * behavior making sure to depend only on output_max_len (the size of the
-     * user-provided output buffer), which is independent from plaintext
-     * length, validity of padding, success of the decryption, and other
-     * secrets. */
-    if( output_max_len != 0 )
-        memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
-
-    /* Report the amount of data we copied to the output buffer. In case
-     * of errors (bad padding or output too large), the value of *olen
-     * when this function returns is not specified. Making it equivalent
-     * to the good case limits the risks of leaking the padding validity. */
-    *olen = plaintext_size;
+    ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding( mode, buf, ilen,
+                                                output, output_max_len, olen );
 
 cleanup:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -2172,7 +1943,7 @@
     MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
     MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
 
-    if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
+    if( mbedtls_ct_memcmp( verif, sig, ctx->len ) != 0 )
     {
         ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
         goto cleanup;
@@ -2181,9 +1952,13 @@
     memcpy( sig, sig_try, ctx->len );
 
 cleanup:
+    mbedtls_platform_zeroize( sig_try, ctx->len );
+    mbedtls_platform_zeroize( verif, ctx->len );
     mbedtls_free( sig_try );
     mbedtls_free( verif );
 
+    if( ret != 0 )
+        memset( sig, '!', ctx->len );
     return( ret );
 }
 #endif /* MBEDTLS_PKCS1_V15 */
@@ -2470,8 +2245,8 @@
      * Compare
      */
 
-    if( ( ret = mbedtls_safer_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/sha1.c b/lib/libmbedtls/mbedtls/library/sha1.c
index 6b0f58e..0a5edaf 100644
--- a/lib/libmbedtls/mbedtls/library/sha1.c
+++ b/lib/libmbedtls/mbedtls/library/sha1.c
@@ -48,29 +48,6 @@
 
 #if !defined(MBEDTLS_SHA1_ALT)
 
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-}
-#endif
-
 void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
 {
     SHA1_VALIDATE( ctx != NULL );
@@ -133,22 +110,22 @@
     SHA1_VALIDATE_RET( ctx != NULL );
     SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
 
-    GET_UINT32_BE( local.W[ 0], data,  0 );
-    GET_UINT32_BE( local.W[ 1], data,  4 );
-    GET_UINT32_BE( local.W[ 2], data,  8 );
-    GET_UINT32_BE( local.W[ 3], data, 12 );
-    GET_UINT32_BE( local.W[ 4], data, 16 );
-    GET_UINT32_BE( local.W[ 5], data, 20 );
-    GET_UINT32_BE( local.W[ 6], data, 24 );
-    GET_UINT32_BE( local.W[ 7], data, 28 );
-    GET_UINT32_BE( local.W[ 8], data, 32 );
-    GET_UINT32_BE( local.W[ 9], data, 36 );
-    GET_UINT32_BE( local.W[10], data, 40 );
-    GET_UINT32_BE( local.W[11], data, 44 );
-    GET_UINT32_BE( local.W[12], data, 48 );
-    GET_UINT32_BE( local.W[13], data, 52 );
-    GET_UINT32_BE( local.W[14], data, 56 );
-    GET_UINT32_BE( local.W[15], data, 60 );
+    local.W[ 0] = MBEDTLS_GET_UINT32_BE( data,  0 );
+    local.W[ 1] = MBEDTLS_GET_UINT32_BE( data,  4 );
+    local.W[ 2] = MBEDTLS_GET_UINT32_BE( data,  8 );
+    local.W[ 3] = MBEDTLS_GET_UINT32_BE( data, 12 );
+    local.W[ 4] = MBEDTLS_GET_UINT32_BE( data, 16 );
+    local.W[ 5] = MBEDTLS_GET_UINT32_BE( data, 20 );
+    local.W[ 6] = MBEDTLS_GET_UINT32_BE( data, 24 );
+    local.W[ 7] = MBEDTLS_GET_UINT32_BE( data, 28 );
+    local.W[ 8] = MBEDTLS_GET_UINT32_BE( data, 32 );
+    local.W[ 9] = MBEDTLS_GET_UINT32_BE( data, 36 );
+    local.W[10] = MBEDTLS_GET_UINT32_BE( data, 40 );
+    local.W[11] = MBEDTLS_GET_UINT32_BE( data, 44 );
+    local.W[12] = MBEDTLS_GET_UINT32_BE( data, 48 );
+    local.W[13] = MBEDTLS_GET_UINT32_BE( data, 52 );
+    local.W[14] = MBEDTLS_GET_UINT32_BE( data, 56 );
+    local.W[15] = MBEDTLS_GET_UINT32_BE( data, 60 );
 
 #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
 
@@ -408,8 +385,8 @@
          | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
-    PUT_UINT32_BE( high, ctx->buffer, 56 );
-    PUT_UINT32_BE( low,  ctx->buffer, 60 );
+    MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
+    MBEDTLS_PUT_UINT32_BE( low,  ctx->buffer, 60 );
 
     if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
         return( ret );
@@ -417,11 +394,11 @@
     /*
      * Output final state
      */
-    PUT_UINT32_BE( ctx->state[0], output,  0 );
-    PUT_UINT32_BE( ctx->state[1], output,  4 );
-    PUT_UINT32_BE( ctx->state[2], output,  8 );
-    PUT_UINT32_BE( ctx->state[3], output, 12 );
-    PUT_UINT32_BE( ctx->state[4], output, 16 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[0], output,  0 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[1], output,  4 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[2], output,  8 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
 
     return( 0 );
 }
diff --git a/lib/libmbedtls/mbedtls/library/sha256.c b/lib/libmbedtls/mbedtls/library/sha256.c
index be373d9..db675ef 100644
--- a/lib/libmbedtls/mbedtls/library/sha256.c
+++ b/lib/libmbedtls/mbedtls/library/sha256.c
@@ -50,29 +50,6 @@
 
 #if !defined(MBEDTLS_SHA256_ALT)
 
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-do {                                                    \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-} while( 0 )
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-do {                                                    \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-} while( 0 )
-#endif
-
 void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
 {
     SHA256_VALIDATE( ctx != NULL );
@@ -214,7 +191,7 @@
     for( i = 0; i < 64; i++ )
     {
         if( i < 16 )
-            GET_UINT32_BE( local.W[i], data, 4 * i );
+            local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
         else
             R( i );
 
@@ -229,7 +206,7 @@
     }
 #else /* MBEDTLS_SHA256_SMALLER */
     for( i = 0; i < 16; i++ )
-        GET_UINT32_BE( local.W[i], data, 4 * i );
+        local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
 
     for( i = 0; i < 16; i += 8 )
     {
@@ -395,8 +372,8 @@
          | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
-    PUT_UINT32_BE( high, ctx->buffer, 56 );
-    PUT_UINT32_BE( low,  ctx->buffer, 60 );
+    MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
+    MBEDTLS_PUT_UINT32_BE( low,  ctx->buffer, 60 );
 
     if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
         return( ret );
@@ -404,16 +381,16 @@
     /*
      * Output final state
      */
-    PUT_UINT32_BE( ctx->state[0], output,  0 );
-    PUT_UINT32_BE( ctx->state[1], output,  4 );
-    PUT_UINT32_BE( ctx->state[2], output,  8 );
-    PUT_UINT32_BE( ctx->state[3], output, 12 );
-    PUT_UINT32_BE( ctx->state[4], output, 16 );
-    PUT_UINT32_BE( ctx->state[5], output, 20 );
-    PUT_UINT32_BE( ctx->state[6], output, 24 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[0], output,  0 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[1], output,  4 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[2], output,  8 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
+    MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
 
     if( ctx->is224 == 0 )
-        PUT_UINT32_BE( ctx->state[7], output, 28 );
+        MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
 
     return( 0 );
 }
diff --git a/lib/libmbedtls/mbedtls/library/sha512.c b/lib/libmbedtls/mbedtls/library/sha512.c
index 06a628a..02a135c 100644
--- a/lib/libmbedtls/mbedtls/library/sha512.c
+++ b/lib/libmbedtls/mbedtls/library/sha512.c
@@ -56,44 +56,13 @@
 
 #if !defined(MBEDTLS_SHA512_ALT)
 
-/*
- * 64-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT64_BE
-#define GET_UINT64_BE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
-        | ( (uint64_t) (b)[(i) + 1] << 48 )       \
-        | ( (uint64_t) (b)[(i) + 2] << 40 )       \
-        | ( (uint64_t) (b)[(i) + 3] << 32 )       \
-        | ( (uint64_t) (b)[(i) + 4] << 24 )       \
-        | ( (uint64_t) (b)[(i) + 5] << 16 )       \
-        | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
-        | ( (uint64_t) (b)[(i) + 7]       );      \
-}
-#endif /* GET_UINT64_BE */
-
-#ifndef PUT_UINT64_BE
-#define PUT_UINT64_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
-    (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 7] = (unsigned char) ( (n)       );       \
-}
-#endif /* PUT_UINT64_BE */
-
 #if defined(MBEDTLS_SHA512_SMALLER)
 static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
 {
-    PUT_UINT64_BE(n, b, i);
+    MBEDTLS_PUT_UINT64_BE(n, b, i);
 }
 #else
-#define sha512_put_uint64_be    PUT_UINT64_BE
+#define sha512_put_uint64_be    MBEDTLS_PUT_UINT64_BE
 #endif /* MBEDTLS_SHA512_SMALLER */
 
 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
@@ -269,7 +238,7 @@
     {
         if( i < 16 )
         {
-            GET_UINT64_BE( local.W[i], data, i << 3 );
+            local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
         }
         else
         {
@@ -289,7 +258,7 @@
 #else /* MBEDTLS_SHA512_SMALLER */
     for( i = 0; i < 16; i++ )
     {
-        GET_UINT64_BE( local.W[i], data, i << 3 );
+        local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
     }
 
     for( ; i < 80; i++ )
diff --git a/lib/libmbedtls/mbedtls/library/ssl_ciphersuites.c b/lib/libmbedtls/mbedtls/library/ssl_ciphersuites.c
index 3826ad2..ceec77e 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_ciphersuites.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_ciphersuites.c
@@ -2181,6 +2181,7 @@
 static int supported_ciphersuites[MAX_CIPHERSUITES];
 static int supported_init = 0;
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info )
 {
     (void)cs_info;
diff --git a/lib/libmbedtls/mbedtls/library/ssl_cli.c b/lib/libmbedtls/mbedtls/library/ssl_cli.c
index f49178c..72351c9 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_cli.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_cli.c
@@ -33,9 +33,11 @@
 #include "mbedtls/ssl_internal.h"
 #include "mbedtls/debug.h"
 #include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 #include "mbedtls/psa_util.h"
+#include "psa/crypto.h"
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 #include <string.h>
@@ -51,6 +53,7 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf )
 {
     if( conf->psk_identity     == NULL ||
@@ -71,6 +74,7 @@
 }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf )
 {
     if( conf->psk_identity     == NULL ||
@@ -89,6 +93,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
                                    unsigned char *buf,
                                    const unsigned char *end,
@@ -136,18 +141,19 @@
      * } ServerNameList;
      *
      */
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SERVERNAME, p, 0 );
+    p += 2;
 
-    *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( (hostname_len + 5)      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( hostname_len + 5, p, 0 );
+    p += 2;
 
-    *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( (hostname_len + 3)      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( hostname_len + 3, p, 0 );
+    p += 2;
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
-    *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( hostname_len      ) & 0xFF );
+    *p++ = MBEDTLS_BYTE_0( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME );
+
+    MBEDTLS_PUT_UINT16_BE( hostname_len, p, 0 );
+    p += 2;
 
     memcpy( p, ssl->hostname, hostname_len );
 
@@ -158,6 +164,7 @@
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
                                         unsigned char *buf,
                                         const unsigned char *end,
@@ -181,14 +188,12 @@
     /*
      * Secure renegotiation
      */
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 )
-                            & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      )
-                            & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
-    *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
-    *p++ = ssl->verify_data_len & 0xFF;
+    *p++ = MBEDTLS_BYTE_0( ssl->verify_data_len + 1 );
+    *p++ = MBEDTLS_BYTE_0( ssl->verify_data_len );
 
     memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
 
@@ -203,6 +208,7 @@
  */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
                                                unsigned char *buf,
                                                const unsigned char *end,
@@ -283,14 +289,14 @@
      * SignatureAndHashAlgorithm
      *   supported_signature_algorithms<2..2^16-2>;
      */
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, p, 0 );
+    p += 2;
 
-    *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ( sig_alg_len + 2 )      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( sig_alg_len + 2, p, 0 );
+    p += 2;
 
-    *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( sig_alg_len      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( sig_alg_len, p, 0 );
+    p += 2;
 
     *olen = 6 + sig_alg_len;
 
@@ -301,6 +307,7 @@
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
                                                     unsigned char *buf,
                                                     const unsigned char *end,
@@ -354,26 +361,25 @@
          grp_id++ )
     {
         info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
-        elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
-        elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
+        elliptic_curve_list[elliptic_curve_len++] = MBEDTLS_BYTE_1( info->tls_id );
+        elliptic_curve_list[elliptic_curve_len++] = MBEDTLS_BYTE_0( info->tls_id );
     }
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 )
-                            & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES      )
-                            & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES, p, 0 );
+    p += 2;
 
-    *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 )      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( elliptic_curve_len + 2, p, 0 );
+    p += 2;
 
-    *p++ = (unsigned char)( ( ( elliptic_curve_len     ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ( elliptic_curve_len     )      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( elliptic_curve_len, p, 0 );
+    p += 2;
 
     *olen = 6 + elliptic_curve_len;
 
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
                                                   unsigned char *buf,
                                                   const unsigned char *end,
@@ -388,10 +394,8 @@
         ( "client hello, adding supported_point_formats extension" ) );
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 )
-                            & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS      )
-                            & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 2;
@@ -407,6 +411,7 @@
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
                                        unsigned char *buf,
                                        const unsigned char *end,
@@ -427,8 +432,8 @@
 
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 );
+    p += 2;
 
     /*
      * We may need to send ClientHello multiple times for Hello verification.
@@ -470,8 +475,8 @@
         memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
     }
 
-    *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( kkpp_len      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 );
+    p += 2;
 
     *olen = kkpp_len + 4;
 
@@ -480,6 +485,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_cid_ext( mbedtls_ssl_context *ssl,
                               unsigned char *buf,
                               const unsigned char *end,
@@ -510,11 +516,11 @@
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, (unsigned)( ssl->own_cid_len + 5 ) );
 
     /* Add extension ID + size */
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_CID, p, 0 );
+    p += 2;
     ext_len = (size_t) ssl->own_cid_len + 1;
-    *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ext_len      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+    p += 2;
 
     *p++ = (uint8_t) ssl->own_cid_len;
     memcpy( p, ssl->own_cid, ssl->own_cid_len );
@@ -526,6 +532,7 @@
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
                                               unsigned char *buf,
                                               const unsigned char *end,
@@ -543,10 +550,8 @@
 
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 )
-                            & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH      )
-                            & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 1;
@@ -560,6 +565,7 @@
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
                                          unsigned char *buf,
                                          const unsigned char *end,
@@ -577,8 +583,8 @@
 
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_TRUNCATED_HMAC, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 0x00;
@@ -590,6 +596,7 @@
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
                                            unsigned char *buf,
                                            const unsigned char *end,
@@ -608,8 +615,8 @@
 
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 0x00;
@@ -621,6 +628,7 @@
 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
                                       unsigned char *buf,
                                       const unsigned char *end,
@@ -639,10 +647,8 @@
 
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 )
-                            & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET      )
-                            & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 0x00;
@@ -654,6 +660,7 @@
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
                                          unsigned char *buf,
                                          const unsigned char *end,
@@ -673,11 +680,11 @@
     /* The addition is safe here since the ticket length is 16 bit. */
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 + tlen );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0 );
+    p += 2;
 
-    *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( tlen      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( tlen, p, 0 );
+    p += 2;
 
     *olen = 4;
 
@@ -696,6 +703,7 @@
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
 #if defined(MBEDTLS_SSL_ALPN)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
                                unsigned char *buf,
                                const unsigned char *end,
@@ -717,8 +725,8 @@
 
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + alpnlen );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ALPN, p, 0 );
+    p += 2;
 
     /*
      * opaque ProtocolName<1..2^8-1>;
@@ -745,18 +753,17 @@
     *olen = p - buf;
 
     /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
-    buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
-    buf[5] = (unsigned char)( ( ( *olen - 6 )      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( *olen - 6, buf, 4 );
 
     /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
-    buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
-    buf[3] = (unsigned char)( ( ( *olen - 4 )      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( *olen - 4, buf, 2 );
 
     return( 0 );
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
                                    unsigned char *buf,
                                    const unsigned char *end,
@@ -802,12 +809,11 @@
      */
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, ext_len + 4 );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_USE_SRTP, p, 0 );
+    p += 2;
 
-
-    *p++ = (unsigned char)( ( ( ext_len & 0xFF00 ) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ext_len & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+    p += 2;
 
     /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
     /* micro-optimization:
@@ -818,8 +824,7 @@
      *                        >> 8 ) & 0xFF );
      */
     *p++ = 0;
-    *p++ = (unsigned char)( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
-                            & 0xFF );
+    *p++ = MBEDTLS_BYTE_0( 2 * ssl->conf->dtls_srtp_profile_list_len );
 
     for( protection_profiles_index=0;
          protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
@@ -831,8 +836,8 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
                                         profile_value ) );
-            *p++ = ( ( profile_value >> 8 ) & 0xFF );
-            *p++ = ( profile_value & 0xFF );
+            MBEDTLS_PUT_UINT16_BE( profile_value, p, 0 );
+            p += 2;
         }
         else
         {
@@ -879,6 +884,7 @@
 /*
  * Generate random bytes for ClientHello
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_generate_random( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -900,10 +906,8 @@
 
 #if defined(MBEDTLS_HAVE_TIME)
     t = mbedtls_time( NULL );
-    *p++ = (unsigned char)( t >> 24 );
-    *p++ = (unsigned char)( t >> 16 );
-    *p++ = (unsigned char)( t >>  8 );
-    *p++ = (unsigned char)( t       );
+    MBEDTLS_PUT_UINT32_BE( t, p, 0 );
+    p += 4;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
                                 (long long) t ) );
@@ -930,6 +934,7 @@
  *
  * \return          0 if valid, else 1
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_validate_ciphersuite(
     const mbedtls_ssl_ciphersuite_t * suite_info,
     const mbedtls_ssl_context * ssl,
@@ -973,6 +978,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -1193,8 +1199,8 @@
         MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
 
         n++;
-        *p++ = (unsigned char)( ciphersuites[i] >> 8 );
-        *p++ = (unsigned char)( ciphersuites[i]      );
+        MBEDTLS_PUT_UINT16_BE( ciphersuites[i], p, 0 );
+        p += 2;
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3,
@@ -1209,8 +1215,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) );
         MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
-        *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
-        *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO      );
+        MBEDTLS_PUT_UINT16_BE( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO, p, 0 );
+        p += 2;
         n++;
     }
 
@@ -1221,8 +1227,8 @@
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
 
         MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
-        *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
-        *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE      );
+        MBEDTLS_PUT_UINT16_BE( MBEDTLS_SSL_FALLBACK_SCSV_VALUE, p, 0 );
+        p += 2;
         n++;
     }
 #endif
@@ -1428,9 +1434,8 @@
     {
         /* No need to check for space here, because the extension
          * writing functions already took care of that. */
-        *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
-        *p++ = (unsigned char)( ( ext_len      ) & 0xFF );
-        p += ext_len;
+        MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+        p += 2 + ext_len;
     }
 
     ssl->out_msglen  = p - buf;
@@ -1464,6 +1469,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
                                          size_t len )
@@ -1474,9 +1480,9 @@
         /* Check verify-data in constant-time. The length OTOH is no secret */
         if( len    != 1 + ssl->verify_data_len * 2 ||
             buf[0] !=     ssl->verify_data_len * 2 ||
-            mbedtls_ssl_safer_memcmp( buf + 1,
+            mbedtls_ct_memcmp( buf + 1,
                           ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
-            mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
+            mbedtls_ct_memcmp( buf + 1 + ssl->verify_data_len,
                           ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -1508,6 +1514,7 @@
 }
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
                                               const unsigned char *buf,
                                               size_t len )
@@ -1534,6 +1541,7 @@
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
                                          size_t len )
@@ -1559,6 +1567,7 @@
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
                               const unsigned char *buf,
                               size_t len )
@@ -1615,6 +1624,7 @@
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
                                          size_t len )
@@ -1641,6 +1651,7 @@
 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
                                          size_t len )
@@ -1667,6 +1678,7 @@
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
                                          size_t len )
@@ -1693,6 +1705,7 @@
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
                                                   const unsigned char *buf,
                                                   size_t len )
@@ -1738,6 +1751,7 @@
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
                                    const unsigned char *buf,
                                    size_t len )
@@ -1772,6 +1786,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_SSL_ALPN)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
                                const unsigned char *buf, size_t len )
 {
@@ -1842,6 +1857,7 @@
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                    const unsigned char *buf,
                                    size_t len )
@@ -1962,6 +1978,7 @@
  * Parse HelloVerifyRequest.  Only called after verifying the HS type.
  */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
 {
     const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
@@ -2045,6 +2062,7 @@
 }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
 {
     int ret, i;
@@ -2290,16 +2308,6 @@
     else
     {
         ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
-
-        if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
-            mbedtls_ssl_send_alert_message(
-                ssl,
-                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
-            return( ret );
-        }
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
@@ -2552,6 +2560,24 @@
     }
 
     /*
+     * mbedtls_ssl_derive_keys() has to be called after the parsing of the
+     * extensions. It sets the transform data for the resumed session which in
+     * case of DTLS includes the server CID extracted from the CID extension.
+     */
+    if( ssl->handshake->resume )
+    {
+        if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
+            mbedtls_ssl_send_alert_message(
+                ssl,
+                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+            return( ret );
+        }
+    }
+
+    /*
      * Renegotiation security checks
      */
     if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
@@ -2605,6 +2631,7 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl,
                                        unsigned char **p,
                                        unsigned char *end )
@@ -2651,6 +2678,7 @@
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
 {
     const mbedtls_ecp_curve_info *curve_info;
@@ -2692,6 +2720,7 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO) &&                           \
         ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||     \
           defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) )
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_server_ecdh_params_psa( mbedtls_ssl_context *ssl,
                                              unsigned char **p,
                                              unsigned char *end )
@@ -2717,6 +2746,10 @@
     tls_id <<= 8;
     tls_id |= *(*p)++;
 
+    /* Check it's a curve we offered */
+    if( mbedtls_ssl_check_curve_tls_id( ssl, tls_id ) != 0 )
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
     /* Convert EC group to PSA key type. */
     if( ( handshake->ecdh_psa_type =
           mbedtls_psa_parse_tls_ecc_group( tls_id, &ecdh_bits ) ) == 0 )
@@ -2754,6 +2787,7 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
                                          unsigned char **p,
                                          unsigned char *end )
@@ -2793,6 +2827,7 @@
           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
                                       unsigned char **p,
                                       unsigned char *end )
@@ -2839,6 +2874,7 @@
 /*
  * Generate a pre-master secret and encrypt it with the server's RSA key
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
                                     size_t offset, size_t *olen,
                                     size_t pms_offset )
@@ -2908,8 +2944,7 @@
     defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( len_bytes == 2 )
     {
-        ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
-        ssl->out_msg[offset+1] = (unsigned char)( *olen      );
+        MBEDTLS_PUT_UINT16_BE( *olen, ssl->out_msg, offset );
         *olen += 2;
     }
 #endif
@@ -2927,6 +2962,7 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
                                           unsigned char **p,
                                           unsigned char *end,
@@ -2993,6 +3029,7 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3011,6 +3048,8 @@
     peer_pk = &ssl->session_negotiate->peer_cert->pk;
 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 
+    /* 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 below. */
     if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
@@ -3044,6 +3083,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3162,7 +3202,7 @@
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
-    } /* FALLTROUGH */
+    } /* FALLTHROUGH */
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) ||                       \
@@ -3258,7 +3298,11 @@
     if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
     {
         size_t sig_len, hashlen;
-        unsigned char hash[64];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        unsigned char hash[PSA_HASH_MAX_SIZE];
+#else
+        unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+#endif
         mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
         mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
         unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
@@ -3446,6 +3490,7 @@
 }
 
 #if ! defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
 {
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@@ -3464,6 +3509,7 @@
     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
 }
 #else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3635,6 +3681,7 @@
 }
 #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3674,6 +3721,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3693,8 +3741,7 @@
          */
         content_len = ssl->handshake->dhm_ctx.len;
 
-        ssl->out_msg[4] = (unsigned char)( content_len >> 8 );
-        ssl->out_msg[5] = (unsigned char)( content_len      );
+        MBEDTLS_PUT_UINT16_BE( content_len, ssl->out_msg, 4 );
         header_len = 6;
 
         ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
@@ -3730,7 +3777,8 @@
     if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
     {
-        psa_status_t status;
+        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+        psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
         psa_key_attributes_t key_attributes;
 
         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@@ -3773,13 +3821,19 @@
                                         own_pubkey, sizeof( own_pubkey ),
                                         &own_pubkey_len );
         if( status != PSA_SUCCESS )
+        {
+            psa_destroy_key( handshake->ecdh_psa_privkey );
+            handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
 
         if( mbedtls_psa_tls_psa_ec_to_ecpoint( own_pubkey,
                                                own_pubkey_len,
                                                &own_pubkey_ecpoint,
                                                &own_pubkey_ecpoint_len ) != 0 )
         {
+            psa_destroy_key( handshake->ecdh_psa_privkey );
+            handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
         }
 
@@ -3799,13 +3853,12 @@
                                         ssl->handshake->premaster,
                                         sizeof( ssl->handshake->premaster ),
                                         &ssl->handshake->pmslen );
-        if( status != PSA_SUCCESS )
-            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
 
-        status = psa_destroy_key( handshake->ecdh_psa_privkey );
-        if( status != PSA_SUCCESS )
-            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        destruction_status = psa_destroy_key( handshake->ecdh_psa_privkey );
         handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
+
+        if( status != PSA_SUCCESS || destruction_status != PSA_SUCCESS )
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
     }
     else
 #endif /* MBEDTLS_USE_PSA_CRYPTO &&
@@ -3909,8 +3962,8 @@
             return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
         }
 
-        ssl->out_msg[header_len++] = (unsigned char)( content_len >> 8 );
-        ssl->out_msg[header_len++] = (unsigned char)( content_len      );
+        ssl->out_msg[header_len++] = MBEDTLS_BYTE_1( content_len );
+        ssl->out_msg[header_len++] = MBEDTLS_BYTE_0( content_len );
 
         memcpy( ssl->out_msg + header_len,
                 ssl->conf->psk_identity,
@@ -3930,7 +3983,10 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
             /* Opaque PSKs are currently only supported for PSK-only suites. */
             if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with RSA-PSK" ) );
                 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+            }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
             if( ( ret = ssl_write_encrypted_pms( ssl, header_len,
@@ -3945,7 +4001,10 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
             /* Opaque PSKs are currently only supported for PSK-only suites. */
             if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with DHE-PSK" ) );
                 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+            }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
             /*
@@ -3961,8 +4020,8 @@
                 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
             }
 
-            ssl->out_msg[header_len++] = (unsigned char)( content_len >> 8 );
-            ssl->out_msg[header_len++] = (unsigned char)( content_len      );
+            ssl->out_msg[header_len++] = MBEDTLS_BYTE_1( content_len );
+            ssl->out_msg[header_len++] = MBEDTLS_BYTE_0( content_len );
 
             ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
                     (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
@@ -3982,7 +4041,10 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
             /* Opaque PSKs are currently only supported for PSK-only suites. */
             if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with ECDHE-PSK" ) );
                 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+            }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
             /*
@@ -4092,6 +4154,7 @@
 }
 
 #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
 {
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@@ -4117,6 +4180,7 @@
     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
 }
 #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -4268,8 +4332,7 @@
         return( ret );
     }
 
-    ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
-    ssl->out_msg[5 + offset] = (unsigned char)( n      );
+    MBEDTLS_PUT_UINT16_BE( n, ssl->out_msg, offset + 4 );
 
     ssl->out_msglen  = 6 + n + offset;
     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@@ -4290,6 +4353,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
diff --git a/lib/libmbedtls/mbedtls/library/ssl_cookie.c b/lib/libmbedtls/mbedtls/library/ssl_cookie.c
index 69d1b32..3781796 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_cookie.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_cookie.c
@@ -36,6 +36,7 @@
 #include "mbedtls/ssl_internal.h"
 #include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -62,7 +63,7 @@
 
 /*
  * Cookies are formed of a 4-bytes timestamp (or serial number) and
- * an HMAC of timestemp and client ID.
+ * an HMAC of timestamp and client ID.
  */
 #define COOKIE_LEN      ( 4 + COOKIE_HMAC_LEN )
 
@@ -121,6 +122,7 @@
 /*
  * Generate the HMAC part of a cookie
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx,
                             const unsigned char time[4],
                             unsigned char **p, unsigned char *end,
@@ -166,10 +168,7 @@
     t = ctx->serial++;
 #endif
 
-    (*p)[0] = (unsigned char)( t >> 24 );
-    (*p)[1] = (unsigned char)( t >> 16 );
-    (*p)[2] = (unsigned char)( t >>  8 );
-    (*p)[3] = (unsigned char)( t       );
+    MBEDTLS_PUT_UINT32_BE(t, *p, 0);
     *p += 4;
 
 #if defined(MBEDTLS_THREADING_C)
@@ -220,15 +219,20 @@
 
 #if defined(MBEDTLS_THREADING_C)
     if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
-        return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR,
-                MBEDTLS_ERR_THREADING_MUTEX_ERROR ) );
+    {
+        ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR,
+                                 MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+    }
 #endif
 
     if( ret != 0 )
-        return( ret );
+        goto exit;
 
-    if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
-        return( -1 );
+    if( mbedtls_ct_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
+    {
+        ret = -1;
+        goto exit;
+    }
 
 #if defined(MBEDTLS_HAVE_TIME)
     cur_time = (unsigned long) mbedtls_time( NULL );
@@ -242,8 +246,13 @@
                   ( (unsigned long) cookie[3]       );
 
     if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout )
-        return( -1 );
+    {
+        ret = -1;
+        goto exit;
+    }
 
-    return( 0 );
+exit:
+    mbedtls_platform_zeroize( ref_hmac, sizeof( ref_hmac ) );
+    return( ret );
 }
 #endif /* MBEDTLS_SSL_COOKIE_C */
diff --git a/lib/libmbedtls/mbedtls/library/ssl_invasive.h b/lib/libmbedtls/mbedtls/library/ssl_invasive.h
deleted file mode 100644
index babbc27..0000000
--- a/lib/libmbedtls/mbedtls/library/ssl_invasive.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * \file ssl_invasive.h
- *
- * \brief SSL module: interfaces for invasive testing only.
- *
- * The interfaces in this file are intended for testing purposes only.
- * They SHOULD NOT be made available in library integrations except when
- * building the library for testing.
- */
-/*
- *  Copyright The Mbed TLS Contributors
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-#ifndef MBEDTLS_SSL_INVASIVE_H
-#define MBEDTLS_SSL_INVASIVE_H
-
-#include "common.h"
-#include "mbedtls/md.h"
-
-#if defined(MBEDTLS_TEST_HOOKS) &&              \
-    defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
-/** \brief Compute the HMAC of variable-length data with constant flow.
- *
- * This function computes the HMAC of the concatenation of \p add_data and \p
- * data, and does with a code flow and memory access pattern that does not
- * depend on \p data_len_secret, but only on \p min_data_len and \p
- * max_data_len. In particular, this function always reads exactly \p
- * max_data_len bytes from \p data.
- *
- * \param ctx               The HMAC context. It must have keys configured
- *                          with mbedtls_md_hmac_starts() and use one of the
- *                          following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
- *                          It is reset using mbedtls_md_hmac_reset() after
- *                          the computation is complete to prepare for the
- *                          next computation.
- * \param add_data          The additional data prepended to \p data. This
- *                          must point to a readable buffer of \p add_data_len
- *                          bytes.
- * \param add_data_len      The length of \p add_data in bytes.
- * \param data              The data appended to \p add_data. This must point
- *                          to a readable buffer of \p max_data_len bytes.
- * \param data_len_secret   The length of the data to process in \p data.
- *                          This must be no less than \p min_data_len and no
- *                          greater than \p max_data_len.
- * \param min_data_len      The minimal length of \p data in bytes.
- * \param max_data_len      The maximal length of \p data in bytes.
- * \param output            The HMAC will be written here. This must point to
- *                          a writable buffer of sufficient size to hold the
- *                          HMAC value.
- *
- * \retval 0
- *         Success.
- * \retval MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
- *         The hardware accelerator failed.
- */
-int mbedtls_ssl_cf_hmac(
-        mbedtls_md_context_t *ctx,
-        const unsigned char *add_data, size_t add_data_len,
-        const unsigned char *data, size_t data_len_secret,
-        size_t min_data_len, size_t max_data_len,
-        unsigned char *output );
-
-/** \brief Copy data from a secret position with constant flow.
- *
- * This function copies \p len bytes from \p src_base + \p offset_secret to \p
- * dst, with a code flow and memory access pattern that does not depend on \p
- * offset_secret, but only on \p offset_min, \p offset_max and \p len.
- *
- * \param dst           The destination buffer. This must point to a writable
- *                      buffer of at least \p len bytes.
- * \param src_base      The base of the source buffer. This must point to a
- *                      readable buffer of at least \p offset_max + \p len
- *                      bytes.
- * \param offset_secret The offset in the source buffer from which to copy.
- *                      This must be no less than \p offset_min and no greater
- *                      than \p offset_max.
- * \param offset_min    The minimal value of \p offset_secret.
- * \param offset_max    The maximal value of \p offset_secret.
- * \param len           The number of bytes to copy.
- */
-void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst,
-                                   const unsigned char *src_base,
-                                   size_t offset_secret,
-                                   size_t offset_min, size_t offset_max,
-                                   size_t len );
-#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
-
-#endif /* MBEDTLS_SSL_INVASIVE_H */
diff --git a/lib/libmbedtls/mbedtls/library/ssl_msg.c b/lib/libmbedtls/mbedtls/library/ssl_msg.c
index 1352b49..e47c538 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_msg.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_msg.c
@@ -44,8 +44,8 @@
 #include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/version.h"
-
-#include "ssl_invasive.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -91,6 +91,7 @@
 }
 
 #if defined(MBEDTLS_SSL_RECORD_CHECKING)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
                                     unsigned char *buf,
                                     size_t len,
@@ -165,11 +166,16 @@
 static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
                                      uint8_t slot );
 static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_buffer_message( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
                                      mbedtls_record const *rec );
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
 
 static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
@@ -187,6 +193,7 @@
     return( out_buf_len );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
 {
     size_t const bytes_written = ssl->out_left;
@@ -203,6 +210,7 @@
     return( (int) ( mtu - bytes_written ) );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -254,6 +262,7 @@
  * Double the retransmit timeout value, within the allowed range,
  * returning -1 if the maximum value has already been reached.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
 {
     uint32_t new_timeout;
@@ -353,6 +362,7 @@
  *  - A negative error code if `max_len` didn't offer enough space
  *    for the expansion.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_build_inner_plaintext( unsigned char *content,
                                       size_t *content_size,
                                       size_t remaining,
@@ -380,6 +390,7 @@
 
 /* This function parses a (D)TLSInnerPlaintext structure.
  * See ssl_build_inner_plaintext() for details. */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_inner_plaintext( unsigned char const *content,
                                           size_t *content_size,
                                           uint8_t *rec_type )
@@ -454,15 +465,13 @@
         *cur = rec->cid_len;
         cur++;
 
-        cur[0] = ( rec->data_len >> 8 ) & 0xFF;
-        cur[1] = ( rec->data_len >> 0 ) & 0xFF;
+        MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 );
         cur += 2;
     }
     else
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
     {
-        cur[0] = ( rec->data_len >> 8 ) & 0xFF;
-        cur[1] = ( rec->data_len >> 0 ) & 0xFF;
+        MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 );
         cur += 2;
     }
 
@@ -476,17 +485,19 @@
 /*
  * SSLv3.0 MAC functions
  */
-static void ssl_mac( mbedtls_md_context_t *md_ctx,
-                     const unsigned char *secret,
-                     const unsigned char *buf, size_t len,
-                     const unsigned char *ctr, int type,
-                     unsigned char out[SSL3_MAC_MAX_BYTES] )
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_mac( mbedtls_md_context_t *md_ctx,
+                    const unsigned char *secret,
+                    const unsigned char *buf, size_t len,
+                    const unsigned char *ctr, int type,
+                    unsigned char out[SSL3_MAC_MAX_BYTES] )
 {
     unsigned char header[11];
     unsigned char padding[48];
     int padlen;
     int md_size = mbedtls_md_get_size( md_ctx->md_info );
     int md_type = mbedtls_md_get_type( md_ctx->md_info );
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
     /* Only MD5 and SHA-1 supported */
     if( md_type == MBEDTLS_MD_MD5 )
@@ -495,30 +506,54 @@
         padlen = 40;
 
     memcpy( header, ctr, 8 );
-    header[ 8] = (unsigned char)  type;
-    header[ 9] = (unsigned char)( len >> 8 );
-    header[10] = (unsigned char)( len      );
+    header[8] = (unsigned char)  type;
+    MBEDTLS_PUT_UINT16_BE( len, header, 9);
 
     memset( padding, 0x36, padlen );
-    mbedtls_md_starts( md_ctx );
-    mbedtls_md_update( md_ctx, secret,  md_size );
-    mbedtls_md_update( md_ctx, padding, padlen  );
-    mbedtls_md_update( md_ctx, header,  11      );
-    mbedtls_md_update( md_ctx, buf,     len     );
-    mbedtls_md_finish( md_ctx, out              );
+    ret = mbedtls_md_starts( md_ctx );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_update( md_ctx, secret,  md_size );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_update( md_ctx, padding, padlen  );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_update( md_ctx, header,  11      );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_update( md_ctx, buf,     len     );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_finish( md_ctx, out              );
+    if( ret != 0 )
+        return( ret );
 
     memset( padding, 0x5C, padlen );
-    mbedtls_md_starts( md_ctx );
-    mbedtls_md_update( md_ctx, secret,    md_size );
-    mbedtls_md_update( md_ctx, padding,   padlen  );
-    mbedtls_md_update( md_ctx, out,       md_size );
-    mbedtls_md_finish( md_ctx, out                );
+    ret = mbedtls_md_starts( md_ctx );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_update( md_ctx, secret,    md_size );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_update( md_ctx, padding,   padlen  );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_update( md_ctx, out,       md_size );
+    if( ret != 0 )
+        return( ret );
+    ret = mbedtls_md_finish( md_ctx, out                );
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
 }
 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
 
 #if defined(MBEDTLS_GCM_C) || \
     defined(MBEDTLS_CCM_C) || \
     defined(MBEDTLS_CHACHAPOLY_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_transform_aead_dynamic_iv_is_explicit(
                                 mbedtls_ssl_transform const *transform )
 {
@@ -717,9 +752,17 @@
         if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
         {
             unsigned char mac[SSL3_MAC_MAX_BYTES];
-            ssl_mac( &transform->md_ctx_enc, transform->mac_enc,
-                     data, rec->data_len, rec->ctr, rec->type, mac );
-            memcpy( data + rec->data_len, mac, transform->maclen );
+            int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+            ret = ssl_mac( &transform->md_ctx_enc, transform->mac_enc,
+                           data, rec->data_len, rec->ctr, rec->type, mac );
+            if( ret == 0 )
+                memcpy( data + rec->data_len, mac, transform->maclen );
+            mbedtls_platform_zeroize( mac, transform->maclen );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
+                return( ret );
+            }
         }
         else
 #endif
@@ -728,18 +771,35 @@
         if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
         {
             unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+            int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
             ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
                                               transform->minor_ver );
 
-            mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
-                                    add_data_len );
-            mbedtls_md_hmac_update( &transform->md_ctx_enc,
-                                    data, rec->data_len );
-            mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
-            mbedtls_md_hmac_reset( &transform->md_ctx_enc );
+            ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+                                          add_data, add_data_len );
+            if( ret != 0 )
+                goto hmac_failed_etm_disabled;
+            ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+                                          data, rec->data_len );
+            if( ret != 0 )
+                goto hmac_failed_etm_disabled;
+            ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
+            if( ret != 0 )
+                goto hmac_failed_etm_disabled;
+            ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
+            if( ret != 0 )
+                goto hmac_failed_etm_disabled;
 
             memcpy( data + rec->data_len, mac, transform->maclen );
+
+        hmac_failed_etm_disabled:
+            mbedtls_platform_zeroize( mac, transform->maclen );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
+                return( ret );
+            }
         }
         else
 #endif
@@ -1012,18 +1072,34 @@
             MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
                                    add_data_len );
 
-            mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
-                                    add_data_len );
-            mbedtls_md_hmac_update( &transform->md_ctx_enc,
-                                    data, rec->data_len );
-            mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
-            mbedtls_md_hmac_reset( &transform->md_ctx_enc );
+            ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
+                                          add_data_len );
+            if( ret != 0 )
+                goto hmac_failed_etm_enabled;
+            ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+                                          data, rec->data_len );
+            if( ret != 0 )
+                goto hmac_failed_etm_enabled;
+            ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
+            if( ret != 0 )
+                goto hmac_failed_etm_enabled;
+            ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
+            if( ret != 0 )
+                goto hmac_failed_etm_enabled;
 
             memcpy( data + rec->data_len, mac, transform->maclen );
 
             rec->data_len += transform->maclen;
             post_avail -= transform->maclen;
             auth_done++;
+
+        hmac_failed_etm_enabled:
+            mbedtls_platform_zeroize( mac, transform->maclen );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
+                return( ret );
+            }
         }
 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
     }
@@ -1046,242 +1122,6 @@
     return( 0 );
 }
 
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
-/*
- * Turn a bit into a mask:
- * - if bit == 1, return the all-bits 1 mask, aka (size_t) -1
- * - if bit == 0, return the all-bits 0 mask, aka 0
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations using masks.
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_ssl_cf_mask_from_bit( size_t bit )
-{
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-    return -bit;
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-}
-
-/*
- * Constant-flow mask generation for "less than" comparison:
- * - if x < y,  return all bits 1, that is (size_t) -1
- * - otherwise, return all bits 0, that is 0
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations using masks.
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_ssl_cf_mask_lt( size_t x, size_t y )
-{
-    /* This has the most significant bit set if and only if x < y */
-    const size_t sub = x - y;
-
-    /* sub1 = (x < y) ? 1 : 0 */
-    const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 );
-
-    /* mask = (x < y) ? 0xff... : 0x00... */
-    const size_t mask = mbedtls_ssl_cf_mask_from_bit( sub1 );
-
-    return( mask );
-}
-
-/*
- * Constant-flow mask generation for "greater or equal" comparison:
- * - if x >= y, return all bits 1, that is (size_t) -1
- * - otherwise, return all bits 0, that is 0
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations using masks.
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_ssl_cf_mask_ge( size_t x, size_t y )
-{
-    return( ~mbedtls_ssl_cf_mask_lt( x, y ) );
-}
-
-/*
- * Constant-flow boolean "equal" comparison:
- * return x == y
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations - it can be used in conjunction with
- * mbedtls_ssl_cf_mask_from_bit().
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_ssl_cf_bool_eq( size_t x, size_t y )
-{
-    /* diff = 0 if x == y, non-zero otherwise */
-    const size_t diff = x ^ y;
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* diff_msb's most significant bit is equal to x != y */
-    const size_t diff_msb = ( diff | -diff );
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    /* diff1 = (x != y) ? 1 : 0 */
-    const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
-
-    return( 1 ^ diff1 );
-}
-
-/*
- * Constant-flow conditional memcpy:
- *  - if c1 == c2, equivalent to memcpy(dst, src, len),
- *  - otherwise, a no-op,
- * but with execution flow independent of the values of c1 and c2.
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst,
-                                         const unsigned char *src,
-                                         size_t len,
-                                         size_t c1, size_t c2 )
-{
-    /* mask = c1 == c2 ? 0xff : 0x00 */
-    const size_t equal = mbedtls_ssl_cf_bool_eq( c1, c2 );
-    const unsigned char mask = (unsigned char) mbedtls_ssl_cf_mask_from_bit( equal );
-
-    /* dst[i] = c1 == c2 ? src[i] : dst[i] */
-    for( size_t i = 0; i < len; i++ )
-        dst[i] = ( src[i] & mask ) | ( dst[i] & ~mask );
-}
-
-/*
- * Compute HMAC of variable-length data with constant flow.
- *
- * Only works with MD-5, SHA-1, SHA-256 and SHA-384.
- * (Otherwise, computation of block_size needs to be adapted.)
- */
-MBEDTLS_STATIC_TESTABLE int mbedtls_ssl_cf_hmac(
-        mbedtls_md_context_t *ctx,
-        const unsigned char *add_data, size_t add_data_len,
-        const unsigned char *data, size_t data_len_secret,
-        size_t min_data_len, size_t max_data_len,
-        unsigned char *output )
-{
-    /*
-     * This function breaks the HMAC abstraction and uses the md_clone()
-     * extension to the MD API in order to get constant-flow behaviour.
-     *
-     * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
-     * concatenation, and okey/ikey are the XOR of the key with some fixed bit
-     * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
-     *
-     * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
-     * minlen, then cloning the context, and for each byte up to maxlen
-     * finishing up the hash computation, keeping only the correct result.
-     *
-     * Then we only need to compute HASH(okey + inner_hash) and we're done.
-     */
-    const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info );
-    /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5,
-     * all of which have the same block size except SHA-384. */
-    const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
-    const unsigned char * const ikey = ctx->hmac_ctx;
-    const unsigned char * const okey = ikey + block_size;
-    const size_t hash_size = mbedtls_md_get_size( ctx->md_info );
-
-    unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
-    mbedtls_md_context_t aux;
-    size_t offset;
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
-    mbedtls_md_init( &aux );
-
-#define MD_CHK( func_call ) \
-    do {                    \
-        ret = (func_call);  \
-        if( ret != 0 )      \
-            goto cleanup;   \
-    } while( 0 )
-
-    MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) );
-
-    /* After hmac_start() of hmac_reset(), ikey has already been hashed,
-     * so we can start directly with the message */
-    MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
-    MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
-
-    /* For each possible length, compute the hash up to that point */
-    for( offset = min_data_len; offset <= max_data_len; offset++ )
-    {
-        MD_CHK( mbedtls_md_clone( &aux, ctx ) );
-        MD_CHK( mbedtls_md_finish( &aux, aux_out ) );
-        /* Keep only the correct inner_hash in the output buffer */
-        mbedtls_ssl_cf_memcpy_if_eq( output, aux_out, hash_size,
-                                     offset, data_len_secret );
-
-        if( offset < max_data_len )
-            MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
-    }
-
-    /* The context needs to finish() before it starts() again */
-    MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
-
-    /* Now compute HASH(okey + inner_hash) */
-    MD_CHK( mbedtls_md_starts( ctx ) );
-    MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
-    MD_CHK( mbedtls_md_update( ctx, output, hash_size ) );
-    MD_CHK( mbedtls_md_finish( ctx, output ) );
-
-    /* Done, get ready for next time */
-    MD_CHK( mbedtls_md_hmac_reset( ctx ) );
-
-#undef MD_CHK
-
-cleanup:
-    mbedtls_md_free( &aux );
-    return( ret );
-}
-
-/*
- * Constant-flow memcpy from variable position in buffer.
- * - functionally equivalent to memcpy(dst, src + offset_secret, len)
- * - but with execution flow independent from the value of offset_secret.
- */
-MBEDTLS_STATIC_TESTABLE void mbedtls_ssl_cf_memcpy_offset(
-                                   unsigned char *dst,
-                                   const unsigned char *src_base,
-                                   size_t offset_secret,
-                                   size_t offset_min, size_t offset_max,
-                                   size_t len )
-{
-    size_t offset;
-
-    for( offset = offset_min; offset <= offset_max; offset++ )
-    {
-        mbedtls_ssl_cf_memcpy_if_eq( dst, src_base + offset, len,
-                                     offset, offset_secret );
-    }
-}
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
-
 int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
                              mbedtls_ssl_transform *transform,
                              mbedtls_record *rec )
@@ -1418,7 +1258,7 @@
                                add_data, add_data_len );
 
         /* Because of the check above, we know that there are
-         * explicit_iv_len Bytes preceeding data, and taglen
+         * explicit_iv_len Bytes preceding data, and taglen
          * bytes following data + data_len. This justifies
          * the debug message and the invocation of
          * mbedtls_cipher_auth_decrypt() below. */
@@ -1521,7 +1361,7 @@
              *
              * Afterwards, we know that data + data_len is followed by at
              * least maclen Bytes, which justifies the call to
-             * mbedtls_ssl_safer_memcmp() below.
+             * mbedtls_ct_memcmp() below.
              *
              * Further, we still know that data_len > minlen */
             rec->data_len -= transform->maclen;
@@ -1531,12 +1371,20 @@
             /* Calculate expected MAC. */
             MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
                                    add_data_len );
-            mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
-                                    add_data_len );
-            mbedtls_md_hmac_update( &transform->md_ctx_dec,
+            ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
+                                          add_data_len );
+            if( ret != 0 )
+                goto hmac_failed_etm_enabled;
+            ret = mbedtls_md_hmac_update( &transform->md_ctx_dec,
                                     data, rec->data_len );
-            mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
-            mbedtls_md_hmac_reset( &transform->md_ctx_dec );
+            if( ret != 0 )
+                goto hmac_failed_etm_enabled;
+            ret = mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
+            if( ret != 0 )
+                goto hmac_failed_etm_enabled;
+            ret = mbedtls_md_hmac_reset( &transform->md_ctx_dec );
+            if( ret != 0 )
+                goto hmac_failed_etm_enabled;
 
             MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", data + rec->data_len,
                                    transform->maclen );
@@ -1544,13 +1392,23 @@
                                    transform->maclen );
 
             /* Compare expected MAC with MAC at the end of the record. */
-            if( mbedtls_ssl_safer_memcmp( data + rec->data_len, mac_expect,
-                                          transform->maclen ) != 0 )
+            if( mbedtls_ct_memcmp( data + rec->data_len, mac_expect,
+                                              transform->maclen ) != 0 )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
-                return( MBEDTLS_ERR_SSL_INVALID_MAC );
+                ret = MBEDTLS_ERR_SSL_INVALID_MAC;
+                goto hmac_failed_etm_enabled;
             }
             auth_done++;
+
+        hmac_failed_etm_enabled:
+            mbedtls_platform_zeroize( mac_expect, transform->maclen );
+            if( ret != 0 )
+            {
+                if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
+                    MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret );
+                return( ret );
+            }
         }
 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
 
@@ -1623,7 +1481,7 @@
 
         if( auth_done == 1 )
         {
-            const size_t mask = mbedtls_ssl_cf_mask_ge(
+            const size_t mask = mbedtls_ct_size_mask_ge(
                                 rec->data_len,
                                 padlen + 1 );
             correct &= mask;
@@ -1643,7 +1501,7 @@
             }
 #endif
 
-            const size_t mask = mbedtls_ssl_cf_mask_ge(
+            const size_t mask = mbedtls_ct_size_mask_ge(
                                 rec->data_len,
                                 transform->maclen + padlen + 1 );
             correct &= mask;
@@ -1699,18 +1557,18 @@
                 /* pad_count += (idx >= padding_idx) &&
                  *              (check[idx] == padlen - 1);
                  */
-                const size_t mask = mbedtls_ssl_cf_mask_ge( idx, padding_idx );
-                const size_t equal = mbedtls_ssl_cf_bool_eq( check[idx],
-                                                             padlen - 1 );
+                const size_t mask = mbedtls_ct_size_mask_ge( idx, padding_idx );
+                const size_t equal = mbedtls_ct_size_bool_eq( check[idx],
+                                                              padlen - 1 );
                 pad_count += mask & equal;
             }
-            correct &= mbedtls_ssl_cf_bool_eq( pad_count, padlen );
+            correct &= mbedtls_ct_size_bool_eq( pad_count, padlen );
 
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
             if( padlen > 0 && correct == 0 )
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
 #endif
-            padlen &= mbedtls_ssl_cf_mask_from_bit( correct );
+            padlen &= mbedtls_ct_size_mask( correct );
         }
         else
 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
@@ -1745,8 +1603,8 @@
 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
     if( auth_done == 0 )
     {
-        unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
-        unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
+        unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 };
+        unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 };
 
         /* If the initial value of padlen was such that
          * data_len < maclen + padlen + 1, then padlen
@@ -1768,11 +1626,16 @@
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
         if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
         {
-            ssl_mac( &transform->md_ctx_dec,
-                     transform->mac_dec,
-                     data, rec->data_len,
-                     rec->ctr, rec->type,
-                     mac_expect );
+            ret = ssl_mac( &transform->md_ctx_dec,
+                           transform->mac_dec,
+                           data, rec->data_len,
+                           rec->ctr, rec->type,
+                           mac_expect );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
+                goto hmac_failed_etm_disabled;
+            }
             memcpy( mac_peer, data + rec->data_len, transform->maclen );
         }
         else
@@ -1794,20 +1657,20 @@
             const size_t max_len = rec->data_len + padlen;
             const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
 
-            ret = mbedtls_ssl_cf_hmac( &transform->md_ctx_dec,
-                                       add_data, add_data_len,
-                                       data, rec->data_len, min_len, max_len,
-                                       mac_expect );
+            ret = mbedtls_ct_hmac( &transform->md_ctx_dec,
+                                   add_data, add_data_len,
+                                   data, rec->data_len, min_len, max_len,
+                                   mac_expect );
             if( ret != 0 )
             {
-                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret );
-                return( ret );
+                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret );
+                goto hmac_failed_etm_disabled;
             }
 
-            mbedtls_ssl_cf_memcpy_offset( mac_peer, data,
-                                          rec->data_len,
-                                          min_len, max_len,
-                                          transform->maclen );
+            mbedtls_ct_memcpy_offset( mac_peer, data,
+                                      rec->data_len,
+                                      min_len, max_len,
+                                      transform->maclen );
         }
         else
 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
@@ -1822,8 +1685,8 @@
         MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", mac_peer, transform->maclen );
 #endif
 
-        if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect,
-                                      transform->maclen ) != 0 )
+        if( mbedtls_ct_memcmp( mac_peer, mac_expect,
+                                          transform->maclen ) != 0 )
         {
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
@@ -1831,6 +1694,12 @@
             correct = 0;
         }
         auth_done++;
+
+    hmac_failed_etm_disabled:
+        mbedtls_platform_zeroize( mac_peer, transform->maclen );
+        mbedtls_platform_zeroize( mac_expect, transform->maclen );
+        if( ret != 0 )
+            return( ret );
     }
 
     /*
@@ -1882,6 +1751,7 @@
 /*
  * Compression/decompression functions
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_compress_buf( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -1934,6 +1804,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -2293,6 +2164,7 @@
 /*
  * Append current handshake message to current outgoing flight
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_flight_append( mbedtls_ssl_context *ssl )
 {
     mbedtls_ssl_flight_item *msg;
@@ -2359,6 +2231,7 @@
 /*
  * Swap transform_out and out_ctr with the alternative ones
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
 {
     mbedtls_ssl_transform *tmp_transform;
@@ -2526,13 +2399,13 @@
              * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
             memcpy( ssl->out_msg, cur->p, 6 );
 
-            ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff );
-            ssl->out_msg[7] = ( ( frag_off >>  8 ) & 0xff );
-            ssl->out_msg[8] = ( ( frag_off       ) & 0xff );
+            ssl->out_msg[6] = MBEDTLS_BYTE_2( frag_off );
+            ssl->out_msg[7] = MBEDTLS_BYTE_1( frag_off );
+            ssl->out_msg[8] = MBEDTLS_BYTE_0( frag_off );
 
-            ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff );
-            ssl->out_msg[10] = ( ( cur_hs_frag_len >>  8 ) & 0xff );
-            ssl->out_msg[11] = ( ( cur_hs_frag_len       ) & 0xff );
+            ssl->out_msg[ 9] = MBEDTLS_BYTE_2( cur_hs_frag_len );
+            ssl->out_msg[10] = MBEDTLS_BYTE_1( cur_hs_frag_len );
+            ssl->out_msg[11] = MBEDTLS_BYTE_0( cur_hs_frag_len );
 
             MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
 
@@ -2729,9 +2602,9 @@
      */
     if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
     {
-        ssl->out_msg[1] = (unsigned char)( hs_len >> 16 );
-        ssl->out_msg[2] = (unsigned char)( hs_len >>  8 );
-        ssl->out_msg[3] = (unsigned char)( hs_len       );
+        ssl->out_msg[1] = MBEDTLS_BYTE_2( hs_len );
+        ssl->out_msg[2] = MBEDTLS_BYTE_1( hs_len );
+        ssl->out_msg[3] = MBEDTLS_BYTE_0( hs_len );
 
         /*
          * DTLS has additional fields in the Handshake layer,
@@ -2759,8 +2632,7 @@
             /* Write message_seq and update it, except for HelloRequest */
             if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
             {
-                ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
-                ssl->out_msg[5] = ( ssl->handshake->out_msg_seq      ) & 0xFF;
+                MBEDTLS_PUT_UINT16_BE( ssl->handshake->out_msg_seq, ssl->out_msg, 4 );
                 ++( ssl->handshake->out_msg_seq );
             }
             else
@@ -2874,8 +2746,7 @@
                            ssl->conf->transport, ssl->out_hdr + 1 );
 
         memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
-        ssl->out_len[0] = (unsigned char)( len >> 8 );
-        ssl->out_len[1] = (unsigned char)( len      );
+        MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0);
 
         if( ssl->transform_out != NULL )
         {
@@ -2915,8 +2786,7 @@
             memcpy( ssl->out_cid, rec.cid, rec.cid_len );
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
             ssl->out_msglen = len = rec.data_len;
-            ssl->out_len[0] = (unsigned char)( rec.data_len >> 8 );
-            ssl->out_len[1] = (unsigned char)( rec.data_len      );
+            MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->out_len, 0 );
         }
 
         protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl );
@@ -3004,6 +2874,7 @@
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
 {
     if( ssl->in_msglen < ssl->in_hslen ||
@@ -3029,6 +2900,7 @@
               ssl->in_msg[8] );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
 {
     uint32_t msg_len, frag_off, frag_len;
@@ -3095,6 +2967,7 @@
 /*
  * Check that bitmask is full
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_bitmask_check( unsigned char *mask, size_t len )
 {
     size_t i;
@@ -3294,6 +3167,7 @@
             ( (uint64_t) buf[5]       ) );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3376,8 +3250,8 @@
 
 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
 /*
- * Without any SSL context, check if a datagram looks like a ClientHello with
- * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
+ * Check if a datagram looks like a ClientHello with a valid cookie,
+ * and if it doesn't, generate a HelloVerifyRequest message.
  * Both input and output include full DTLS headers.
  *
  * - if cookie is valid, return 0
@@ -3386,10 +3260,10 @@
  *   return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
  * - otherwise return a specific error code
  */
-static int ssl_check_dtls_clihlo_cookie(
-                           mbedtls_ssl_cookie_write_t *f_cookie_write,
-                           mbedtls_ssl_cookie_check_t *f_cookie_check,
-                           void *p_cookie,
+MBEDTLS_CHECK_RETURN_CRITICAL
+MBEDTLS_STATIC_TESTABLE
+int mbedtls_ssl_check_dtls_clihlo_cookie(
+                           mbedtls_ssl_context *ssl,
                            const unsigned char *cli_id, size_t cli_id_len,
                            const unsigned char *in, size_t in_len,
                            unsigned char *obuf, size_t buf_len, size_t *olen )
@@ -3423,26 +3297,53 @@
      *
      * Minimum length is 61 bytes.
      */
-    if( in_len < 61 ||
-        in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
+    MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: in_len=%u",
+                                (unsigned) in_len ) );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "cli_id", cli_id, cli_id_len );
+    if( in_len < 61 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: record too short" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+    if( in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
         in[3] != 0 || in[4] != 0 ||
         in[19] != 0 || in[20] != 0 || in[21] != 0 )
     {
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: not a good ClientHello" ) );
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "    type=%u epoch=%u fragment_offset=%u",
+                                    in[0],
+                                    (unsigned) in[3] << 8 | in[4],
+                                    (unsigned) in[19] << 16 | in[20] << 8 | in[21] ) );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
     sid_len = in[59];
-    if( sid_len > in_len - 61 )
+    if( 59 + 1 + sid_len + 1 > in_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: sid_len=%u > %u",
+                                    (unsigned) sid_len,
+                                    (unsigned) in_len - 61 ) );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+    MBEDTLS_SSL_DEBUG_BUF( 4, "sid received from network",
+                           in + 60, sid_len );
 
     cookie_len = in[60 + sid_len];
-    if( cookie_len > in_len - 60 )
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
-
-    if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
-                        cli_id, cli_id_len ) == 0 )
+    if( 59 + 1 + sid_len + 1 + cookie_len > in_len )
     {
-        /* Valid cookie */
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: cookie_len=%u > %u",
+                                    (unsigned) cookie_len,
+                                    (unsigned) ( in_len - sid_len - 61 ) ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "cookie received from network",
+                           in + sid_len + 61, cookie_len );
+    if( ssl->conf->f_cookie_check( ssl->conf->p_cookie,
+                                   in + sid_len + 61, cookie_len,
+                                   cli_id, cli_id_len ) == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: valid" ) );
         return( 0 );
     }
 
@@ -3477,8 +3378,9 @@
 
     /* Generate and write actual cookie */
     p = obuf + 28;
-    if( f_cookie_write( p_cookie,
-                        &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
+    if( ssl->conf->f_cookie_write( ssl->conf->p_cookie,
+                                   &p, obuf + buf_len,
+                                   cli_id, cli_id_len ) != 0 )
     {
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
     }
@@ -3488,12 +3390,11 @@
     /* Go back and fill length fields */
     obuf[27] = (unsigned char)( *olen - 28 );
 
-    obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 );
-    obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >>  8 );
-    obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 )       );
+    obuf[14] = obuf[22] = MBEDTLS_BYTE_2( *olen - 25 );
+    obuf[15] = obuf[23] = MBEDTLS_BYTE_1( *olen - 25 );
+    obuf[16] = obuf[24] = MBEDTLS_BYTE_0( *olen - 25 );
 
-    obuf[11] = (unsigned char)( ( *olen - 13 ) >>  8 );
-    obuf[12] = (unsigned char)( ( *olen - 13 )       );
+    MBEDTLS_PUT_UINT16_BE( *olen - 13, obuf, 11 );
 
     return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
 }
@@ -3518,6 +3419,7 @@
  * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
  * errors, and is the right thing to do in both cases).
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3533,15 +3435,13 @@
         return( 0 );
     }
 
-    ret = ssl_check_dtls_clihlo_cookie(
-            ssl->conf->f_cookie_write,
-            ssl->conf->f_cookie_check,
-            ssl->conf->p_cookie,
+    ret = mbedtls_ssl_check_dtls_clihlo_cookie(
+            ssl,
             ssl->cli_id, ssl->cli_id_len,
             ssl->in_buf, ssl->in_left,
             ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
 
-    MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
+    MBEDTLS_SSL_DEBUG_RET( 2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret );
 
     if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
     {
@@ -3575,6 +3475,7 @@
 }
 #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_record_type( uint8_t record_type )
 {
     if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
@@ -3607,6 +3508,7 @@
  * Point 2 is needed when the peer is resending, and we have already received
  * the first record from a datagram but are still waiting for the others.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
                                     unsigned char *buf,
                                     size_t len,
@@ -3719,7 +3621,6 @@
     /*
      * Parse and validate record version
      */
-
     rec->ver[0] = buf[ rec_hdr_version_offset + 0 ];
     rec->ver[1] = buf[ rec_hdr_version_offset + 1 ];
     mbedtls_ssl_read_version( &major_ver, &minor_ver,
@@ -3728,16 +3629,19 @@
 
     if( major_ver != ssl->major_ver )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch: got %u, expected %u",
+                                    (unsigned) major_ver,
+                                    (unsigned) ssl->major_ver ) );
         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
     }
 
     if( minor_ver > ssl->conf->max_minor_ver )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch: got %u, expected max %u",
+                                    (unsigned) minor_ver,
+                                    (unsigned) ssl->conf->max_minor_ver ) );
         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
     }
-
     /*
      * Parse/Copy record sequence number.
      */
@@ -3840,6 +3744,7 @@
 
 
 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl )
 {
     unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
@@ -3869,6 +3774,7 @@
 /*
  * If applicable, decrypt record content
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
                                        mbedtls_record *rec )
 {
@@ -4002,7 +3908,7 @@
 
     /* Check actual (decrypted) record content length against
      * configured maximum. */
-    if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
+    if( rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
@@ -4020,8 +3926,11 @@
  */
 
 /* Helper functions for mbedtls_ssl_read_record(). */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_get_next_record( mbedtls_ssl_context *ssl );
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
 
 int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
@@ -4109,6 +4018,7 @@
 }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
 {
     if( ssl->in_left > ssl->next_record_offset )
@@ -4117,6 +4027,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
 {
     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
@@ -4214,6 +4125,7 @@
     return( ret );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
                                   size_t desired )
 {
@@ -4256,6 +4168,7 @@
     return( -1 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_buffer_message( mbedtls_ssl_context *ssl )
 {
     int ret = 0;
@@ -4460,6 +4373,7 @@
 }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
 {
     /*
@@ -4547,6 +4461,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
 {
     if( ssl->in_msglen > 0 )
@@ -4573,6 +4488,7 @@
     }
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
 {
     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
@@ -4630,6 +4546,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
                                      mbedtls_record const *rec )
 {
@@ -4688,6 +4605,7 @@
 
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_get_next_record( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -4891,8 +4809,7 @@
     ssl->in_hdr[0] = rec.type;
     ssl->in_msg    = rec.buf + rec.data_offset;
     ssl->in_msglen = rec.data_len;
-    ssl->in_len[0] = (unsigned char)( rec.data_len >> 8 );
-    ssl->in_len[1] = (unsigned char)( rec.data_len      );
+    MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->in_len, 0 );
 
 #if defined(MBEDTLS_ZLIB_SUPPORT)
     if( ssl->transform_in != NULL &&
@@ -5067,6 +4984,9 @@
     if( ssl == NULL || ssl->conf == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
+    if( ssl->out_left != 0 )
+        return( mbedtls_ssl_flush_output( ssl ) );
+
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
 
@@ -5436,6 +5356,7 @@
 /*
  * Check record counters and renegotiate if they're above the limit.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
 {
     size_t ep_len = mbedtls_ssl_ep_len( ssl );
@@ -5786,6 +5707,7 @@
  * Therefore, it is possible that the input message length is 0 and the
  * corresponding return code is 0 on success.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_real( mbedtls_ssl_context *ssl,
                            const unsigned char *buf, size_t len )
 {
@@ -5857,6 +5779,7 @@
  * remember whether we already did the split or not.
  */
 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_split( mbedtls_ssl_context *ssl,
                             const unsigned char *buf, size_t len )
 {
@@ -5939,9 +5862,6 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
 
-    if( ssl->out_left != 0 )
-        return( mbedtls_ssl_flush_output( ssl ) );
-
     if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
     {
         if( ( ret = mbedtls_ssl_send_alert_message( ssl,
diff --git a/lib/libmbedtls/mbedtls/library/ssl_srv.c b/lib/libmbedtls/mbedtls/library/ssl_srv.c
index aca871e..2efb13c 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_srv.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_srv.c
@@ -34,6 +34,8 @@
 #include "mbedtls/debug.h"
 #include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -76,6 +78,7 @@
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
                                      const unsigned char *buf,
                                      size_t len )
@@ -145,6 +148,7 @@
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf )
 {
     if( conf->f_psk != NULL )
@@ -165,6 +169,7 @@
 }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
 {
     if( ssl->conf->f_psk != NULL )
@@ -186,6 +191,7 @@
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
                                          size_t len )
@@ -196,7 +202,7 @@
         /* Check verify-data in constant-time. The length OTOH is no secret */
         if( len    != 1 + ssl->verify_data_len ||
             buf[0] !=     ssl->verify_data_len ||
-            mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data,
+            mbedtls_ct_memcmp( buf + 1, ssl->peer_verify_data,
                           ssl->verify_data_len ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -237,6 +243,7 @@
  * This needs to be done at a later stage.
  *
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
                                                const unsigned char *buf,
                                                size_t len )
@@ -315,6 +322,7 @@
 
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
                                                 const unsigned char *buf,
                                                 size_t len )
@@ -381,6 +389,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
                                               const unsigned char *buf,
                                               size_t len )
@@ -423,6 +432,7 @@
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
                                    const unsigned char *buf,
                                    size_t len )
@@ -452,6 +462,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
                                               const unsigned char *buf,
                                               size_t len )
@@ -471,6 +482,7 @@
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
                               const unsigned char *buf,
                               size_t len )
@@ -543,6 +555,7 @@
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
                                          const unsigned char *buf,
                                          size_t len )
@@ -565,6 +578,7 @@
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
                                       const unsigned char *buf,
                                       size_t len )
@@ -590,6 +604,7 @@
 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
                                       const unsigned char *buf,
                                       size_t len )
@@ -615,6 +630,7 @@
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
                                          unsigned char *buf,
                                          size_t len )
@@ -689,6 +705,7 @@
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
 #if defined(MBEDTLS_SSL_ALPN)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
                                const unsigned char *buf, size_t len )
 {
@@ -777,6 +794,7 @@
 #endif /* MBEDTLS_SSL_ALPN */
 
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
                                    const unsigned char *buf,
                                    size_t len )
@@ -905,6 +923,7 @@
  * Return 0 if the given key uses one of the acceptable curves, -1 otherwise
  */
 #if defined(MBEDTLS_ECDSA_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_key_curve( mbedtls_pk_context *pk,
                                 const mbedtls_ecp_curve_info **curves )
 {
@@ -926,6 +945,7 @@
  * Try picking a certificate for this ciphersuite,
  * return 0 on success and -1 on failure.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_pick_cert( mbedtls_ssl_context *ssl,
                           const mbedtls_ssl_ciphersuite_t * ciphersuite_info )
 {
@@ -1030,6 +1050,7 @@
  * Check if a given ciphersuite is suitable for use with our config/keys/etc
  * Sets ciphersuite_info only if the suite matches.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
                                   const mbedtls_ssl_ciphersuite_t **ciphersuite_info )
 {
@@ -1145,6 +1166,7 @@
 }
 
 #if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
 {
     int ret, got_common_suite;
@@ -1322,8 +1344,7 @@
     for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
     {
         if( p[0] == 0 &&
-            p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
-            p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE      ) & 0xff ) )
+            MBEDTLS_GET_UINT16_BE(p, 1) != MBEDTLS_SSL_FALLBACK_SCSV_VALUE )
         {
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) );
 
@@ -1354,8 +1375,7 @@
 #endif
         {
             if( p[0] != 0 ||
-                p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
-                p[2] != ( ( ciphersuites[i]      ) & 0xFF ) )
+                MBEDTLS_GET_UINT16_BE(p, 1) != ciphersuites[i] )
                 continue;
 
             got_common_suite = 1;
@@ -1410,6 +1430,7 @@
 /* This function doesn't alert on errors that happen early during
    ClientHello parsing because they might indicate that the client is
    not talking SSL/TLS at all and would not understand our alert. */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
 {
     int ret, got_common_suite;
@@ -1583,7 +1604,7 @@
      * Handshake layer:
      *     0  .   0   handshake type
      *     1  .   3   handshake length
-     *     4  .   5   DTLS only: message seqence number
+     *     4  .   5   DTLS only: message sequence number
      *     6  .   8   DTLS only: fragment offset
      *     9  .  11   DTLS only: fragment length
      */
@@ -1604,11 +1625,19 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d",
                    ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) );
 
-    /* We don't support fragmentation of ClientHello (yet?) */
-    if( buf[1] != 0 ||
-        msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) )
+    if( buf[1] != 0 )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message: %u != 0",
+                                    (unsigned) buf[1] ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+    /* We don't support fragmentation of ClientHello (yet?) */
+    if( msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message: %u != %u + %u",
+                                    (unsigned) msg_len,
+                                    (unsigned) mbedtls_ssl_hs_hdr_len( ssl ),
+                                    (unsigned) ( buf[2] << 8 ) | buf[3] ) );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -1649,6 +1678,11 @@
          * For now we don't support fragmentation, so make sure
          * fragment_offset == 0 and fragment_length == length
          */
+        MBEDTLS_SSL_DEBUG_MSG(
+            4, ( "fragment_offset=%u fragment_length=%u length=%u",
+                 (unsigned) ( ssl->in_msg[6] << 16 | ssl->in_msg[7] << 8 | ssl->in_msg[8] ),
+                 (unsigned) ( ssl->in_msg[9] << 16 | ssl->in_msg[10] << 8 | ssl->in_msg[11] ),
+                 (unsigned) ( ssl->in_msg[1] << 16 | ssl->in_msg[2] << 8 | ssl->in_msg[3] ) ) );
         if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 ||
             memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 )
         {
@@ -2086,8 +2120,7 @@
 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
     for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 )
     {
-        if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
-            p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE      ) & 0xff ) )
+        if( MBEDTLS_GET_UINT16_BE( p, 0 ) == MBEDTLS_SSL_FALLBACK_SCSV_VALUE )
         {
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) );
 
@@ -2205,8 +2238,7 @@
         for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
 #endif
         {
-            if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
-                p[1] != ( ( ciphersuites[i]      ) & 0xFF ) )
+            if( MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i] )
                 continue;
 
             got_common_suite = 1;
@@ -2290,8 +2322,8 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_TRUNCATED_HMAC, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 0x00;
@@ -2334,12 +2366,11 @@
      *      opaque cid<0..2^8-1>;
      *   } ConnectionId;
     */
-
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_CID, p, 0 );
+    p += 2;
     ext_len = (size_t) ssl->own_cid_len + 1;
-    *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ext_len      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+    p += 2;
 
     *p++ = (uint8_t) ssl->own_cid_len;
     memcpy( p, ssl->own_cid, ssl->own_cid_len );
@@ -2357,12 +2388,8 @@
     const mbedtls_ssl_ciphersuite_t *suite = NULL;
     const mbedtls_cipher_info_t *cipher = NULL;
 
-    if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
-        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
-    {
-        *olen = 0;
-        return;
-    }
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
 
     /*
      * RFC 7366: "If a server receives an encrypt-then-MAC request extension
@@ -2375,14 +2402,19 @@
         ( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL ||
         cipher->mode != MBEDTLS_MODE_CBC )
     {
+        ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
+    }
+
+    if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED )
+    {
         *olen = 0;
         return;
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 0x00;
@@ -2408,8 +2440,8 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret "
                         "extension" ) );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 0x00;
@@ -2433,8 +2465,8 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 0x00;
@@ -2457,8 +2489,8 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0 );
+    p += 2;
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
     if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
@@ -2498,8 +2530,8 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 1;
@@ -2528,8 +2560,8 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) );
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0 );
+    p += 2;
 
     *p++ = 0x00;
     *p++ = 2;
@@ -2566,8 +2598,8 @@
         return;
     }
 
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 );
+    p += 2;
 
     ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
                                         p + 2, end - p - 2, &kkpp_len,
@@ -2578,8 +2610,8 @@
         return;
     }
 
-    *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( kkpp_len      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 );
+    p += 2;
 
     *olen = kkpp_len + 4;
 }
@@ -2604,18 +2636,15 @@
      * 6 . 6    protocol name length
      * 7 . 7+n  protocol name
      */
-    buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
-    buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ALPN, buf, 0);
 
     *olen = 7 + strlen( ssl->alpn_chosen );
 
-    buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
-    buf[3] = (unsigned char)( ( ( *olen - 4 )      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( *olen - 4, buf, 2 );
 
-    buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
-    buf[5] = (unsigned char)( ( ( *olen - 6 )      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( *olen - 6, buf, 4 );
 
-    buf[6] = (unsigned char)( ( ( *olen - 7 )      ) & 0xFF );
+    buf[6] = MBEDTLS_BYTE_0( *olen - 7 );
 
     memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 );
 }
@@ -2660,15 +2689,13 @@
     }
 
     /* extension */
-    buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF );
-    buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP      ) & 0xFF );
+    MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0 );
     /*
      * total length 5 and mki value: only one profile(2 bytes)
      *              and length(2 bytes) and srtp_mki  )
      */
     ext_len = 5 + mki_len;
-    buf[2] = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
-    buf[3] = (unsigned char)( ext_len & 0xFF );
+    MBEDTLS_PUT_UINT16_BE( ext_len, buf, 2 );
 
     /* protection profile length: 2 */
     buf[4] = 0x00;
@@ -2677,8 +2704,7 @@
                                 ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
     if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
     {
-        buf[6] = (unsigned char)( ( profile_value >> 8 ) & 0xFF );
-        buf[7] = (unsigned char)( profile_value & 0xFF );
+        MBEDTLS_PUT_UINT16_BE( profile_value, buf, 6 );
     }
     else
     {
@@ -2694,6 +2720,7 @@
 #endif /* MBEDTLS_SSL_DTLS_SRTP */
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -2814,6 +2841,7 @@
     mbedtls_ssl_session_free( &session_tmp );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
 {
 #if defined(MBEDTLS_HAVE_TIME)
@@ -2861,10 +2889,8 @@
 
 #if defined(MBEDTLS_HAVE_TIME)
     t = mbedtls_time( NULL );
-    *p++ = (unsigned char)( t >> 24 );
-    *p++ = (unsigned char)( t >> 16 );
-    *p++ = (unsigned char)( t >>  8 );
-    *p++ = (unsigned char)( t       );
+    MBEDTLS_PUT_UINT32_BE( t, p, 0 );
+    p += 4;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
                                 (long long) t ) );
@@ -2945,9 +2971,9 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
                    ssl->handshake->resume ? "a" : "no" ) );
 
-    *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 );
-    *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite      );
-    *p++ = (unsigned char)( ssl->session_negotiate->compression      );
+    MBEDTLS_PUT_UINT16_BE( ssl->session_negotiate->ciphersuite, p, 0 );
+    p += 2;
+    *p++ = MBEDTLS_BYTE_0( ssl->session_negotiate->compression );
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s",
            mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) );
@@ -3026,9 +3052,8 @@
 
     if( ext_len > 0 )
     {
-        *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
-        *p++ = (unsigned char)( ( ext_len      ) & 0xFF );
-        p += ext_len;
+        MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+        p += 2 + ext_len;
     }
 
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
@@ -3047,6 +3072,7 @@
 }
 
 #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
 {
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@@ -3065,6 +3091,7 @@
     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
 }
 #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -3167,8 +3194,7 @@
 #endif
         }
 
-        p[0] = (unsigned char)( sa_len >> 8 );
-        p[1] = (unsigned char)( sa_len      );
+        MBEDTLS_PUT_UINT16_BE( sa_len, p, 0 );
         sa_len += 2;
         p += sa_len;
     }
@@ -3208,8 +3234,8 @@
                 break;
             }
 
-            *p++ = (unsigned char)( dn_size >> 8 );
-            *p++ = (unsigned char)( dn_size      );
+            MBEDTLS_PUT_UINT16_BE( dn_size, p, 0 );
+            p += 2;
             memcpy( p, crt->subject_raw.p, dn_size );
             p += dn_size;
 
@@ -3223,8 +3249,7 @@
     ssl->out_msglen  = p - buf;
     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
-    ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size  >> 8 );
-    ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size       );
+    MBEDTLS_PUT_UINT16_BE( total_dn_size, ssl->out_msg, 4 + ct_len + sa_len );
 
     ret = mbedtls_ssl_write_handshake_msg( ssl );
 
@@ -3236,18 +3261,23 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_pk_context *own_key = mbedtls_ssl_own_key( ssl );
 
-    if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) )
+    /* Check if the key is a transparent ECDH key.
+     * This also ensures that it is safe to call mbedtls_pk_ec(). */
+    if( mbedtls_pk_get_type( own_key ) != MBEDTLS_PK_ECKEY &&
+        mbedtls_pk_get_type( own_key ) != MBEDTLS_PK_ECKEY_DH )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
         return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
     }
 
     if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx,
-                                 mbedtls_pk_ec( *mbedtls_ssl_own_key( ssl ) ),
+                                 mbedtls_pk_ec( *own_key ),
                                  MBEDTLS_ECDH_OURS ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
@@ -3261,6 +3291,7 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
                                            size_t *signature_len )
 {
@@ -3288,6 +3319,7 @@
 /* Prepare the ServerKeyExchange message, up to and including
  * calculating the signature if any, but excluding formatting the
  * signature and sending the message. */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
                                             size_t *signature_len )
 {
@@ -3481,7 +3513,11 @@
     {
         size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
         size_t hashlen = 0;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+        unsigned char hash[PSA_HASH_MAX_SIZE];
+#else
         unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+#endif
         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
         /*
@@ -3653,6 +3689,7 @@
  * that do not include a ServerKeyExchange message, do nothing. Either
  * way, if successful, move on to the next step in the SSL state
  * machine. */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3674,7 +3711,12 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
         if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
         {
-            ssl_get_ecdh_params_from_cert( ssl );
+            ret = ssl_get_ecdh_params_from_cert( ssl );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
+                return( ret );
+            }
         }
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
 
@@ -3722,8 +3764,8 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
     if( signature_len != 0 )
     {
-        ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
-        ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len      );
+        ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1( signature_len );
+        ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0( signature_len );
 
         MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
                                ssl->out_msg + ssl->out_msglen,
@@ -3750,6 +3792,7 @@
     return( 0 );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -3789,6 +3832,7 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char **p,
                                        const unsigned char *end )
 {
@@ -3832,6 +3876,7 @@
     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
 
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl,
                                    unsigned char *peer_pms,
                                    size_t *peer_pmslen,
@@ -3849,6 +3894,7 @@
 }
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
                                       const unsigned char *p,
                                       const unsigned char *end,
@@ -3879,12 +3925,13 @@
     defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
     {
-        if ( p + 2 > end ) {
+        if ( p + 2 > end )
+        {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
         }
-        if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
-            *p++ != ( ( len      ) & 0xFF ) )
+        if( *p++ != MBEDTLS_BYTE_1( len ) ||
+            *p++ != MBEDTLS_BYTE_0( len ) )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
@@ -3940,6 +3987,7 @@
     return( ret );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
                                     const unsigned char *p,
                                     const unsigned char *end,
@@ -3986,16 +4034,7 @@
     diff |= peer_pms[1] ^ ver[1];
 
     /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
-    /* MSVC has a warning about unary minus on unsigned, but this is
-     * well-defined and precisely what we want to do here */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-    mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
+    mask = mbedtls_ct_uint_mask( diff );
 
     /*
      * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
@@ -4038,6 +4077,7 @@
           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p,
                                           const unsigned char *end )
 {
@@ -4078,7 +4118,7 @@
         /* Identity is not a big secret since clients send it in the clear,
          * but treat it carefully anyway, just in case */
         if( n != ssl->conf->psk_identity_len ||
-            mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
+            mbedtls_ct_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
         {
             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
         }
@@ -4098,6 +4138,7 @@
 }
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -4225,7 +4266,7 @@
         }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-        /* For opaque PSKs, we perform the PSK-to-MS derivation atomatically
+        /* For opaque PSKs, we perform the PSK-to-MS derivation automatically
          * and skip the intermediate PMS. */
         if( ssl_use_opaque_psk( ssl ) == 1 )
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) );
@@ -4265,7 +4306,10 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         /* Opaque PSKs are currently only supported for PSK-only. */
         if( ssl_use_opaque_psk( ssl ) == 1 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with RSA-PSK" ) );
             return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
 #endif
 
         if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
@@ -4300,7 +4344,10 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         /* Opaque PSKs are currently only supported for PSK-only. */
         if( ssl_use_opaque_psk( ssl ) == 1 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with DHE-PSK" ) );
             return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
 #endif
 
         if( p != end )
@@ -4337,7 +4384,10 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         /* Opaque PSKs are currently only supported for PSK-only. */
         if( ssl_use_opaque_psk( ssl ) == 1 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "opaque PSK not supported with ECDHE-PSK" ) );
             return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
 #endif
 
         MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
@@ -4404,6 +4454,7 @@
 }
 
 #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
 {
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@@ -4422,6 +4473,7 @@
     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
 }
 #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -4615,6 +4667,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -4647,14 +4700,8 @@
         tlen = 0;
     }
 
-    ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF;
-    ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF;
-    ssl->out_msg[6] = ( lifetime >>  8 ) & 0xFF;
-    ssl->out_msg[7] = ( lifetime       ) & 0xFF;
-
-    ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF );
-    ssl->out_msg[9] = (unsigned char)( ( tlen      ) & 0xFF );
-
+    MBEDTLS_PUT_UINT32_BE( lifetime, ssl->out_msg, 4 );
+    MBEDTLS_PUT_UINT16_BE( tlen, ssl->out_msg, 8 );
     ssl->out_msglen = 10 + tlen;
 
     /*
diff --git a/lib/libmbedtls/mbedtls/library/ssl_ticket.c b/lib/libmbedtls/mbedtls/library/ssl_ticket.c
index 626d137..e0126cc 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_ticket.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_ticket.c
@@ -37,7 +37,7 @@
 #include <string.h>
 
 /*
- * Initialze context
+ * Initialize context
  */
 void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx )
 {
@@ -66,6 +66,7 @@
 /*
  * Generate/update a key
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx,
                                unsigned char index )
 {
@@ -96,6 +97,7 @@
 /*
  * Rotate/generate keys if necessary
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx )
 {
 #if !defined(MBEDTLS_HAVE_TIME)
@@ -245,8 +247,7 @@
     {
          goto cleanup;
     }
-    state_len_bytes[0] = ( clear_len >> 8 ) & 0xff;
-    state_len_bytes[1] = ( clear_len      ) & 0xff;
+    MBEDTLS_PUT_UINT16_BE( clear_len, state_len_bytes, 0 );
 
     /* Encrypt and authenticate */
     if( ( ret = mbedtls_cipher_auth_encrypt_ext( &key->ctx,
diff --git a/lib/libmbedtls/mbedtls/library/ssl_tls.c b/lib/libmbedtls/mbedtls/library/ssl_tls.c
index 976a87c..7badec5 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_tls.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_tls.c
@@ -43,6 +43,7 @@
 #include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/version.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -187,6 +188,10 @@
     mbedtls_ssl_session_free( dst );
     memcpy( dst, src, sizeof( mbedtls_ssl_session ) );
 
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+    dst->ticket = NULL;
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 
 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
@@ -240,6 +245,7 @@
 }
 
 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int resize_buffer( unsigned char **buffer, size_t len_new, size_t *len_old )
 {
     unsigned char* resized_buffer = mbedtls_calloc( 1, len_new );
@@ -332,6 +338,7 @@
  * Key material generation
  */
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl3_prf( const unsigned char *secret, size_t slen,
                      const char *label,
                      const unsigned char *random, size_t rlen,
@@ -393,6 +400,7 @@
 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int tls1_prf( const unsigned char *secret, size_t slen,
                      const char *label,
                      const unsigned char *random, size_t rlen,
@@ -441,19 +449,37 @@
         goto exit;
     }
 
-    mbedtls_md_hmac_starts( &md_ctx, S1, hs );
-    mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
-    mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
+    ret = mbedtls_md_hmac_starts( &md_ctx, S1, hs );
+    if( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
+    if( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
+    if( ret != 0 )
+        goto exit;
 
     for( i = 0; i < dlen; i += 16 )
     {
-        mbedtls_md_hmac_reset ( &md_ctx );
-        mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb );
-        mbedtls_md_hmac_finish( &md_ctx, h_i );
+        ret = mbedtls_md_hmac_reset ( &md_ctx );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_finish( &md_ctx, h_i );
+        if( ret != 0 )
+            goto exit;
 
-        mbedtls_md_hmac_reset ( &md_ctx );
-        mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 );
-        mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
+        ret = mbedtls_md_hmac_reset ( &md_ctx );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
+        if( ret != 0 )
+            goto exit;
 
         k = ( i + 16 > dlen ) ? dlen % 16 : 16;
 
@@ -477,19 +503,37 @@
         goto exit;
     }
 
-    mbedtls_md_hmac_starts( &md_ctx, S2, hs );
-    mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
-    mbedtls_md_hmac_finish( &md_ctx, tmp );
+    ret = mbedtls_md_hmac_starts( &md_ctx, S2, hs );
+    if( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
+    if( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
+    if( ret != 0 )
+        goto exit;
 
     for( i = 0; i < dlen; i += 20 )
     {
-        mbedtls_md_hmac_reset ( &md_ctx );
-        mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb );
-        mbedtls_md_hmac_finish( &md_ctx, h_i );
+        ret = mbedtls_md_hmac_reset ( &md_ctx );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_finish( &md_ctx, h_i );
+        if( ret != 0 )
+            goto exit;
 
-        mbedtls_md_hmac_reset ( &md_ctx );
-        mbedtls_md_hmac_update( &md_ctx, tmp, 20 );
-        mbedtls_md_hmac_finish( &md_ctx, tmp );
+        ret = mbedtls_md_hmac_reset ( &md_ctx );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_update( &md_ctx, tmp, 20 );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
+        if( ret != 0 )
+            goto exit;
 
         k = ( i + 20 > dlen ) ? dlen % 20 : 20;
 
@@ -564,6 +608,7 @@
     return( PSA_SUCCESS );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int tls_prf_generic( mbedtls_md_type_t md_type,
                             const unsigned char *secret, size_t slen,
                             const char *label,
@@ -638,6 +683,7 @@
 
 #else /* MBEDTLS_USE_PSA_CRYPTO */
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int tls_prf_generic( mbedtls_md_type_t md_type,
                             const unsigned char *secret, size_t slen,
                             const char *label,
@@ -679,19 +725,37 @@
     if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
         goto exit;
 
-    mbedtls_md_hmac_starts( &md_ctx, secret, slen );
-    mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
-    mbedtls_md_hmac_finish( &md_ctx, tmp );
+    ret = mbedtls_md_hmac_starts( &md_ctx, secret, slen );
+    if( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
+    if( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
+    if( ret != 0 )
+        goto exit;
 
     for( i = 0; i < dlen; i += md_len )
     {
-        mbedtls_md_hmac_reset ( &md_ctx );
-        mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
-        mbedtls_md_hmac_finish( &md_ctx, h_i );
+        ret = mbedtls_md_hmac_reset ( &md_ctx );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_finish( &md_ctx, h_i );
+        if( ret != 0 )
+            goto exit;
 
-        mbedtls_md_hmac_reset ( &md_ctx );
-        mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
-        mbedtls_md_hmac_finish( &md_ctx, tmp );
+        ret = mbedtls_md_hmac_reset ( &md_ctx );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
+        if( ret != 0 )
+            goto exit;
+        ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
+        if( ret != 0 )
+            goto exit;
 
         k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
 
@@ -711,6 +775,7 @@
 }
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 #if defined(MBEDTLS_SHA256_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int tls_prf_sha256( const unsigned char *secret, size_t slen,
                            const char *label,
                            const unsigned char *random, size_t rlen,
@@ -722,6 +787,7 @@
 #endif /* MBEDTLS_SHA256_C */
 
 #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int tls_prf_sha384( const unsigned char *secret, size_t slen,
                            const char *label,
                            const unsigned char *random, size_t rlen,
@@ -766,6 +832,7 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
     defined(MBEDTLS_USE_PSA_CRYPTO)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
 {
     if( ssl->conf->f_psk != NULL )
@@ -890,6 +957,7 @@
  *        - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
  *        - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_populate_transform( mbedtls_ssl_transform *transform,
                                    int ciphersuite,
                                    const unsigned char master[48],
@@ -931,6 +999,7 @@
 
 #if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) && \
     !defined(MBEDTLS_SSL_EXPORT_KEYS) && \
+    !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
     !defined(MBEDTLS_DEBUG_C)
     ssl = NULL; /* make sure we don't use it except for those cases */
     (void) ssl;
@@ -1231,8 +1300,14 @@
            For AEAD-based ciphersuites, there is nothing to do here. */
         if( mac_key_len != 0 )
         {
-            mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len );
-            mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len );
+            ret = mbedtls_md_hmac_starts( &transform->md_ctx_enc,
+                                          mac_enc, mac_key_len );
+            if( ret != 0 )
+                goto end;
+            ret = mbedtls_md_hmac_starts( &transform->md_ctx_dec,
+                                          mac_dec, mac_key_len );
+            if( ret != 0 )
+                goto end;
         }
     }
     else
@@ -1296,7 +1371,7 @@
      * the structure field for the IV, which the PSA-based
      * implementation currently doesn't. */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
         ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_enc,
                                         cipher_info, transform->taglen );
@@ -1339,7 +1414,7 @@
      * the structure field for the IV, which the PSA-based
      * implementation currently doesn't. */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
         ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_dec,
                                         cipher_info, transform->taglen );
@@ -1446,6 +1521,7 @@
  * Outputs:
  * - the tls_prf, calc_verify and calc_finished members of handshake structure
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake,
                                    int minor_ver,
                                    mbedtls_md_type_t hash )
@@ -1515,6 +1591,7 @@
  *      EMS: passed to calc_verify (debug + (SSL3) session_negotiate)
  *      PSA-PSA: minor_ver, conf
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
                                unsigned char *master,
                                const mbedtls_ssl_context *ssl )
@@ -1948,8 +2025,8 @@
         if( end - p < 2 )
             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-        *(p++) = (unsigned char)( psk_len >> 8 );
-        *(p++) = (unsigned char)( psk_len      );
+        MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
+        p += 2;
 
         if( end < p || (size_t)( end - p ) < psk_len )
             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -1989,9 +2066,8 @@
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
             return( ret );
         }
-        *(p++) = (unsigned char)( len >> 8 );
-        *(p++) = (unsigned char)( len );
-        p += len;
+        MBEDTLS_PUT_UINT16_BE( len, p, 0 );
+        p += 2 + len;
 
         MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
     }
@@ -2011,9 +2087,8 @@
             return( ret );
         }
 
-        *(p++) = (unsigned char)( zlen >> 8 );
-        *(p++) = (unsigned char)( zlen      );
-        p += zlen;
+        MBEDTLS_PUT_UINT16_BE( zlen, p, 0 );
+        p += 2 + zlen;
 
         MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
                                 MBEDTLS_DEBUG_ECDH_Z );
@@ -2029,8 +2104,8 @@
     if( end - p < 2 )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-    *(p++) = (unsigned char)( psk_len >> 8 );
-    *(p++) = (unsigned char)( psk_len      );
+    MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
+    p += 2;
 
     if( end < p || (size_t)( end - p ) < psk_len )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -2045,6 +2120,7 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -2224,17 +2300,17 @@
             return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE );
         }
 
-        ssl->out_msg[i    ] = (unsigned char)( n >> 16 );
-        ssl->out_msg[i + 1] = (unsigned char)( n >>  8 );
-        ssl->out_msg[i + 2] = (unsigned char)( n       );
+        ssl->out_msg[i    ] = MBEDTLS_BYTE_2( n );
+        ssl->out_msg[i + 1] = MBEDTLS_BYTE_1( n );
+        ssl->out_msg[i + 2] = MBEDTLS_BYTE_0( n );
 
         i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
         i += n; crt = crt->next;
     }
 
-    ssl->out_msg[4]  = (unsigned char)( ( i - 7 ) >> 16 );
-    ssl->out_msg[5]  = (unsigned char)( ( i - 7 ) >>  8 );
-    ssl->out_msg[6]  = (unsigned char)( ( i - 7 )       );
+    ssl->out_msg[4]  = MBEDTLS_BYTE_2( i - 7 );
+    ssl->out_msg[5]  = MBEDTLS_BYTE_1( i - 7 );
+    ssl->out_msg[6]  = MBEDTLS_BYTE_0( i - 7 );
 
     ssl->out_msglen  = i;
     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@@ -2260,6 +2336,7 @@
 #if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
 
 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
                                          unsigned char *crt_buf,
                                          size_t crt_buf_len )
@@ -2275,6 +2352,7 @@
     return( memcmp( peer_crt->raw.p, crt_buf, peer_crt->raw.len ) );
 }
 #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
                                          unsigned char *crt_buf,
                                          size_t crt_buf_len )
@@ -2309,6 +2387,7 @@
  * Once the certificate message is read, parse it into a cert chain and
  * perform basic checks, but leave actual verification to the caller
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl,
                                         mbedtls_x509_crt *chain )
 {
@@ -2458,6 +2537,7 @@
 }
 
 #if defined(MBEDTLS_SSL_SRV_C)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl )
 {
     if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
@@ -2507,6 +2587,7 @@
  */
 #define SSL_CERTIFICATE_EXPECTED 0
 #define SSL_CERTIFICATE_SKIP     1
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
                                              int authmode )
 {
@@ -2536,6 +2617,7 @@
     return( SSL_CERTIFICATE_EXPECTED );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
                                          int authmode,
                                          mbedtls_x509_crt *chain,
@@ -2633,7 +2715,9 @@
     {
         const mbedtls_pk_context *pk = &chain->pk;
 
-        /* If certificate uses an EC key, make sure the curve is OK */
+        /* 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 ) &&
             mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
         {
@@ -2724,6 +2808,7 @@
 }
 
 #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl,
                                          unsigned char *start, size_t len )
 {
@@ -2755,6 +2840,7 @@
     return( ret );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl,
                                      unsigned char *start, size_t len )
 {
@@ -3365,7 +3451,7 @@
     ssl->handshake = NULL;
 
     /*
-     * Free the previous transform and swith in the current one
+     * Free the previous transform and switch in the current one
      */
     if( ssl->transform )
     {
@@ -3572,22 +3658,6 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
 
-    ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
-
-    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
-        return( ret );
-    }
-
-    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
-        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
-    }
-
     /* There is currently no ciphersuite using another length with TLS 1.2 */
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
     if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
@@ -3596,22 +3666,41 @@
 #endif
         hash_len = 12;
 
+    ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        goto exit;
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+        goto exit;
+    }
+
     if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
         ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
+        ret = MBEDTLS_ERR_SSL_BAD_HS_FINISHED;
+        goto exit;
     }
 
-    if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
+    if( mbedtls_ct_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
                       buf, hash_len ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
+        ret = MBEDTLS_ERR_SSL_BAD_HS_FINISHED;
+        goto exit;
     }
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -3640,7 +3729,9 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) );
 
-    return( 0 );
+exit:
+    mbedtls_platform_zeroize( buf, hash_len );
+    return( ret );
 }
 
 static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
@@ -3728,6 +3819,7 @@
     memset( session, 0, sizeof(mbedtls_ssl_session) );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_handshake_init( mbedtls_ssl_context *ssl )
 {
     /* Clear old handshake information if present */
@@ -3805,6 +3897,7 @@
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
 /* Dummy cookie callbacks for defaults */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_cookie_write_dummy( void *ctx,
                       unsigned char **p, unsigned char *end,
                       const unsigned char *cli_id, size_t cli_id_len )
@@ -3818,6 +3911,7 @@
     return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
 }
 
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_cookie_check_dummy( void *ctx,
                       const unsigned char *cookie, size_t cookie_len,
                       const unsigned char *cli_id, size_t cli_id_len )
@@ -4235,6 +4329,7 @@
 }
 
 /* Append a new keycert entry to a (possibly empty) list */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_append_key_cert( mbedtls_ssl_key_cert **head,
                                 mbedtls_x509_crt *cert,
                                 mbedtls_pk_context *key )
@@ -4403,6 +4498,7 @@
  * It checks that the provided identity is well-formed and attempts
  * to make a copy of it in the SSL config.
  * On failure, the PSK identity in the config remains unset. */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_conf_set_psk_identity( mbedtls_ssl_config *conf,
                                       unsigned char const *psk_identity,
                                       size_t psk_identity_len )
@@ -4564,6 +4660,9 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
+    mbedtls_mpi_free( &conf->dhm_P );
+    mbedtls_mpi_free( &conf->dhm_G );
+
     if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 ||
         ( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 )
     {
@@ -4579,6 +4678,9 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
+    mbedtls_mpi_free( &conf->dhm_P );
+    mbedtls_mpi_free( &conf->dhm_G );
+
     if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
         ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
     {
@@ -5278,8 +5380,8 @@
     MBEDTLS_VERSION_MAJOR,
     MBEDTLS_VERSION_MINOR,
     MBEDTLS_VERSION_PATCH,
-    ( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG >> 8 ) & 0xFF,
-    ( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG >> 0 ) & 0xFF,
+    MBEDTLS_BYTE_1( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+    MBEDTLS_BYTE_0( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
 };
 
 /*
@@ -5316,6 +5418,7 @@
  * verify_result is put before peer_cert so that all mandatory fields come
  * together in one block.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_session_save( const mbedtls_ssl_session *session,
                              unsigned char omit_header,
                              unsigned char *buf,
@@ -5360,14 +5463,8 @@
     {
         start = (uint64_t) session->start;
 
-        *p++ = (unsigned char)( ( start >> 56 ) & 0xFF );
-        *p++ = (unsigned char)( ( start >> 48 ) & 0xFF );
-        *p++ = (unsigned char)( ( start >> 40 ) & 0xFF );
-        *p++ = (unsigned char)( ( start >> 32 ) & 0xFF );
-        *p++ = (unsigned char)( ( start >> 24 ) & 0xFF );
-        *p++ = (unsigned char)( ( start >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( start >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( start       ) & 0xFF );
+        MBEDTLS_PUT_UINT64_BE( start, p, 0 );
+        p += 8;
     }
 #endif /* MBEDTLS_HAVE_TIME */
 
@@ -5383,22 +5480,20 @@
 
     if( used <= buf_len )
     {
-        *p++ = (unsigned char)( ( session->ciphersuite >> 8 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->ciphersuite      ) & 0xFF );
+        MBEDTLS_PUT_UINT16_BE( session->ciphersuite, p, 0 );
+        p += 2;
 
-        *p++ = (unsigned char)( session->compression & 0xFF );
+        *p++ = MBEDTLS_BYTE_0( session->compression );
 
-        *p++ = (unsigned char)( session->id_len & 0xFF );
+        *p++ = MBEDTLS_BYTE_0( session->id_len );
         memcpy( p, session->id, 32 );
         p += 32;
 
         memcpy( p, session->master, 48 );
         p += 48;
 
-        *p++ = (unsigned char)( ( session->verify_result >> 24 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->verify_result >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->verify_result >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->verify_result       ) & 0xFF );
+        MBEDTLS_PUT_UINT32_BE( session->verify_result, p, 0 );
+        p += 4;
     }
 
     /*
@@ -5415,9 +5510,9 @@
 
     if( used <= buf_len )
     {
-        *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( cert_len >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( cert_len       ) & 0xFF );
+        *p++ = MBEDTLS_BYTE_2( cert_len );
+        *p++ = MBEDTLS_BYTE_1( cert_len );
+        *p++ = MBEDTLS_BYTE_0( cert_len );
 
         if( session->peer_cert != NULL )
         {
@@ -5458,9 +5553,9 @@
 
     if( used <= buf_len )
     {
-        *p++ = (unsigned char)( ( session->ticket_len >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->ticket_len >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->ticket_len       ) & 0xFF );
+        *p++ = MBEDTLS_BYTE_2( session->ticket_len );
+        *p++ = MBEDTLS_BYTE_1( session->ticket_len );
+        *p++ = MBEDTLS_BYTE_0( session->ticket_len );
 
         if( session->ticket != NULL )
         {
@@ -5468,10 +5563,8 @@
             p += session->ticket_len;
         }
 
-        *p++ = (unsigned char)( ( session->ticket_lifetime >> 24 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->ticket_lifetime >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->ticket_lifetime >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( session->ticket_lifetime       ) & 0xFF );
+        MBEDTLS_PUT_UINT32_BE( session->ticket_lifetime, p, 0 );
+        p += 4;
     }
 #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
 
@@ -5496,7 +5589,7 @@
     used += 1;
 
     if( used <= buf_len )
-        *p++ = (unsigned char)( ( session->encrypt_then_mac ) & 0xFF );
+        *p++ = MBEDTLS_BYTE_0( session->encrypt_then_mac );
 #endif
 
     /* Done */
@@ -5525,6 +5618,7 @@
  * This internal version is wrapped by a public function that cleans up in
  * case of error, and has an extra option omit_header.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_session_load( mbedtls_ssl_session *session,
                              unsigned char omit_header,
                              const unsigned char *buf,
@@ -5828,6 +5922,7 @@
 /*
  * Write HelloRequest to request renegotiation on server
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -6149,11 +6244,11 @@
     MBEDTLS_VERSION_MAJOR,
     MBEDTLS_VERSION_MINOR,
     MBEDTLS_VERSION_PATCH,
-    ( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG >> 8 ) & 0xFF,
-    ( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG >> 0 ) & 0xFF,
-    ( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG >> 16 ) & 0xFF,
-    ( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG >>  8 ) & 0xFF,
-    ( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG >>  0 ) & 0xFF,
+    MBEDTLS_BYTE_1( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+    MBEDTLS_BYTE_0( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+    MBEDTLS_BYTE_2( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
+    MBEDTLS_BYTE_1( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
+    MBEDTLS_BYTE_0( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
 };
 
 /*
@@ -6294,10 +6389,8 @@
     used += 4 + session_len;
     if( used <= buf_len )
     {
-        *p++ = (unsigned char)( ( session_len >> 24 ) & 0xFF );
-        *p++ = (unsigned char)( ( session_len >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( session_len >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( session_len       ) & 0xFF );
+        MBEDTLS_PUT_UINT32_BE( session_len, p, 0 );
+        p += 4;
 
         ret = ssl_session_save( ssl->session, 1,
                                 p, session_len, &session_len );
@@ -6339,10 +6432,8 @@
     used += 4;
     if( used <= buf_len )
     {
-        *p++ = (unsigned char)( ( ssl->badmac_seen >> 24 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->badmac_seen >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->badmac_seen >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->badmac_seen       ) & 0xFF );
+        MBEDTLS_PUT_UINT32_BE( ssl->badmac_seen, p, 0 );
+        p += 4;
     }
 #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
 
@@ -6350,23 +6441,11 @@
     used += 16;
     if( used <= buf_len )
     {
-        *p++ = (unsigned char)( ( ssl->in_window_top >> 56 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window_top >> 48 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window_top >> 40 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window_top >> 32 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window_top >> 24 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window_top >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window_top >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window_top       ) & 0xFF );
+        MBEDTLS_PUT_UINT64_BE( ssl->in_window_top, p, 0 );
+        p += 8;
 
-        *p++ = (unsigned char)( ( ssl->in_window >> 56 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window >> 48 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window >> 40 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window >> 32 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window >> 24 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window >> 16 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->in_window       ) & 0xFF );
+        MBEDTLS_PUT_UINT64_BE( ssl->in_window, p, 0 );
+        p += 8;
     }
 #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
 
@@ -6389,8 +6468,8 @@
     used += 2;
     if( used <= buf_len )
     {
-        *p++ = (unsigned char)( ( ssl->mtu >>  8 ) & 0xFF );
-        *p++ = (unsigned char)( ( ssl->mtu       ) & 0xFF );
+        MBEDTLS_PUT_UINT16_BE( ssl->mtu, p, 0 );
+        p += 2;
     }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
@@ -6455,6 +6534,7 @@
  * This internal version is wrapped by a public function that cleans up in
  * case of error.
  */
+MBEDTLS_CHECK_RETURN_CRITICAL
 static int ssl_context_load( mbedtls_ssl_context *ssl,
                              const unsigned char *buf,
                              size_t len )
@@ -7278,6 +7358,18 @@
 
     return( -1 );
 }
+
+/*
+ * Same as mbedtls_ssl_check_curve() but takes a TLS ID for the curve.
+ */
+int mbedtls_ssl_check_curve_tls_id( const mbedtls_ssl_context *ssl, uint16_t tls_id )
+{
+    const mbedtls_ecp_curve_info *curve_info =
+        mbedtls_ecp_curve_info_from_tls_id( tls_id );
+    if( curve_info == NULL )
+        return( -1 );
+    return( mbedtls_ssl_check_curve( ssl, curve_info->grp_id ) );
+}
 #endif /* MBEDTLS_ECP_C */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
@@ -7556,7 +7648,7 @@
         goto exit;
     }
 
-    if( ( status = psa_hash_finish( &hash_operation, hash, MBEDTLS_MD_MAX_SIZE,
+    if( ( status = psa_hash_finish( &hash_operation, hash, PSA_HASH_MAX_SIZE,
                                     hashlen ) ) != PSA_SUCCESS )
     {
          MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_finish", status );
diff --git a/lib/libmbedtls/mbedtls/library/ssl_tls13_keys.c b/lib/libmbedtls/mbedtls/library/ssl_tls13_keys.c
index c39e032..3de6f03 100644
--- a/lib/libmbedtls/mbedtls/library/ssl_tls13_keys.c
+++ b/lib/libmbedtls/mbedtls/library/ssl_tls13_keys.c
@@ -112,17 +112,17 @@
 #endif
 
     *p++ = 0;
-    *p++ = (unsigned char)( ( desired_length >> 0 ) & 0xFF );
+    *p++ = MBEDTLS_BYTE_0( desired_length );
 
     /* Add label incl. prefix */
-    *p++ = (unsigned char)( total_label_len & 0xFF );
+    *p++ = MBEDTLS_BYTE_0( total_label_len );
     memcpy( p, tls1_3_label_prefix, sizeof(tls1_3_label_prefix) );
     p += sizeof(tls1_3_label_prefix);
     memcpy( p, label, llen );
     p += llen;
 
     /* Add context value */
-    *p++ = (unsigned char)( clen & 0xFF );
+    *p++ = MBEDTLS_BYTE_0( clen );
     if( clen != 0 )
         memcpy( p, ctx, clen );
 
diff --git a/lib/libmbedtls/mbedtls/library/threading.c b/lib/libmbedtls/mbedtls/library/threading.c
index 2de117f..5e0aaa4 100644
--- a/lib/libmbedtls/mbedtls/library/threading.c
+++ b/lib/libmbedtls/mbedtls/library/threading.c
@@ -113,7 +113,7 @@
 int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread;
 
 /*
- * With phtreads we can statically initialize mutexes
+ * With pthreads we can statically initialize mutexes
  */
 #define MUTEX_INIT  = { PTHREAD_MUTEX_INITIALIZER, 1 }
 
diff --git a/lib/libmbedtls/mbedtls/library/timing.c b/lib/libmbedtls/mbedtls/library/timing.c
index eb41461..57bc9bc 100644
--- a/lib/libmbedtls/mbedtls/library/timing.c
+++ b/lib/libmbedtls/mbedtls/library/timing.c
@@ -56,15 +56,15 @@
 
 #include <unistd.h>
 #include <sys/types.h>
-#include <sys/time.h>
 #include <signal.h>
+/* time.h should be included independently of MBEDTLS_HAVE_TIME. If the
+ * platform matches the ifdefs above, it will be used. */
 #include <time.h>
-
+#include <sys/time.h>
 struct _hr_time
 {
     struct timeval start;
 };
-
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 
 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
@@ -364,7 +364,6 @@
     return( 0 );
 }
 
-#endif /* !MBEDTLS_TIMING_ALT */
 
 #if defined(MBEDTLS_SELF_TEST)
 
@@ -526,5 +525,5 @@
 }
 
 #endif /* MBEDTLS_SELF_TEST */
-
+#endif /* !MBEDTLS_TIMING_ALT */
 #endif /* MBEDTLS_TIMING_C */
diff --git a/lib/libmbedtls/mbedtls/library/version_features.c b/lib/libmbedtls/mbedtls/library/version_features.c
index f665a23..40c9520 100644
--- a/lib/libmbedtls/mbedtls/library/version_features.c
+++ b/lib/libmbedtls/mbedtls/library/version_features.c
@@ -267,6 +267,9 @@
 #if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
     "MBEDTLS_CAMELLIA_SMALL_MEMORY",
 #endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+    "MBEDTLS_CHECK_RETURN_WARNING",
+#endif /* MBEDTLS_CHECK_RETURN_WARNING */
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     "MBEDTLS_CIPHER_MODE_CBC",
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
diff --git a/lib/libmbedtls/mbedtls/library/x509.c b/lib/libmbedtls/mbedtls/library/x509.c
index f21e9e6..3997ebd 100644
--- a/lib/libmbedtls/mbedtls/library/x509.c
+++ b/lib/libmbedtls/mbedtls/library/x509.c
@@ -741,7 +741,7 @@
 int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i, n;
+    size_t i, j, n;
     unsigned char c, merge = 0;
     const mbedtls_x509_name *name;
     const char *short_name = NULL;
@@ -775,17 +775,24 @@
             ret = mbedtls_snprintf( p, n, "\?\?=" );
         MBEDTLS_X509_SAFE_SNPRINTF;
 
-        for( i = 0; i < name->val.len; i++ )
+        for( i = 0, j = 0; i < name->val.len; i++, j++ )
         {
-            if( i >= sizeof( s ) - 1 )
-                break;
+            if( j >= sizeof( s ) - 1 )
+                return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
 
             c = name->val.p[i];
+            // Special characters requiring escaping, RFC 1779
+            if( c && strchr( ",=+<>#;\"\\", c ) )
+            {
+                if( j + 1 >= sizeof( s ) - 1 )
+                    return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+                s[j++] = '\\';
+            }
             if( c < 32 || c >= 127 )
-                 s[i] = '?';
-            else s[i] = c;
+                 s[j] = '?';
+            else s[j] = c;
         }
-        s[i] = '\0';
+        s[j] = '\0';
         ret = mbedtls_snprintf( p, n, "%s", s );
         MBEDTLS_X509_SAFE_SNPRINTF;
 
diff --git a/lib/libmbedtls/mbedtls/library/x509_crl.c b/lib/libmbedtls/mbedtls/library/x509_crl.c
index ac4fc75..d2d8042 100644
--- a/lib/libmbedtls/mbedtls/library/x509_crl.c
+++ b/lib/libmbedtls/mbedtls/library/x509_crl.c
@@ -52,11 +52,13 @@
 #define mbedtls_snprintf   snprintf
 #endif
 
+#if defined(MBEDTLS_HAVE_TIME)
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 #include <windows.h>
 #else
 #include <time.h>
 #endif
+#endif
 
 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
 #include <stdio.h>
diff --git a/lib/libmbedtls/mbedtls/library/x509_crt.c b/lib/libmbedtls/mbedtls/library/x509_crt.c
index acdd545..911644b 100644
--- a/lib/libmbedtls/mbedtls/library/x509_crt.c
+++ b/lib/libmbedtls/mbedtls/library/x509_crt.c
@@ -63,11 +63,13 @@
 #include "mbedtls/threading.h"
 #endif
 
+#if defined(MBEDTLS_HAVE_TIME)
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 #include <windows.h>
 #else
 #include <time.h>
 #endif
+#endif
 
 #if defined(MBEDTLS_FS_IO)
 #include <stdio.h>
@@ -95,10 +97,6 @@
  * concerns. */
 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
 {
-#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
-    /* Allow SHA-1 (weak, but still safe in controlled environments) */
-    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
-#endif
     /* Only SHA-2 hashes */
     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
diff --git a/lib/libmbedtls/mbedtls/library/x509write_crt.c b/lib/libmbedtls/mbedtls/library/x509write_crt.c
index 8f4a4f5..0c5e991 100644
--- a/lib/libmbedtls/mbedtls/library/x509write_crt.c
+++ b/lib/libmbedtls/mbedtls/library/x509write_crt.c
@@ -251,8 +251,7 @@
         return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
 
     c = buf + 5;
-    ku[0] = (unsigned char)( key_usage      );
-    ku[1] = (unsigned char)( key_usage >> 8 );
+    MBEDTLS_PUT_UINT16_LE( key_usage, ku, 0 );
     ret = mbedtls_asn1_write_named_bitstring( &c, buf, ku, 9 );
 
     if( ret < 0 )
@@ -300,7 +299,7 @@
     /*
      * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
      */
-    if( t[0] == '2' && t[1] == '0' && t[2] < '5' )
+    if( t[0] < '2' || ( t[0] == '2' && t[1] == '0' && t[2] < '5' ) )
     {
         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
                                              (const unsigned char *) t + 2,
diff --git a/lib/libmbedtls/mbedtls/library/xtea.c b/lib/libmbedtls/mbedtls/library/xtea.c
index 4b8c9c0..77f6cb6 100644
--- a/lib/libmbedtls/mbedtls/library/xtea.c
+++ b/lib/libmbedtls/mbedtls/library/xtea.c
@@ -37,29 +37,6 @@
 
 #if !defined(MBEDTLS_XTEA_ALT)
 
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-}
-#endif
-
 void mbedtls_xtea_init( mbedtls_xtea_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_xtea_context ) );
@@ -84,7 +61,7 @@
 
     for( i = 0; i < 4; i++ )
     {
-        GET_UINT32_BE( ctx->k[i], key, i << 2 );
+        ctx->k[i] = MBEDTLS_GET_UINT32_BE( key, i << 2 );
     }
 }
 
@@ -98,8 +75,8 @@
 
     k = ctx->k;
 
-    GET_UINT32_BE( v0, input, 0 );
-    GET_UINT32_BE( v1, input, 4 );
+    v0 = MBEDTLS_GET_UINT32_BE( input, 0 );
+    v1 = MBEDTLS_GET_UINT32_BE( input, 4 );
 
     if( mode == MBEDTLS_XTEA_ENCRYPT )
     {
@@ -124,8 +101,8 @@
         }
     }
 
-    PUT_UINT32_BE( v0, output, 0 );
-    PUT_UINT32_BE( v1, output, 4 );
+    MBEDTLS_PUT_UINT32_BE( v0, output, 0 );
+    MBEDTLS_PUT_UINT32_BE( v1, output, 4 );
 
     return( 0 );
 }