Merge remote-tracking branch 'upstream/development' into psa-m-aead-merge

Also fiixed the following merge problems:

crypto_struct.h   : Added MBEDTLS_PRIVATE to psa_aead_operation_s
                    members (merge conflict)
psa_crypto_aead.c : Added ciphertext_length to mbedtls_gcm_finish
                    call (change of API during development)

Signed-off-by: Paul Elliott <paul.elliott@arm.com>
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index f31820a..a5d692c 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -13,13 +13,11 @@
 set(src_crypto
     aes.c
     aesni.c
-    arc4.c
     aria.c
     asn1parse.c
     asn1write.c
     base64.c
     bignum.c
-    blowfish.c
     camellia.c
     ccm.c
     chacha20.c
@@ -42,8 +40,6 @@
     hkdf.c
     hmac_drbg.c
     md.c
-    md2.c
-    md4.c
     md5.c
     memory_buffer_alloc.c
     mps_reader.c
@@ -84,11 +80,8 @@
     timing.c
     version.c
     version_features.c
-    xtea.c
 )
 
-list(APPEND src_crypto ${thirdparty_src})
-
 set(src_x509
     x509.c
     x509_create.c
@@ -111,6 +104,9 @@
     ssl_ticket.c
     ssl_tls.c
     ssl_tls13_keys.c
+    ssl_tls13_server.c
+    ssl_tls13_client.c
+    ssl_tls13_generic.c
 )
 
 if(CMAKE_COMPILER_IS_GNUCC)
@@ -180,6 +176,10 @@
     set_target_properties(${mbedcrypto_static_target} PROPERTIES OUTPUT_NAME mbedcrypto)
     target_link_libraries(${mbedcrypto_static_target} PUBLIC ${libs})
 
+    if(TARGET everest)
+        target_link_libraries(${mbedcrypto_static_target} PUBLIC everest)
+    endif()
+
     add_library(${mbedx509_static_target} STATIC ${src_x509})
     set_target_properties(${mbedx509_static_target} PROPERTIES OUTPUT_NAME mbedx509)
     target_link_libraries(${mbedx509_static_target} PUBLIC ${libs} ${mbedcrypto_static_target})
@@ -191,15 +191,19 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(${mbedcrypto_target} SHARED ${src_crypto})
-    set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.26.0 SOVERSION 6)
+    set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.0.0 SOVERSION 10)
     target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
 
+    if(TARGET everest)
+        target_link_libraries(${mbedcrypto_target} PUBLIC everest)
+    endif()
+
     add_library(${mbedx509_target} SHARED ${src_x509})
-    set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.26.0 SOVERSION 1)
+    set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.0.0 SOVERSION 4)
     target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
 
     add_library(${mbedtls_target} SHARED ${src_tls})
-    set_target_properties(${mbedtls_target} PROPERTIES VERSION 2.26.0 SOVERSION 13)
+    set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.0.0 SOVERSION 16)
     target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
 endif(USE_SHARED_MBEDTLS_LIBRARY)
 
@@ -210,15 +214,14 @@
     # /library needs to be listed explicitly when building .c files outside
     # of /library (which currently means: under /3rdparty).
     target_include_directories(${target}
-        PUBLIC ${MBEDTLS_DIR}/include/
-        PUBLIC ${thirdparty_inc_public}
-        PRIVATE ${MBEDTLS_DIR}/library/
-        PRIVATE ${thirdparty_inc})
-    target_compile_definitions(${target}
-        PRIVATE ${thirdparty_def})
-    install(TARGETS ${target}
-            DESTINATION ${LIB_INSTALL_DIR}
-            PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+        PUBLIC $<BUILD_INTERFACE:${MBEDTLS_DIR}/include/>
+               $<INSTALL_INTERFACE:include/>
+        PRIVATE ${MBEDTLS_DIR}/library/)
+    install(
+        TARGETS ${target}
+        EXPORT MbedTLSTargets
+        DESTINATION ${LIB_INSTALL_DIR}
+        PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
 endforeach(target)
 
 set(lib_target "${MBEDTLS_TARGET_PREFIX}lib")
diff --git a/library/Makefile b/library/Makefile
index 90a477d..13cd7db 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -1,5 +1,5 @@
 
-# Also see "include/mbedtls/config.h"
+# Also see "include/mbedtls/mbedtls_config.h"
 
 CFLAGS	?= -O2
 WARNING_CFLAGS ?=  -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
@@ -41,9 +41,9 @@
 endif
 endif
 
-SOEXT_TLS=so.13
-SOEXT_X509=so.1
-SOEXT_CRYPTO=so.6
+SOEXT_TLS=so.16
+SOEXT_X509=so.4
+SOEXT_CRYPTO=so.10
 
 # Set AR_DASH= (empty string) to use an ar implementation that does not accept
 # the - prefix for command line options (e.g. llvm-ar)
@@ -72,13 +72,11 @@
 OBJS_CRYPTO= \
 	     aes.o \
 	     aesni.o \
-	     arc4.o \
 	     aria.o \
 	     asn1parse.o \
 	     asn1write.o \
 	     base64.o \
 	     bignum.o \
-	     blowfish.o \
 	     camellia.o \
 	     ccm.o \
 	     chacha20.o \
@@ -101,8 +99,6 @@
 	     hkdf.o \
 	     hmac_drbg.o \
 	     md.o \
-	     md2.o \
-	     md4.o \
 	     md5.o \
 	     memory_buffer_alloc.o \
 	     mps_reader.o \
@@ -143,7 +139,6 @@
 	     timing.o \
 	     version.o \
 	     version_features.o \
-	     xtea.o \
 	     # This line is intentionally left blank
 
 include ../3rdparty/Makefile.inc
@@ -172,6 +167,9 @@
 	  ssl_ticket.o \
 	  ssl_tls.o \
 	  ssl_tls13_keys.o \
+	  ssl_tls13_client.o \
+	  ssl_tls13_server.o \
+	  ssl_tls13_generic.o \
 	  # This line is intentionally left blank
 
 .SILENT:
@@ -286,12 +284,12 @@
 
 version_features.c: ../scripts/generate_features.pl
 version_features.c: ../scripts/data_files/version_features.fmt
-## The generated file only depends on the options that are present in config.h,
+## The generated file only depends on the options that are present in mbedtls_config.h,
 ## not on which options are set. To avoid regenerating this file all the time
-## when switching between configurations, don't declare config.h as a
+## when switching between configurations, don't declare mbedtls_config.h as a
 ## dependency. Remove this file from your working tree if you've just added or
-## removed an option in config.h.
-#version_features.c: ../include/mbedtls/config.h
+## removed an option in mbedtls_config.h.
+#version_features.c: ../include/mbedtls/mbedtls_config.h
 version_features.c:
 	echo "  Gen   $@"
 	$(PERL) ../scripts/generate_features.pl
diff --git a/library/aes.c b/library/aes.c
index a15a809..8e3358c 100644
--- a/library/aes.c
+++ b/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 ) );
 
@@ -937,10 +914,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-- )
     {
@@ -951,33 +928,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 ) );
 
@@ -1097,35 +1074,6 @@
 
 #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];
 
 /*
@@ -1141,14 +1089,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 );
 }
 
 /*
diff --git a/library/aesni.h b/library/aesni.h
index c1d22f5..3359cfe 100644
--- a/library/aesni.h
+++ b/library/aesni.h
@@ -25,11 +25,7 @@
 #ifndef MBEDTLS_AESNI_H
 #define MBEDTLS_AESNI_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/aes.h"
 
diff --git a/library/arc4.c b/library/arc4.c
deleted file mode 100644
index b34dc5e..0000000
--- a/library/arc4.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *  An implementation of the ARCFOUR algorithm
- *
- *  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 ARCFOUR algorithm was publicly disclosed on 94/09.
- *
- *  http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
- */
-
-#include "common.h"
-
-#if defined(MBEDTLS_ARC4_C)
-
-#include "mbedtls/arc4.h"
-#include "mbedtls/platform_util.h"
-
-#include <string.h>
-
-#if defined(MBEDTLS_SELF_TEST)
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST */
-
-#if !defined(MBEDTLS_ARC4_ALT)
-
-void mbedtls_arc4_init( mbedtls_arc4_context *ctx )
-{
-    memset( ctx, 0, sizeof( mbedtls_arc4_context ) );
-}
-
-void mbedtls_arc4_free( mbedtls_arc4_context *ctx )
-{
-    if( ctx == NULL )
-        return;
-
-    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
-}
-
-/*
- * ARC4 key schedule
- */
-void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
-                 unsigned int keylen )
-{
-    int i, j, a;
-    unsigned int k;
-    unsigned char *m;
-
-    ctx->x = 0;
-    ctx->y = 0;
-    m = ctx->m;
-
-    for( i = 0; i < 256; i++ )
-        m[i] = (unsigned char) i;
-
-    j = k = 0;
-
-    for( i = 0; i < 256; i++, k++ )
-    {
-        if( k >= keylen ) k = 0;
-
-        a = m[i];
-        j = ( j + a + key[k] ) & 0xFF;
-        m[i] = m[j];
-        m[j] = (unsigned char) a;
-    }
-}
-
-/*
- * ARC4 cipher function
- */
-int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
-                unsigned char *output )
-{
-    int x, y, a, b;
-    size_t i;
-    unsigned char *m;
-
-    x = ctx->x;
-    y = ctx->y;
-    m = ctx->m;
-
-    for( i = 0; i < length; i++ )
-    {
-        x = ( x + 1 ) & 0xFF; a = m[x];
-        y = ( y + a ) & 0xFF; b = m[y];
-
-        m[x] = (unsigned char) b;
-        m[y] = (unsigned char) a;
-
-        output[i] = (unsigned char)
-            ( input[i] ^ m[(unsigned char)( a + b )] );
-    }
-
-    ctx->x = x;
-    ctx->y = y;
-
-    return( 0 );
-}
-
-#endif /* !MBEDTLS_ARC4_ALT */
-
-#if defined(MBEDTLS_SELF_TEST)
-/*
- * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
- *
- * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
- */
-static const unsigned char arc4_test_key[3][8] =
-{
-    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
-    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-};
-
-static const unsigned char arc4_test_pt[3][8] =
-{
-    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-};
-
-static const unsigned char arc4_test_ct[3][8] =
-{
-    { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
-    { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
-    { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
-};
-
-/*
- * Checkup routine
- */
-int mbedtls_arc4_self_test( int verbose )
-{
-    int i, ret = 0;
-    unsigned char ibuf[8];
-    unsigned char obuf[8];
-    mbedtls_arc4_context ctx;
-
-    mbedtls_arc4_init( &ctx );
-
-    for( i = 0; i < 3; i++ )
-    {
-        if( verbose != 0 )
-            mbedtls_printf( "  ARC4 test #%d: ", i + 1 );
-
-        memcpy( ibuf, arc4_test_pt[i], 8 );
-
-        mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 );
-        mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf );
-
-        if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
-        {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
-            ret = 1;
-            goto exit;
-        }
-
-        if( verbose != 0 )
-            mbedtls_printf( "passed\n" );
-    }
-
-    if( verbose != 0 )
-        mbedtls_printf( "\n" );
-
-exit:
-    mbedtls_arc4_free( &ctx );
-
-    return( ret );
-}
-
-#endif /* MBEDTLS_SELF_TEST */
-
-#endif /* MBEDTLS_ARC4_C */
diff --git a/library/aria.c b/library/aria.c
index a5786b3..bc05c4a 100644
--- a/library/aria.c
+++ b/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/library/asn1write.c b/library/asn1write.c
index 0289e89..dc61854 100644
--- a/library/asn1write.c
+++ b/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 );
     }
diff --git a/library/base64.c b/library/base64.c
index 1a05226..9cf5dd4 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -319,9 +319,9 @@
         if( ++n == 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       );
+            if( j > 0 ) *p++ = MBEDTLS_BYTE_2( x );
+            if( j > 1 ) *p++ = MBEDTLS_BYTE_1( x );
+            if( j > 2 ) *p++ = MBEDTLS_BYTE_0( x );
         }
     }
 
diff --git a/library/bignum.c b/library/bignum.c
index c20c6b7..42ec7ac 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -181,8 +181,35 @@
     return( 0 );
 }
 
+/* Resize X to have exactly n limbs and set it to 0. */
+static int mbedtls_mpi_resize_clear( mbedtls_mpi *X, size_t limbs )
+{
+    if( limbs == 0 )
+    {
+        mbedtls_mpi_free( X );
+        return( 0 );
+    }
+    else if( X->n == limbs )
+    {
+        memset( X->p, 0, limbs * ciL );
+        X->s = 1;
+        return( 0 );
+    }
+    else
+    {
+        mbedtls_mpi_free( X );
+        return( mbedtls_mpi_grow( X, limbs ) );
+    }
+}
+
 /*
- * Copy the contents of Y into X
+ * Copy the contents of Y into X.
+ *
+ * This function is not constant-time. Leading zeros in Y may be removed.
+ *
+ * Ensure that X does not shrink. This is not guaranteed by the public API,
+ * but some code in the bignum module relies on this property, for example
+ * in mbedtls_mpi_exp_mod().
  */
 int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
 {
@@ -196,7 +223,11 @@
 
     if( Y->n == 0 )
     {
-        mbedtls_mpi_free( X );
+        if( X->n != 0 )
+        {
+            X->s = 1;
+            memset( X->p, 0, X->n * ciL );
+        }
         return( 0 );
     }
 
@@ -237,6 +268,36 @@
     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.
@@ -249,8 +310,23 @@
                                   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] = dest[i] * ( 1 - assign ) + src[i] * assign;
+        dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
 }
 
 /*
@@ -262,20 +338,34 @@
 {
     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) >> 7;
+    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 = X->s * ( 1 - assign ) + Y->s * assign;
+    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] *= ( 1 - assign );
+        X->p[i] &= ~limb_mask;
 
 cleanup:
     return( ret );
@@ -291,6 +381,7 @@
 {
     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 );
@@ -298,22 +389,35 @@
     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) >> 7;
+    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 = X->s * ( 1 - swap ) + Y->s * swap;
-    Y->s = Y->s * ( 1 - swap ) +    s * swap;
+    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] * ( 1 - swap ) + Y->p[i] * swap;
-        Y->p[i] = Y->p[i] * ( 1 - swap ) +     tmp * swap;
+        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:
@@ -481,6 +585,12 @@
 
     mbedtls_mpi_init( &T );
 
+    if( s[0] == 0 )
+    {
+        mbedtls_mpi_free( X );
+        return( 0 );
+    }
+
     if( s[0] == '-' )
     {
         ++s;
@@ -838,14 +948,7 @@
     size_t const limbs = CHARS_TO_LIMBS( buflen );
 
     /* Ensure that target MPI has exactly the necessary number of limbs */
-    if( X->n != limbs )
-    {
-        mbedtls_mpi_free( X );
-        mbedtls_mpi_init( X );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
-    }
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
 
     for( i = 0; i < buflen; i++ )
         X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
@@ -874,17 +977,11 @@
     MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
 
     /* Ensure that target MPI has exactly the necessary number of limbs */
-    if( X->n != limbs )
-    {
-        mbedtls_mpi_free( X );
-        mbedtls_mpi_init( X );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
-    }
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
 
-    /* Avoid calling `memcpy` with NULL source argument,
+    /* Avoid calling `memcpy` with NULL source or destination argument,
      * even if buflen is 0. */
-    if( buf != NULL )
+    if( buflen != 0 )
     {
         Xp = (unsigned char*) X->p;
         memcpy( Xp + overhead, buf, buflen );
@@ -1490,17 +1587,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 ) );
 }
 
 /*
@@ -1508,17 +1605,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.
@@ -1617,6 +1714,7 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t i, j;
     mbedtls_mpi TA, TB;
+    int result_is_zero = 0;
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( A != NULL );
     MPI_VALIDATE_RET( B != NULL );
@@ -1629,10 +1727,14 @@
     for( i = A->n; i > 0; i-- )
         if( A->p[i - 1] != 0 )
             break;
+    if( i == 0 )
+        result_is_zero = 1;
 
     for( j = B->n; j > 0; j-- )
         if( B->p[j - 1] != 0 )
             break;
+    if( j == 0 )
+        result_is_zero = 1;
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
@@ -1640,7 +1742,14 @@
     for( ; j > 0; j-- )
         mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
 
-    X->s = A->s * B->s;
+    /* If the result is 0, we don't shortcut the operation, which reduces
+     * but does not eliminate side channels leaking the zero-ness. We do
+     * need to take care to set the sign bit properly since the library does
+     * not fully support an MPI object with a value of 0 and s == -1. */
+    if( result_is_zero )
+        X->s = 1;
+    else
+        X->s = A->s * B->s;
 
 cleanup:
 
@@ -1918,16 +2027,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 ) );
 }
 
 /*
@@ -2119,18 +2228,83 @@
 }
 
 /*
+ * 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.
+ *
+ * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
+ * reads the entire table in order to avoid leaking the value of idx to an
+ * attacker able to observe memory access patterns.
+ *
+ * \param[out] R        Where to write the selected MPI.
+ * \param[in] T         The table to read from.
+ * \param[in] T_size    The number of elements in the table.
+ * \param[in] idx       The index of the element to select;
+ *                      this must satisfy 0 <= idx < T_size.
+ *
+ * \return \c 0 on success, or a negative error code.
+ */
+static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    for( size_t i = 0; i < T_size; i++ )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
+                        (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
  * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
  */
 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;
     size_t i, j, nblimbs;
     size_t bufsize, nbits;
     mbedtls_mpi_uint ei, mm, state;
-    mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
+    mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos;
     int neg;
 
     MPI_VALIDATE_RET( X != NULL );
@@ -2154,6 +2328,7 @@
     mpi_montg_init( &mm, N );
     mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
     mbedtls_mpi_init( &Apos );
+    mbedtls_mpi_init( &WW );
     memset( W, 0, sizeof( W ) );
 
     i = mbedtls_mpi_bitlen( E );
@@ -2167,6 +2342,11 @@
 #endif
 
     j = N->n + 1;
+    /* All W[i] and X must have at least N->n limbs for the mpi_montmul()
+     * and mpi_montred() calls later. Here we ensure that W[1] and X are
+     * large enough, and later we'll grow other W[i] to the same length.
+     * They must not be shrunk midway through this function!
+     */
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1],  j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
@@ -2185,26 +2365,34 @@
     /*
      * 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[1] = A * R^2 * R^-1 mod N = A * R mod N
      */
     if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
+    {
         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
+        /* This should be a no-op because W[1] is already that large before
+         * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
+         * in mpi_montmul() below, so let's make sure. */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n + 1 ) );
+    }
     else
         MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
 
+    /* Note that this is safe because W[1] always has at least N->n limbs
+     * (it grew above and was preserved by mbedtls_mpi_copy()). */
     mpi_montmul( &W[1], &RR, N, mm, &T );
 
     /*
@@ -2294,7 +2482,8 @@
             /*
              * X = X * W[wbits] R^-1 mod N
              */
-            mpi_montmul( X, &W[wbits], N, mm, &T );
+            MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) );
+            mpi_montmul( X, &WW, N, mm, &T );
 
             state--;
             nbits = 0;
@@ -2332,8 +2521,9 @@
         mbedtls_mpi_free( &W[i] );
 
     mbedtls_mpi_free( &W[1] ); 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 );
@@ -2360,19 +2550,67 @@
     lz = mbedtls_mpi_lsb( &TA );
     lzt = mbedtls_mpi_lsb( &TB );
 
+    /* The loop below gives the correct result when A==0 but not when B==0.
+     * So have a special case for B==0. Leverage the fact that we just
+     * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
+     * slightly more efficient than cmp_int(). */
+    if( lzt == 0 && mbedtls_mpi_get_bit( &TB, 0 ) == 0 )
+    {
+        ret = mbedtls_mpi_copy( G, A );
+        goto cleanup;
+    }
+
     if( lzt < lz )
         lz = lzt;
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
-
     TA.s = TB.s = 1;
 
+    /* We mostly follow the procedure described in HAC 14.54, but with some
+     * minor differences:
+     * - Sequences of multiplications or divisions by 2 are grouped into a
+     *   single shift operation.
+     * - The procedure in HAC assumes that 0 < TB <= TA.
+     *     - The condition TB <= TA is not actually necessary for correctness.
+     *       TA and TB have symmetric roles except for the loop termination
+     *       condition, and the shifts at the beginning of the loop body
+     *       remove any significance from the ordering of TA vs TB before
+     *       the shifts.
+     *     - If TA = 0, the loop goes through 0 iterations and the result is
+     *       correctly TB.
+     *     - The case TB = 0 was short-circuited above.
+     *
+     * For the correctness proof below, decompose the original values of
+     * A and B as
+     *   A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1
+     *   B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1
+     * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
+     * and gcd(A',B') is odd or 0.
+     *
+     * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
+     * The code maintains the following invariant:
+     *     gcd(A,B) = 2^k * gcd(TA,TB) for some k   (I)
+     */
+
+    /* Proof that the loop terminates:
+     * At each iteration, either the right-shift by 1 is made on a nonzero
+     * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases
+     * by at least 1, or the right-shift by 1 is made on zero and then
+     * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted
+     * since in that case TB is calculated from TB-TA with the condition TB>TA).
+     */
     while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
     {
+        /* Divisions by 2 preserve the invariant (I). */
         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
 
+        /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,
+         * 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
+         * divides TA.
+         */
         if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
         {
             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
@@ -2383,8 +2621,18 @@
             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
             MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
         }
+        /* Note that one of TA or TB is still odd. */
     }
 
+    /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.
+     * At the loop exit, TA = 0, so gcd(TA,TB) = TB.
+     * - If there was at least one loop iteration, then one of TA or TB is odd,
+     *   and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,
+     *   lz = min(a,b) so gcd(A,B) = 2^lz * TB.
+     * - If there was no loop iteration, then A was 0, and gcd(A,B) = B.
+     *   In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.
+     */
+
     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
 
@@ -2395,6 +2643,33 @@
     return( ret );
 }
 
+/* Fill X with n_bytes random bytes.
+ * X must already have room for those bytes.
+ * The ordering of the bytes returned from the RNG is suitable for
+ * deterministic ECDSA (see RFC 6979 §3.3 and mbedtls_mpi_random()).
+ * The size and sign of X are unchanged.
+ * n_bytes must not be 0.
+ */
+static int mpi_fill_random_internal(
+    mbedtls_mpi *X, size_t n_bytes,
+    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    const size_t limbs = CHARS_TO_LIMBS( n_bytes );
+    const size_t overhead = ( limbs * ciL ) - n_bytes;
+
+    if( X->n < limbs )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    memset( X->p, 0, overhead );
+    memset( (unsigned char *) X->p + limbs * ciL, 0, ( X->n - limbs ) * ciL );
+    MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X->p + overhead, n_bytes ) );
+    mpi_bigendian_to_host( X->p, limbs );
+
+cleanup:
+    return( ret );
+}
+
 /*
  * Fill X with size bytes of random.
  *
@@ -2408,30 +2683,96 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t const limbs = CHARS_TO_LIMBS( size );
-    size_t const overhead = ( limbs * ciL ) - size;
-    unsigned char *Xp;
 
     MPI_VALIDATE_RET( X     != NULL );
     MPI_VALIDATE_RET( f_rng != NULL );
 
     /* Ensure that target MPI has exactly the necessary number of limbs */
-    if( X->n != limbs )
-    {
-        mbedtls_mpi_free( X );
-        mbedtls_mpi_init( X );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
-    }
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
+    if( size == 0 )
+        return( 0 );
 
-    Xp = (unsigned char*) X->p;
-    MBEDTLS_MPI_CHK( f_rng( p_rng, Xp + overhead, size ) );
-
-    mpi_bigendian_to_host( X->p, limbs );
+    ret = mpi_fill_random_internal( X, size, f_rng, p_rng );
 
 cleanup:
     return( ret );
 }
 
+int mbedtls_mpi_random( mbedtls_mpi *X,
+                        mbedtls_mpi_sint min,
+                        const mbedtls_mpi *N,
+                        int (*f_rng)(void *, unsigned char *, size_t),
+                        void *p_rng )
+{
+    int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+    int count;
+    unsigned lt_lower = 1, lt_upper = 0;
+    size_t n_bits = mbedtls_mpi_bitlen( N );
+    size_t n_bytes = ( n_bits + 7 ) / 8;
+    mbedtls_mpi lower_bound;
+
+    if( min < 0 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    if( mbedtls_mpi_cmp_int( N, min ) <= 0 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    /*
+     * When min == 0, each try has at worst a probability 1/2 of failing
+     * (the msb has a probability 1/2 of being 0, and then the result will
+     * be < N), so after 30 tries failure probability is a most 2**(-30).
+     *
+     * When N is just below a power of 2, as is the case when generating
+     * a random scalar on most elliptic curves, 1 try is enough with
+     * overwhelming probability. When N is just above a power of 2,
+     * as when generating a random scalar on secp224k1, each try has
+     * a probability of failing that is almost 1/2.
+     *
+     * The probabilities are almost the same if min is nonzero but negligible
+     * compared to N. This is always the case when N is crypto-sized, but
+     * it's convenient to support small N for testing purposes. When N
+     * is small, use a higher repeat count, otherwise the probability of
+     * failure is macroscopic.
+     */
+    count = ( n_bytes > 4 ? 30 : 250 );
+
+    mbedtls_mpi_init( &lower_bound );
+
+    /* Ensure that target MPI has exactly the same number of limbs
+     * as the upper bound, even if the upper bound has leading zeros.
+     * This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
+
+    /*
+     * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
+     * when f_rng is a suitably parametrized instance of HMAC_DRBG:
+     * - use the same byte ordering;
+     * - keep the leftmost n_bits bits of the generated octet string;
+     * - try until result is in the desired range.
+     * This also avoids any bias, which is especially important for ECDSA.
+     */
+    do
+    {
+        MBEDTLS_MPI_CHK( mpi_fill_random_internal( X, n_bytes, f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, 8 * n_bytes - n_bits ) );
+
+        if( --count == 0 )
+        {
+            ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+            goto cleanup;
+        }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, &lt_lower ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &lt_upper ) );
+    }
+    while( lt_lower != 0 || lt_upper == 0 );
+
+cleanup:
+    mbedtls_mpi_free( &lower_bound );
+    return( ret );
+}
+
 /*
  * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64)
  */
diff --git a/library/blowfish.c b/library/blowfish.c
deleted file mode 100644
index 76da448..0000000
--- a/library/blowfish.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- *  Blowfish implementation
- *
- *  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 Blowfish block cipher was designed by Bruce Schneier in 1993.
- *  http://www.schneier.com/blowfish.html
- *  http://en.wikipedia.org/wiki/Blowfish_%28cipher%29
- *
- */
-
-#include "common.h"
-
-#if defined(MBEDTLS_BLOWFISH_C)
-
-#include "mbedtls/blowfish.h"
-#include "mbedtls/platform_util.h"
-
-#include <string.h>
-
-#if !defined(MBEDTLS_BLOWFISH_ALT)
-
-/* Parameter validation macros */
-#define BLOWFISH_VALIDATE_RET( cond )                                       \
-    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA )
-#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,
-        0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
-        0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
-        0x9216D5D9L, 0x8979FB1BL
-};
-
-/* declarations of data at the end of this file */
-static const uint32_t S[4][256];
-
-static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x )
-{
-   unsigned short a, b, c, d;
-   uint32_t  y;
-
-   d = (unsigned short)(x & 0xFF);
-   x >>= 8;
-   c = (unsigned short)(x & 0xFF);
-   x >>= 8;
-   b = (unsigned short)(x & 0xFF);
-   x >>= 8;
-   a = (unsigned short)(x & 0xFF);
-   y = ctx->S[0][a] + ctx->S[1][b];
-   y = y ^ ctx->S[2][c];
-   y = y + ctx->S[3][d];
-
-   return( y );
-}
-
-static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
-{
-    uint32_t  Xl, Xr, temp;
-    short i;
-
-    Xl = *xl;
-    Xr = *xr;
-
-    for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i )
-    {
-        Xl = Xl ^ ctx->P[i];
-        Xr = F( ctx, Xl ) ^ Xr;
-
-        temp = Xl;
-        Xl = Xr;
-        Xr = temp;
-    }
-
-    temp = Xl;
-    Xl = Xr;
-    Xr = temp;
-
-    Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS];
-    Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1];
-
-    *xl = Xl;
-    *xr = Xr;
-}
-
-static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
-{
-    uint32_t  Xl, Xr, temp;
-    short i;
-
-    Xl = *xl;
-    Xr = *xr;
-
-    for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i )
-    {
-        Xl = Xl ^ ctx->P[i];
-        Xr = F( ctx, Xl ) ^ Xr;
-
-        temp = Xl;
-        Xl = Xr;
-        Xr = temp;
-    }
-
-    temp = Xl;
-    Xl = Xr;
-    Xr = temp;
-
-    Xr = Xr ^ ctx->P[1];
-    Xl = Xl ^ ctx->P[0];
-
-    *xl = Xl;
-    *xr = Xr;
-}
-
-void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx )
-{
-    BLOWFISH_VALIDATE( ctx != NULL );
-    memset( ctx, 0, sizeof( mbedtls_blowfish_context ) );
-}
-
-void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx )
-{
-    if( ctx == NULL )
-        return;
-
-    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
-}
-
-/*
- * Blowfish key schedule
- */
-int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx,
-                             const unsigned char *key,
-                             unsigned int keybits )
-{
-    unsigned int i, j, k;
-    uint32_t data, datal, datar;
-    BLOWFISH_VALIDATE_RET( ctx != NULL );
-    BLOWFISH_VALIDATE_RET( key != NULL );
-
-    if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS    ||
-        keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS    ||
-        keybits % 8 != 0 )
-    {
-        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
-    }
-
-    keybits >>= 3;
-
-    for( i = 0; i < 4; i++ )
-    {
-        for( j = 0; j < 256; j++ )
-            ctx->S[i][j] = S[i][j];
-    }
-
-    j = 0;
-    for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i )
-    {
-        data = 0x00000000;
-        for( k = 0; k < 4; ++k )
-        {
-            data = ( data << 8 ) | key[j++];
-            if( j >= keybits )
-                j = 0;
-        }
-        ctx->P[i] = P[i] ^ data;
-    }
-
-    datal = 0x00000000;
-    datar = 0x00000000;
-
-    for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 )
-    {
-        blowfish_enc( ctx, &datal, &datar );
-        ctx->P[i] = datal;
-        ctx->P[i + 1] = datar;
-    }
-
-    for( i = 0; i < 4; i++ )
-    {
-       for( j = 0; j < 256; j += 2 )
-       {
-            blowfish_enc( ctx, &datal, &datar );
-            ctx->S[i][j] = datal;
-            ctx->S[i][j + 1] = datar;
-        }
-    }
-    return( 0 );
-}
-
-/*
- * Blowfish-ECB block encryption/decryption
- */
-int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
-                    int mode,
-                    const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
-                    unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] )
-{
-    uint32_t X0, X1;
-    BLOWFISH_VALIDATE_RET( ctx != NULL );
-    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
-                           mode == MBEDTLS_BLOWFISH_DECRYPT );
-    BLOWFISH_VALIDATE_RET( input  != NULL );
-    BLOWFISH_VALIDATE_RET( output != NULL );
-
-    GET_UINT32_BE( X0, input,  0 );
-    GET_UINT32_BE( X1, input,  4 );
-
-    if( mode == MBEDTLS_BLOWFISH_DECRYPT )
-    {
-        blowfish_dec( ctx, &X0, &X1 );
-    }
-    else /* MBEDTLS_BLOWFISH_ENCRYPT */
-    {
-        blowfish_enc( ctx, &X0, &X1 );
-    }
-
-    PUT_UINT32_BE( X0, output,  0 );
-    PUT_UINT32_BE( X1, output,  4 );
-
-    return( 0 );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-/*
- * Blowfish-CBC buffer encryption/decryption
- */
-int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
-                    int mode,
-                    size_t length,
-                    unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
-                    const unsigned char *input,
-                    unsigned char *output )
-{
-    int i;
-    unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
-    BLOWFISH_VALIDATE_RET( ctx != NULL );
-    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
-                           mode == MBEDTLS_BLOWFISH_DECRYPT );
-    BLOWFISH_VALIDATE_RET( iv != NULL );
-    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
-    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
-
-    if( length % MBEDTLS_BLOWFISH_BLOCKSIZE )
-        return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
-
-    if( mode == MBEDTLS_BLOWFISH_DECRYPT )
-    {
-        while( length > 0 )
-        {
-            memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE );
-            mbedtls_blowfish_crypt_ecb( ctx, mode, input, output );
-
-            for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ )
-                output[i] = (unsigned char)( output[i] ^ iv[i] );
-
-            memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE );
-
-            input  += MBEDTLS_BLOWFISH_BLOCKSIZE;
-            output += MBEDTLS_BLOWFISH_BLOCKSIZE;
-            length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
-        }
-    }
-    else
-    {
-        while( length > 0 )
-        {
-            for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ )
-                output[i] = (unsigned char)( input[i] ^ iv[i] );
-
-            mbedtls_blowfish_crypt_ecb( ctx, mode, output, output );
-            memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE );
-
-            input  += MBEDTLS_BLOWFISH_BLOCKSIZE;
-            output += MBEDTLS_BLOWFISH_BLOCKSIZE;
-            length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
-        }
-    }
-
-    return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-/*
- * Blowfish CFB buffer encryption/decryption
- */
-int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
-                       int mode,
-                       size_t length,
-                       size_t *iv_off,
-                       unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
-                       const unsigned char *input,
-                       unsigned char *output )
-{
-    int c;
-    size_t n;
-
-    BLOWFISH_VALIDATE_RET( ctx != NULL );
-    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
-                           mode == MBEDTLS_BLOWFISH_DECRYPT );
-    BLOWFISH_VALIDATE_RET( iv     != NULL );
-    BLOWFISH_VALIDATE_RET( iv_off != NULL );
-    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
-    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
-
-    n = *iv_off;
-    if( n >= 8 )
-        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
-
-    if( mode == MBEDTLS_BLOWFISH_DECRYPT )
-    {
-        while( length-- )
-        {
-            if( n == 0 )
-                mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
-
-            c = *input++;
-            *output++ = (unsigned char)( c ^ iv[n] );
-            iv[n] = (unsigned char) c;
-
-            n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
-        }
-    }
-    else
-    {
-        while( length-- )
-        {
-            if( n == 0 )
-                mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
-
-            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
-
-            n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
-        }
-    }
-
-    *iv_off = n;
-
-    return( 0 );
-}
-#endif /*MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-/*
- * Blowfish CTR buffer encryption/decryption
- */
-int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
-                       size_t length,
-                       size_t *nc_off,
-                       unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
-                       unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
-                       const unsigned char *input,
-                       unsigned char *output )
-{
-    int c, i;
-    size_t n;
-    BLOWFISH_VALIDATE_RET( ctx != NULL );
-    BLOWFISH_VALIDATE_RET( nonce_counter != NULL );
-    BLOWFISH_VALIDATE_RET( stream_block  != NULL );
-    BLOWFISH_VALIDATE_RET( nc_off != NULL );
-    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
-    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
-
-    n = *nc_off;
-    if( n >= 8 )
-        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
-
-    while( length-- )
-    {
-        if( n == 0 ) {
-            mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter,
-                                stream_block );
-
-            for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- )
-                if( ++nonce_counter[i - 1] != 0 )
-                    break;
-        }
-        c = *input++;
-        *output++ = (unsigned char)( c ^ stream_block[n] );
-
-        n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
-    }
-
-    *nc_off = n;
-
-    return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-static const uint32_t S[4][256] = {
-    {   0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
-        0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
-        0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
-        0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
-        0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
-        0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
-        0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
-        0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
-        0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
-        0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
-        0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
-        0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
-        0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
-        0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
-        0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
-        0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
-        0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
-        0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
-        0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
-        0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
-        0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
-        0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
-        0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
-        0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
-        0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
-        0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
-        0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
-        0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
-        0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
-        0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
-        0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
-        0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
-        0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
-        0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
-        0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
-        0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
-        0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
-        0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
-        0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
-        0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
-        0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
-        0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
-        0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
-        0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
-        0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
-        0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
-        0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
-        0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
-        0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
-        0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
-        0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
-        0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
-        0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
-        0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
-        0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
-        0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
-        0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
-        0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
-        0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
-        0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
-        0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
-        0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
-        0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
-        0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL   },
-    {   0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
-        0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
-        0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
-        0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
-        0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
-        0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
-        0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
-        0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
-        0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
-        0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
-        0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
-        0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
-        0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
-        0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
-        0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
-        0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
-        0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
-        0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
-        0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
-        0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
-        0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
-        0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
-        0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
-        0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
-        0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
-        0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
-        0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
-        0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
-        0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
-        0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
-        0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
-        0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
-        0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
-        0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
-        0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
-        0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
-        0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
-        0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
-        0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
-        0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
-        0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
-        0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
-        0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
-        0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
-        0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
-        0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
-        0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
-        0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
-        0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
-        0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
-        0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
-        0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
-        0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
-        0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
-        0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
-        0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
-        0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
-        0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
-        0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
-        0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
-        0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
-        0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
-        0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
-        0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L   },
-    {   0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
-        0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
-        0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
-        0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
-        0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
-        0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
-        0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
-        0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
-        0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
-        0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
-        0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
-        0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
-        0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
-        0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
-        0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
-        0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
-        0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
-        0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
-        0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
-        0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
-        0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
-        0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
-        0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
-        0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
-        0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
-        0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
-        0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
-        0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
-        0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
-        0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
-        0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
-        0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
-        0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
-        0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
-        0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
-        0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
-        0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
-        0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
-        0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
-        0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
-        0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
-        0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
-        0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
-        0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
-        0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
-        0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
-        0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
-        0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
-        0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
-        0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
-        0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
-        0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
-        0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
-        0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
-        0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
-        0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
-        0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
-        0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
-        0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
-        0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
-        0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
-        0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
-        0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
-        0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L  },
-    {   0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
-        0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
-        0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
-        0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
-        0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
-        0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
-        0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
-        0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
-        0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
-        0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
-        0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
-        0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
-        0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
-        0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
-        0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
-        0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
-        0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
-        0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
-        0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
-        0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
-        0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
-        0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
-        0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
-        0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
-        0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
-        0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
-        0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
-        0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
-        0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
-        0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
-        0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
-        0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
-        0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
-        0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
-        0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
-        0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
-        0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
-        0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
-        0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
-        0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
-        0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
-        0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
-        0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
-        0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
-        0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
-        0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
-        0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
-        0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
-        0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
-        0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
-        0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
-        0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
-        0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
-        0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
-        0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
-        0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
-        0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
-        0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
-        0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
-        0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
-        0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
-        0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
-        0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
-        0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L  }
-};
-
-#endif /* !MBEDTLS_BLOWFISH_ALT */
-#endif /* MBEDTLS_BLOWFISH_C */
diff --git a/library/bn_mul.h b/library/bn_mul.h
index 17d057f..328e765 100644
--- a/library/bn_mul.h
+++ b/library/bn_mul.h
@@ -36,14 +36,50 @@
 #ifndef MBEDTLS_BN_MUL_H
 #define MBEDTLS_BN_MUL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/bignum.h"
 
+
+/*
+ * Conversion macros for embedded constants:
+ * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
+ */
+#if defined(MBEDTLS_HAVE_INT32)
+
+#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d )               \
+    ( (mbedtls_mpi_uint) (a) <<  0 ) |                        \
+    ( (mbedtls_mpi_uint) (b) <<  8 ) |                        \
+    ( (mbedtls_mpi_uint) (c) << 16 ) |                        \
+    ( (mbedtls_mpi_uint) (d) << 24 )
+
+#define MBEDTLS_BYTES_TO_T_UINT_2( a, b )                   \
+    MBEDTLS_BYTES_TO_T_UINT_4( a, b, 0, 0 )
+
+#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
+    MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ),                \
+    MBEDTLS_BYTES_TO_T_UINT_4( e, f, g, h )
+
+#else /* 64-bits */
+
+#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h )   \
+    ( (mbedtls_mpi_uint) (a) <<  0 ) |                        \
+    ( (mbedtls_mpi_uint) (b) <<  8 ) |                        \
+    ( (mbedtls_mpi_uint) (c) << 16 ) |                        \
+    ( (mbedtls_mpi_uint) (d) << 24 ) |                        \
+    ( (mbedtls_mpi_uint) (e) << 32 ) |                        \
+    ( (mbedtls_mpi_uint) (f) << 40 ) |                        \
+    ( (mbedtls_mpi_uint) (g) << 48 ) |                        \
+    ( (mbedtls_mpi_uint) (h) << 56 )
+
+#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d )             \
+    MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
+
+#define MBEDTLS_BYTES_TO_T_UINT_2( a, b )                   \
+    MBEDTLS_BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
+
+#endif /* bits in mbedtls_mpi_uint */
+
 #if defined(MBEDTLS_HAVE_ASM)
 
 #ifndef asm
@@ -189,9 +225,9 @@
         "addq   $8, %%rdi\n"
 
 #define MULADDC_STOP                        \
-        : "+c" (c), "+D" (d), "+S" (s)      \
-        : "b" (b)                           \
-        : "rax", "rdx", "r8"                \
+        : "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \
+        : "b" (b), "m" (*(const uint64_t (*)[16]) s)                 \
+        : "rax", "rdx", "r8"                                         \
     );
 
 #endif /* AMD64 */
diff --git a/library/camellia.c b/library/camellia.c
index f7e0136..29d730a 100644
--- a/library/camellia.c
+++ b/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/library/ccm.c b/library/ccm.c
index 424ee77..15efff7 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -36,31 +36,23 @@
 
 #include <string.h>
 
-#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
 #include <stdio.h>
 #define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+#endif /* MBEDTLS_PLATFORM_C */
 
 #if !defined(MBEDTLS_CCM_ALT)
 
-#define CCM_VALIDATE_RET( cond ) \
-    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT )
-#define CCM_VALIDATE( cond ) \
-    MBEDTLS_INTERNAL_VALIDATE( cond )
-
-#define CCM_ENCRYPT 0
-#define CCM_DECRYPT 1
 
 /*
  * Initialize context
  */
 void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
 {
-    CCM_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
 }
 
@@ -72,9 +64,6 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     const mbedtls_cipher_info_t *cipher_info;
 
-    CCM_VALIDATE_RET( ctx != NULL );
-    CCM_VALIDATE_RET( key != NULL );
-
     cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
                                                    MBEDTLS_MODE_ECB );
     if( cipher_info == NULL )
@@ -108,82 +97,67 @@
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
 }
 
-/*
- * Macros for common operations.
- * Results in smaller compiled code than static inline functions.
- */
-
-/*
- * Update the CBC-MAC state in y using a block in b
- * (Always using b as the source helps the compiler optimise a bit better.)
- */
-#define UPDATE_CBC_MAC                                                      \
-    for( i = 0; i < 16; i++ )                                               \
-        y[i] ^= b[i];                                                       \
-                                                                            \
-    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
-        return( ret );
+#define CCM_STATE__CLEAR                0
+#define CCM_STATE__STARTED              (1 << 0)
+#define CCM_STATE__LENGHTS_SET          (1 << 1)
+#define CCM_STATE__AUTH_DATA_STARTED    (1 << 2)
+#define CCM_STATE__AUTH_DATA_FINISHED   (1 << 3)
+#define CCM_STATE__ERROR                (1 << 4)
 
 /*
  * Encrypt or decrypt a partial block with CTR
- * Warning: using b for temporary storage! src and dst must not be b!
- * This avoids allocating one more 16 bytes buffer while allowing src == dst.
  */
-#define CTR_CRYPT( dst, src, len  )                                            \
-    do                                                                  \
-    {                                                                   \
-        if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr,       \
-                                           16, b, &olen ) ) != 0 )      \
-        {                                                               \
-            return( ret );                                              \
-        }                                                               \
-                                                                        \
-        for( i = 0; i < (len); i++ )                                    \
-            (dst)[i] = (src)[i] ^ b[i];                                 \
-    } while( 0 )
+static int mbedtls_ccm_crypt( mbedtls_ccm_context *ctx,
+                              size_t offset, size_t use_len,
+                              const unsigned char *input,
+                              unsigned char *output )
+{
+    size_t i;
+    size_t olen = 0;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char tmp_buf[16] = {0};
 
-/*
- * Authenticated encryption or decryption
- */
-static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
-                           const unsigned char *iv, size_t iv_len,
-                           const unsigned char *add, size_t add_len,
-                           const unsigned char *input, unsigned char *output,
-                           unsigned char *tag, size_t tag_len )
+    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->ctr, 16, tmp_buf,
+                                       &olen ) ) != 0 )
+    {
+        ctx->state |= CCM_STATE__ERROR;
+        mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf));
+        return ret;
+    }
+
+    for( i = 0; i < use_len; i++ )
+        output[i] = input[i] ^ tmp_buf[offset + i];
+
+    mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf));
+    return ret;
+}
+
+static void mbedtls_ccm_clear_state(mbedtls_ccm_context *ctx) {
+    ctx->state = CCM_STATE__CLEAR;
+    memset( ctx->y, 0, 16);
+    memset( ctx->ctr, 0, 16);
+}
+
+static int ccm_calculate_first_block_if_ready(mbedtls_ccm_context *ctx)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char i;
-    unsigned char q;
     size_t len_left, olen;
-    unsigned char b[16];
-    unsigned char y[16];
-    unsigned char ctr[16];
-    const unsigned char *src;
-    unsigned char *dst;
 
-    /*
-     * Check length requirements: SP800-38C A.1
-     * Additional requirement: a < 2^16 - 2^8 to simplify the code.
-     * 'length' checked later (when writing it to the first block)
-     *
-     * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
+    /* length calulcation can be done only after both
+     * mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() have been executed
      */
-    if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
-        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+    if( !(ctx->state & CCM_STATE__STARTED) || !(ctx->state & CCM_STATE__LENGHTS_SET) )
+        return 0;
 
-    /* Also implies q is within bounds */
-    if( iv_len < 7 || iv_len > 13 )
+    if( ctx->tag_len == 0 && \
+        ( ctx->mode == MBEDTLS_CCM_ENCRYPT || ctx->mode == MBEDTLS_CCM_DECRYPT ) )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
 
-    if( add_len >= 0xFF00 )
-        return( MBEDTLS_ERR_CCM_BAD_INPUT );
-
-    q = 16 - 1 - (unsigned char) iv_len;
-
     /*
-     * First block B_0:
+     * First block:
      * 0        .. 0        flags
-     * 1        .. iv_len   nonce (aka iv)
+     * 1        .. iv_len   nonce (aka iv)  - set by: mbedtls_ccm_starts()
      * iv_len+1 .. 15       length
      *
      * With flags as (bits):
@@ -192,57 +166,40 @@
      * 5 .. 3   (t - 2) / 2
      * 2 .. 0   q - 1
      */
-    b[0] = 0;
-    b[0] |= ( add_len > 0 ) << 6;
-    b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
-    b[0] |= q - 1;
+    ctx->y[0] |= ( ctx->add_len > 0 ) << 6;
+    ctx->y[0] |= ( ( ctx->tag_len - 2 ) / 2 ) << 3;
+    ctx->y[0] |= ctx->q - 1;
 
-    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 );
+    for( i = 0, len_left = ctx->plaintext_len; i < ctx->q; i++, len_left >>= 8 )
+        ctx->y[15-i] = MBEDTLS_BYTE_0( len_left );
 
     if( len_left > 0 )
+    {
+        ctx->state |= CCM_STATE__ERROR;
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+    }
+
+    /* Start CBC-MAC with first block*/
+    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
+    {
+        ctx->state |= CCM_STATE__ERROR;
+        return( ret );
+    }
+
+    return (0);
+}
+
+int mbedtls_ccm_starts( mbedtls_ccm_context *ctx,
+                        int mode,
+                        const unsigned char *iv,
+                        size_t iv_len )
+{
+    /* Also implies q is within bounds */
+    if( iv_len < 7 || iv_len > 13 )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
 
-
-    /* Start CBC-MAC with first block */
-    memset( y, 0, 16 );
-    UPDATE_CBC_MAC;
-
-    /*
-     * If there is additional data, update CBC-MAC with
-     * add_len, add, 0 (padding to a block boundary)
-     */
-    if( add_len > 0 )
-    {
-        size_t use_len;
-        len_left = add_len;
-        src = add;
-
-        memset( b, 0, 16 );
-        b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
-        b[1] = (unsigned char)( ( add_len      ) & 0xFF );
-
-        use_len = len_left < 16 - 2 ? len_left : 16 - 2;
-        memcpy( b + 2, src, use_len );
-        len_left -= use_len;
-        src += use_len;
-
-        UPDATE_CBC_MAC;
-
-        while( len_left > 0 )
-        {
-            use_len = len_left > 16 ? 16 : len_left;
-
-            memset( b, 0, 16 );
-            memcpy( b, src, use_len );
-            UPDATE_CBC_MAC;
-
-            len_left -= use_len;
-            src += use_len;
-        }
-    }
+    ctx->mode = mode;
+    ctx->q = 16 - 1 - (unsigned char) iv_len;
 
     /*
      * Prepare counter block for encryption:
@@ -254,62 +211,290 @@
      * 7 .. 3   0
      * 2 .. 0   q - 1
      */
-    ctr[0] = q - 1;
-    memcpy( ctr + 1, iv, iv_len );
-    memset( ctr + 1 + iv_len, 0, q );
-    ctr[15] = 1;
+    memset( ctx->ctr, 0, 16);
+    ctx->ctr[0] = ctx->q - 1;
+    memcpy( ctx->ctr + 1, iv, iv_len );
+    memset( ctx->ctr + 1 + iv_len, 0, ctx->q );
+    ctx->ctr[15] = 1;
 
     /*
-     * Authenticate and {en,de}crypt the message.
-     *
-     * The only difference between encryption and decryption is
-     * the respective order of authentication and {en,de}cryption.
+     * See ccm_calculate_first_block_if_ready() for block layout description
      */
-    len_left = length;
-    src = input;
-    dst = output;
+    memcpy( ctx->y + 1, iv, iv_len );
 
-    while( len_left > 0 )
+    ctx->state |= CCM_STATE__STARTED;
+    return ccm_calculate_first_block_if_ready(ctx);
+}
+
+int mbedtls_ccm_set_lengths( mbedtls_ccm_context *ctx,
+                             size_t total_ad_len,
+                             size_t plaintext_len,
+                             size_t tag_len )
+{
+    /*
+     * Check length requirements: SP800-38C A.1
+     * Additional requirement: a < 2^16 - 2^8 to simplify the code.
+     * 'length' checked later (when writing it to the first block)
+     *
+     * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
+     */
+    if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    if( total_ad_len >= 0xFF00 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    ctx->plaintext_len = plaintext_len;
+    ctx->add_len = total_ad_len;
+    ctx->tag_len = tag_len;
+    ctx->processed = 0;
+
+    ctx->state |= CCM_STATE__LENGHTS_SET;
+    return ccm_calculate_first_block_if_ready(ctx);
+}
+
+int mbedtls_ccm_update_ad( mbedtls_ccm_context *ctx,
+                           const unsigned char *add,
+                           size_t add_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char i;
+    size_t olen, use_len, offset;
+
+    if( ctx->state & CCM_STATE__ERROR )
     {
-        size_t use_len = len_left > 16 ? 16 : len_left;
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
 
-        if( mode == CCM_ENCRYPT )
+    if( add_len > 0 )
+    {
+        if( ctx->state & CCM_STATE__AUTH_DATA_FINISHED )
         {
-            memset( b, 0, 16 );
-            memcpy( b, src, use_len );
-            UPDATE_CBC_MAC;
+            return MBEDTLS_ERR_CCM_BAD_INPUT;
         }
 
-        CTR_CRYPT( dst, src, use_len );
-
-        if( mode == CCM_DECRYPT )
+        if( !(ctx->state & CCM_STATE__AUTH_DATA_STARTED) )
         {
-            memset( b, 0, 16 );
-            memcpy( b, dst, use_len );
-            UPDATE_CBC_MAC;
+            if ( add_len > ctx->add_len )
+            {
+                return MBEDTLS_ERR_CCM_BAD_INPUT;
+            }
+
+            ctx->y[0] ^= (unsigned char)( ( ctx->add_len >> 8 ) & 0xFF );
+            ctx->y[1] ^= (unsigned char)( ( ctx->add_len      ) & 0xFF );
+
+            ctx->state |= CCM_STATE__AUTH_DATA_STARTED;
+        }
+        else if ( ctx->processed + add_len > ctx->add_len )
+        {
+            return MBEDTLS_ERR_CCM_BAD_INPUT;
         }
 
-        dst += use_len;
-        src += use_len;
-        len_left -= use_len;
+        while( add_len > 0 )
+        {
+            offset = (ctx->processed + 2) % 16; /* account for y[0] and y[1]
+                                                 * holding total auth data length */
+            use_len = 16 - offset;
 
-        /*
-         * Increment counter.
-         * No need to check for overflow thanks to the length check above.
-         */
-        for( i = 0; i < q; i++ )
-            if( ++ctr[15-i] != 0 )
+            if( use_len > add_len )
+                use_len = add_len;
+
+            for( i = 0; i < use_len; i++ )
+                ctx->y[i + offset] ^= add[i];
+
+            ctx->processed += use_len;
+            add_len -= use_len;
+            add += use_len;
+
+            if( use_len + offset == 16 || ctx->processed == ctx->add_len )
+            {
+                if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
+                {
+                    ctx->state |= CCM_STATE__ERROR;
+                    return( ret );
+                }
+            }
+        }
+
+        if( ctx->processed == ctx->add_len )
+        {
+            ctx->state |= CCM_STATE__AUTH_DATA_FINISHED;
+            ctx->processed = 0; // prepare for mbedtls_ccm_update()
+        }
+    }
+
+    return (0);
+}
+
+int mbedtls_ccm_update( mbedtls_ccm_context *ctx,
+                        const unsigned char *input, size_t input_len,
+                        unsigned char *output, size_t output_size,
+                        size_t *output_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char i;
+    size_t use_len, offset, olen;
+
+    unsigned char local_output[16];
+
+    if( ctx->state & CCM_STATE__ERROR )
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    if( ctx->processed + input_len > ctx->plaintext_len )
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    if( output_size < input_len )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+    *output_len = input_len;
+
+    ret = 0;
+
+    while ( input_len > 0 )
+    {
+        offset = ctx->processed % 16;
+
+        use_len = 16 - offset;
+
+        if( use_len > input_len )
+            use_len = input_len;
+
+        ctx->processed += use_len;
+
+        if( ctx->mode == MBEDTLS_CCM_ENCRYPT || \
+            ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT )
+        {
+            for( i = 0; i < use_len; i++ )
+                ctx->y[i + offset] ^= input[i];
+
+            if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
+            {
+                if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
+                {
+                    ctx->state |= CCM_STATE__ERROR;
+                    goto exit;
+                }
+            }
+
+            ret = mbedtls_ccm_crypt( ctx, offset, use_len, input, output );
+            if( ret != 0 )
+                goto exit;
+        }
+
+        if( ctx->mode == MBEDTLS_CCM_DECRYPT || \
+            ctx->mode == MBEDTLS_CCM_STAR_DECRYPT )
+        {
+            /* Since output may be in shared memory, we cannot be sure that
+             * it will contain what we wrote to it. Therefore, we should avoid using
+             * it as input to any operations.
+             * Write decrypted data to local_output to avoid using output variable as
+             * input in the XOR operation for Y.
+             */
+            ret = mbedtls_ccm_crypt( ctx, offset, use_len, input, local_output );
+            if( ret != 0 )
+                goto exit;
+
+            for( i = 0; i < use_len; i++ )
+                ctx->y[i + offset] ^= local_output[i];
+
+            memcpy( output, local_output, use_len );
+            mbedtls_platform_zeroize( local_output, 16 );
+
+            if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
+            {
+                if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
+                {
+                    ctx->state |= CCM_STATE__ERROR;
+                    goto exit;
+                }
+            }
+        }
+
+        if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
+        {
+            for( i = 0; i < ctx->q; i++ )
+            if( ++(ctx->ctr)[15-i] != 0 )
                 break;
+        }
+
+        input_len -= use_len;
+        input += use_len;
+        output += use_len;
+    }
+
+exit:
+    mbedtls_platform_zeroize( local_output, 16 );
+
+    return ret;
+}
+
+int mbedtls_ccm_finish( mbedtls_ccm_context *ctx,
+                        unsigned char *tag, size_t tag_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char i;
+
+    if( ctx->state & CCM_STATE__ERROR )
+    {
+        return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    }
+
+    if( ctx->add_len > 0 && !( ctx->state & CCM_STATE__AUTH_DATA_FINISHED ) )
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    if( ctx->plaintext_len > 0 && ctx->processed != ctx->plaintext_len )
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
     }
 
     /*
      * Authentication: reset counter and crypt/mask internal tag
      */
-    for( i = 0; i < q; i++ )
-        ctr[15-i] = 0;
+    for( i = 0; i < ctx->q; i++ )
+        ctx->ctr[15-i] = 0;
 
-    CTR_CRYPT( y, y, 16 );
-    memcpy( tag, y, tag_len );
+    ret = mbedtls_ccm_crypt( ctx, 0, 16, ctx->y, ctx->y );
+    if( ret != 0 )
+        return ret;
+    if( tag != NULL )
+        memcpy( tag, ctx->y, tag_len );
+    mbedtls_ccm_clear_state(ctx);
+
+    return( 0 );
+}
+
+/*
+ * Authenticated encryption or decryption
+ */
+static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
+                           const unsigned char *iv, size_t iv_len,
+                           const unsigned char *add, size_t add_len,
+                           const unsigned char *input, unsigned char *output,
+                           unsigned char *tag, size_t tag_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t olen;
+
+    if( ( ret = mbedtls_ccm_starts( ctx, mode, iv, iv_len ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_ccm_set_lengths( ctx, add_len, length, tag_len ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_ccm_update_ad( ctx, add, add_len ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_ccm_update( ctx, input, length,
+                                    output, length, &olen ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_ccm_finish( ctx, tag, tag_len ) ) != 0 )
+        return( ret );
 
     return( 0 );
 }
@@ -323,13 +508,7 @@
                          const unsigned char *input, unsigned char *output,
                          unsigned char *tag, size_t tag_len )
 {
-    CCM_VALIDATE_RET( ctx != NULL );
-    CCM_VALIDATE_RET( iv != NULL );
-    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
-    CCM_VALIDATE_RET( length == 0 || input != NULL );
-    CCM_VALIDATE_RET( length == 0 || output != NULL );
-    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
-    return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
+    return( ccm_auth_crypt( ctx, MBEDTLS_CCM_STAR_ENCRYPT, length, iv, iv_len,
                             add, add_len, input, output, tag, tag_len ) );
 }
 
@@ -339,78 +518,75 @@
                          const unsigned char *input, unsigned char *output,
                          unsigned char *tag, size_t tag_len )
 {
-    CCM_VALIDATE_RET( ctx != NULL );
-    CCM_VALIDATE_RET( iv != NULL );
-    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
-    CCM_VALIDATE_RET( length == 0 || input != NULL );
-    CCM_VALIDATE_RET( length == 0 || output != NULL );
-    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
-    if( tag_len == 0 )
-        return( MBEDTLS_ERR_CCM_BAD_INPUT );
-
-    return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
-                add_len, input, output, tag, tag_len ) );
+    return( ccm_auth_crypt( ctx, MBEDTLS_CCM_ENCRYPT, length, iv, iv_len,
+                            add, add_len, input, output, tag, tag_len ) );
 }
 
 /*
  * Authenticated decryption
  */
-int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
-                      const unsigned char *iv, size_t iv_len,
-                      const unsigned char *add, size_t add_len,
-                      const unsigned char *input, unsigned char *output,
-                      const unsigned char *tag, size_t tag_len )
+static int mbedtls_ccm_compare_tags(const unsigned char *tag1, const unsigned char *tag2, size_t tag_len)
 {
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    unsigned char check_tag[16];
     unsigned char i;
     int diff;
 
-    CCM_VALIDATE_RET( ctx != NULL );
-    CCM_VALIDATE_RET( iv != NULL );
-    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
-    CCM_VALIDATE_RET( length == 0 || input != NULL );
-    CCM_VALIDATE_RET( length == 0 || output != NULL );
-    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    /* Check tag in "constant-time" */
+    for( diff = 0, i = 0; i < tag_len; i++ )
+        diff |= tag1[i] ^ tag2[i];
 
-    if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
+    if( diff != 0 )
+    {
+        return( MBEDTLS_ERR_CCM_AUTH_FAILED );
+    }
+
+    return( 0 );
+}
+
+static int ccm_auth_decrypt( mbedtls_ccm_context *ctx, int mode, size_t length,
+                             const unsigned char *iv, size_t iv_len,
+                             const unsigned char *add, size_t add_len,
+                             const unsigned char *input, unsigned char *output,
+                             const unsigned char *tag, size_t tag_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char check_tag[16];
+
+    if( ( ret = ccm_auth_crypt( ctx, mode, length,
                                 iv, iv_len, add, add_len,
                                 input, output, check_tag, tag_len ) ) != 0 )
     {
         return( ret );
     }
 
-    /* Check tag in "constant-time" */
-    for( diff = 0, i = 0; i < tag_len; i++ )
-        diff |= tag[i] ^ check_tag[i];
-
-    if( diff != 0 )
+    if( ( ret = mbedtls_ccm_compare_tags( tag, check_tag, tag_len ) ) != 0 )
     {
         mbedtls_platform_zeroize( output, length );
-        return( MBEDTLS_ERR_CCM_AUTH_FAILED );
+        return( ret );
     }
 
     return( 0 );
 }
 
+int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *add, size_t add_len,
+                      const unsigned char *input, unsigned char *output,
+                      const unsigned char *tag, size_t tag_len )
+{
+    return ccm_auth_decrypt( ctx, MBEDTLS_CCM_STAR_DECRYPT, length,
+                             iv, iv_len, add, add_len,
+                             input, output, tag, tag_len );
+}
+
 int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
                       const unsigned char *iv, size_t iv_len,
                       const unsigned char *add, size_t add_len,
                       const unsigned char *input, unsigned char *output,
                       const unsigned char *tag, size_t tag_len )
 {
-    CCM_VALIDATE_RET( ctx != NULL );
-    CCM_VALIDATE_RET( iv != NULL );
-    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
-    CCM_VALIDATE_RET( length == 0 || input != NULL );
-    CCM_VALIDATE_RET( length == 0 || output != NULL );
-    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
-
-    if( tag_len == 0 )
-        return( MBEDTLS_ERR_CCM_BAD_INPUT );
-
-    return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add,
-                add_len, input, output, tag, tag_len ) );
+    return ccm_auth_decrypt( ctx, MBEDTLS_CCM_DECRYPT, length,
+                             iv, iv_len, add, add_len,
+                             input, output, tag, tag_len );
 }
 #endif /* !MBEDTLS_CCM_ALT */
 
diff --git a/library/chacha20.c b/library/chacha20.c
index 78467d3..658f046 100644
--- a/library/chacha20.c
+++ b/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/library/chachapoly.c b/library/chachapoly.c
index 77d5477..dc75b20 100644
--- a/library/chachapoly.c
+++ b/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/library/cipher.c b/library/cipher.c
index 4f56b52..546cace 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1109,9 +1109,14 @@
 
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+    {
+        size_t output_length;
+        /* The code here doesn't yet support alternative implementations
+         * that can delay up to a block of output. */
         return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
-                                    NULL, 0,
+                                    NULL, 0, &output_length,
                                     tag, tag_len ) );
+    }
 #endif
 
 #if defined(MBEDTLS_CHACHAPOLY_C)
@@ -1158,12 +1163,16 @@
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
     {
+        size_t output_length;
+        /* The code here doesn't yet support alternative implementations
+         * that can delay up to a block of output. */
+
         if( tag_len > sizeof( check_tag ) )
             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
 
         if( 0 != ( ret = mbedtls_gcm_finish(
                        (mbedtls_gcm_context *) ctx->cipher_ctx,
-                       NULL, 0,
+                       NULL, 0, &output_length,
                        check_tag, tag_len ) ) )
         {
             return( ret );
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 7f23387..5776d5e 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -36,10 +36,6 @@
 #include "mbedtls/aes.h"
 #endif
 
-#if defined(MBEDTLS_ARC4_C)
-#include "mbedtls/arc4.h"
-#endif
-
 #if defined(MBEDTLS_CAMELLIA_C)
 #include "mbedtls/camellia.h"
 #endif
@@ -52,10 +48,6 @@
 #include "mbedtls/des.h"
 #endif
 
-#if defined(MBEDTLS_BLOWFISH_C)
-#include "mbedtls/blowfish.h"
-#endif
-
 #if defined(MBEDTLS_CHACHA20_C)
 #include "mbedtls/chacha20.h"
 #endif
@@ -1674,225 +1666,6 @@
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 #endif /* MBEDTLS_DES_C */
 
-#if defined(MBEDTLS_BLOWFISH_C)
-
-static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
-        const unsigned char *input, unsigned char *output )
-{
-    return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input,
-                               output );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
-        size_t length, unsigned char *iv, const unsigned char *input,
-        unsigned char *output )
-{
-    return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv,
-                               input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation,
-        size_t length, size_t *iv_off, unsigned char *iv,
-        const unsigned char *input, unsigned char *output )
-{
-    return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length,
-                                 iv_off, iv, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
-        unsigned char *nonce_counter, unsigned char *stream_block,
-        const unsigned char *input, unsigned char *output )
-{
-    return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off,
-                               nonce_counter, stream_block, input, output );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-
-static int blowfish_setkey_wrap( void *ctx, const unsigned char *key,
-                                 unsigned int key_bitlen )
-{
-    return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen );
-}
-
-static void * blowfish_ctx_alloc( void )
-{
-    mbedtls_blowfish_context *ctx;
-    ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) );
-
-    if( ctx == NULL )
-        return( NULL );
-
-    mbedtls_blowfish_init( ctx );
-
-    return( ctx );
-}
-
-static void blowfish_ctx_free( void *ctx )
-{
-    mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx );
-    mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t blowfish_info = {
-    MBEDTLS_CIPHER_ID_BLOWFISH,
-    blowfish_crypt_ecb_wrap,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-    blowfish_crypt_cbc_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-    blowfish_crypt_cfb64_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
-    NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-    blowfish_crypt_ctr_wrap,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-    NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
-    NULL,
-#endif
-    blowfish_setkey_wrap,
-    blowfish_setkey_wrap,
-    blowfish_ctx_alloc,
-    blowfish_ctx_free
-};
-
-static const mbedtls_cipher_info_t blowfish_ecb_info = {
-    MBEDTLS_CIPHER_BLOWFISH_ECB,
-    MBEDTLS_MODE_ECB,
-    128,
-    "BLOWFISH-ECB",
-    0,
-    MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
-    8,
-    &blowfish_info
-};
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-static const mbedtls_cipher_info_t blowfish_cbc_info = {
-    MBEDTLS_CIPHER_BLOWFISH_CBC,
-    MBEDTLS_MODE_CBC,
-    128,
-    "BLOWFISH-CBC",
-    8,
-    MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
-    8,
-    &blowfish_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-static const mbedtls_cipher_info_t blowfish_cfb64_info = {
-    MBEDTLS_CIPHER_BLOWFISH_CFB64,
-    MBEDTLS_MODE_CFB,
-    128,
-    "BLOWFISH-CFB64",
-    8,
-    MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
-    8,
-    &blowfish_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CFB */
-
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-static const mbedtls_cipher_info_t blowfish_ctr_info = {
-    MBEDTLS_CIPHER_BLOWFISH_CTR,
-    MBEDTLS_MODE_CTR,
-    128,
-    "BLOWFISH-CTR",
-    8,
-    MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
-    8,
-    &blowfish_info
-};
-#endif /* MBEDTLS_CIPHER_MODE_CTR */
-#endif /* MBEDTLS_BLOWFISH_C */
-
-#if defined(MBEDTLS_ARC4_C)
-static int arc4_crypt_stream_wrap( void *ctx, size_t length,
-                                   const unsigned char *input,
-                                   unsigned char *output )
-{
-    return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) );
-}
-
-static int arc4_setkey_wrap( void *ctx, const unsigned char *key,
-                             unsigned int key_bitlen )
-{
-    /* we get key_bitlen in bits, arc4 expects it in bytes */
-    if( key_bitlen % 8 != 0 )
-        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
-
-    mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 );
-    return( 0 );
-}
-
-static void * arc4_ctx_alloc( void )
-{
-    mbedtls_arc4_context *ctx;
-    ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) );
-
-    if( ctx == NULL )
-        return( NULL );
-
-    mbedtls_arc4_init( ctx );
-
-    return( ctx );
-}
-
-static void arc4_ctx_free( void *ctx )
-{
-    mbedtls_arc4_free( (mbedtls_arc4_context *) ctx );
-    mbedtls_free( ctx );
-}
-
-static const mbedtls_cipher_base_t arc4_base_info = {
-    MBEDTLS_CIPHER_ID_ARC4,
-    NULL,
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-    NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-    NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_OFB)
-    NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-    NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_XTS)
-    NULL,
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_STREAM)
-    arc4_crypt_stream_wrap,
-#endif
-    arc4_setkey_wrap,
-    arc4_setkey_wrap,
-    arc4_ctx_alloc,
-    arc4_ctx_free
-};
-
-static const mbedtls_cipher_info_t arc4_128_info = {
-    MBEDTLS_CIPHER_ARC4_128,
-    MBEDTLS_MODE_STREAM,
-    128,
-    "ARC4-128",
-    0,
-    0,
-    1,
-    &arc4_base_info
-};
-#endif /* MBEDTLS_ARC4_C */
-
 #if defined(MBEDTLS_CHACHA20_C)
 
 static int chacha20_setkey_wrap( void *ctx, const unsigned char *key,
@@ -2285,23 +2058,6 @@
 #endif
 #endif /* MBEDTLS_AES_C */
 
-#if defined(MBEDTLS_ARC4_C)
-    { MBEDTLS_CIPHER_ARC4_128,             &arc4_128_info },
-#endif
-
-#if defined(MBEDTLS_BLOWFISH_C)
-    { MBEDTLS_CIPHER_BLOWFISH_ECB,         &blowfish_ecb_info },
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-    { MBEDTLS_CIPHER_BLOWFISH_CBC,         &blowfish_cbc_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CFB)
-    { MBEDTLS_CIPHER_BLOWFISH_CFB64,       &blowfish_cfb64_info },
-#endif
-#if defined(MBEDTLS_CIPHER_MODE_CTR)
-    { MBEDTLS_CIPHER_BLOWFISH_CTR,         &blowfish_ctr_info },
-#endif
-#endif /* MBEDTLS_BLOWFISH_C */
-
 #if defined(MBEDTLS_CAMELLIA_C)
     { MBEDTLS_CIPHER_CAMELLIA_128_ECB,     &camellia_128_ecb_info },
     { MBEDTLS_CIPHER_CAMELLIA_192_ECB,     &camellia_192_ecb_info },
diff --git a/library/cipher_wrap.h b/library/cipher_wrap.h
index 5635982..90563d8 100644
--- a/library/cipher_wrap.h
+++ b/library/cipher_wrap.h
@@ -24,11 +24,7 @@
 #ifndef MBEDTLS_CIPHER_WRAP_H
 #define MBEDTLS_CIPHER_WRAP_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/cipher.h"
 
diff --git a/library/common.h b/library/common.h
index 5845766..780ce37 100644
--- a/library/common.h
+++ b/library/common.h
@@ -23,11 +23,9 @@
 #ifndef MBEDTLS_LIBRARY_COMMON_H
 #define MBEDTLS_LIBRARY_COMMON_H
 
-#if defined(MBEDTLS_CONFIG_FILE)
-#include MBEDTLS_CONFIG_FILE
-#else
-#include "mbedtls/config.h"
-#endif
+#include "mbedtls/build_info.h"
+
+#include <stdint.h>
 
 /** Helper to define a function as static except when building invasive tests.
  *
@@ -50,4 +48,274 @@
 #define MBEDTLS_STATIC_TESTABLE static
 #endif
 
+#if defined(MBEDTLS_TEST_HOOKS)
+extern void (*mbedtls_test_hook_test_fail)( const char * test, int line, const char * file );
+#define MBEDTLS_TEST_HOOK_TEST_ASSERT( TEST ) \
+       do { \
+            if( ( ! ( TEST ) ) && ( ( *mbedtls_test_hook_test_fail ) != NULL ) ) \
+            { \
+              ( *mbedtls_test_hook_test_fail )( #TEST, __LINE__, __FILE__ ); \
+            } \
+    } while( 0 )
+#else
+#define MBEDTLS_TEST_HOOK_TEST_ASSERT( TEST )
+#endif /* defined(MBEDTLS_TEST_HOOKS) */
+
+/** Allow library to access its structs' private members.
+ *
+ * Although structs defined in header files are publicly available,
+ * their members are private and should not be accessed by the user.
+ */
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+/** 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/library/ctr_drbg.c b/library/ctr_drbg.c
index 602ec69..93a7cdc 100644
--- a/library/ctr_drbg.c
+++ b/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;
@@ -304,7 +301,7 @@
 }
 
 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
- * mbedtls_ctr_drbg_update_ret(ctx, additional, add_len)
+ * mbedtls_ctr_drbg_update(ctx, additional, add_len)
  * implements
  * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
  *                      security_strength) -> initial_working_state
@@ -315,7 +312,7 @@
  * and with outputs
  *   ctx = initial_working_state
  */
-int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
+int mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
                                  const unsigned char *additional,
                                  size_t add_len )
 {
@@ -657,7 +654,7 @@
     fclose( f );
     f = NULL;
 
-    ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
+    ret = mbedtls_ctr_drbg_update( ctx, buf, n );
 
 exit:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
diff --git a/library/debug.c b/library/debug.c
index 4be2cba..fa60d13 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -220,8 +220,8 @@
                       const char *text, const mbedtls_mpi *X )
 {
     char str[DEBUG_BUF_SIZE];
-    int j, k, zeros = 1;
-    size_t i, n, idx = 0;
+    size_t bitlen;
+    size_t idx = 0;
 
     if( NULL == ssl              ||
         NULL == ssl->conf        ||
@@ -232,55 +232,43 @@
         return;
     }
 
-    for( n = X->n - 1; n > 0; n-- )
-        if( X->p[n] != 0 )
-            break;
+    bitlen = mbedtls_mpi_bitlen( X );
 
-    for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- )
-        if( ( ( X->p[n] >> j ) & 1 ) != 0 )
-            break;
-
-    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n",
-              text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) );
-
+    mbedtls_snprintf( str, sizeof( str ), "value of '%s' (%u bits) is:\n",
+                      text, (unsigned) bitlen );
     debug_send_line( ssl, level, file, line, str );
 
-    idx = 0;
-    for( i = n + 1, j = 0; i > 0; i-- )
+    if( bitlen == 0 )
     {
-        if( zeros && X->p[i - 1] == 0 )
-            continue;
-
-        for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- )
+        str[0] = ' '; str[1] = '0'; str[2] = '0';
+        idx = 3;
+    }
+    else
+    {
+        int n;
+        for( n = (int) ( ( bitlen - 1 ) / 8 ); n >= 0; n-- )
         {
-            if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 )
-                continue;
-            else
-                zeros = 0;
-
-            if( j % 16 == 0 )
+            size_t limb_offset = n / sizeof( mbedtls_mpi_uint );
+            size_t offset_in_limb = n % sizeof( mbedtls_mpi_uint );
+            unsigned char octet =
+                ( X->p[limb_offset] >> ( offset_in_limb * 8 ) ) & 0xff;
+            mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", octet );
+            idx += 3;
+            /* Wrap lines after 16 octets that each take 3 columns */
+            if( idx >= 3 * 16 )
             {
-                if( j > 0 )
-                {
-                    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
-                    debug_send_line( ssl, level, file, line, str );
-                    idx = 0;
-                }
+                mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
+                debug_send_line( ssl, level, file, line, str );
+                idx = 0;
             }
-
-            idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int)
-                             ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF );
-
-            j++;
         }
-
     }
 
-    if( zeros == 1 )
-        idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" );
-
-    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
-    debug_send_line( ssl, level, file, line, str );
+    if( idx != 0 )
+    {
+        mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
+        debug_send_line( ssl, level, file, line, str );
+    }
 }
 #endif /* MBEDTLS_BIGNUM_C */
 
diff --git a/library/des.c b/library/des.c
index eddf55e..7f90faa 100644
--- a/library/des.c
+++ b/library/des.c
@@ -44,29 +44,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 +400,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 +610,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 +623,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 );
 }
@@ -720,8 +697,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 +722,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 );
 }
diff --git a/library/dhm.c b/library/dhm.c
index 9758af7..2ce0ed4 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -100,22 +100,21 @@
  */
 static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
 {
-    mbedtls_mpi L, U;
+    mbedtls_mpi U;
     int ret = 0;
 
-    mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
+    mbedtls_mpi_init( &U );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
 
-    if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
+    if( mbedtls_mpi_cmp_int( param, 2 ) < 0 ||
         mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
     {
         ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
     }
 
 cleanup:
-    mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
+    mbedtls_mpi_free( &U );
     return( ret );
 }
 
@@ -125,6 +124,47 @@
     memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
 }
 
+size_t mbedtls_dhm_get_bitlen( const mbedtls_dhm_context *ctx )
+{
+    return( mbedtls_mpi_bitlen( &ctx->P ) );
+}
+
+size_t mbedtls_dhm_get_len( const mbedtls_dhm_context *ctx )
+{
+    return( mbedtls_mpi_size( &ctx->P ) );
+}
+
+int mbedtls_dhm_get_value( const mbedtls_dhm_context *ctx,
+                           mbedtls_dhm_parameter param,
+                           mbedtls_mpi *dest )
+{
+    const mbedtls_mpi *src = NULL;
+    switch( param )
+    {
+        case MBEDTLS_DHM_PARAM_P:
+            src = &ctx->P;
+            break;
+        case MBEDTLS_DHM_PARAM_G:
+            src = &ctx->G;
+            break;
+        case MBEDTLS_DHM_PARAM_X:
+            src = &ctx->X;
+            break;
+        case MBEDTLS_DHM_PARAM_GX:
+            src = &ctx->GX;
+            break;
+        case MBEDTLS_DHM_PARAM_GY:
+            src = &ctx->GY;
+            break;
+        case MBEDTLS_DHM_PARAM_K:
+            src = &ctx->K;
+            break;
+        default:
+            return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+    }
+    return( mbedtls_mpi_copy( dest, src ) );
+}
+
 /*
  * Parse the ServerKeyExchange parameters
  */
@@ -145,44 +185,48 @@
     if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
         return( ret );
 
-    ctx->len = mbedtls_mpi_size( &ctx->P );
-
     return( 0 );
 }
 
 /*
- * Setup and write the ServerKeyExchange parameters
+ * Pick a random R in the range [2, M-2] for blinding or key generation.
  */
-int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
-                     unsigned char *output, size_t *olen,
-                     int (*f_rng)(void *, unsigned char *, size_t),
-                     void *p_rng )
+static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
-    int ret, count = 0;
-    size_t n1, n2, n3;
-    unsigned char *p;
-    DHM_VALIDATE_RET( ctx != NULL );
-    DHM_VALIDATE_RET( output != NULL );
-    DHM_VALIDATE_RET( olen != NULL );
-    DHM_VALIDATE_RET( f_rng != NULL );
+    int ret;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_random( R, 3, M, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( R, R, 1 ) );
+
+cleanup:
+    return( ret );
+}
+
+static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng )
+{
+    int ret = 0;
 
     if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+    if( x_size < 0 )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
-    /*
-     * Generate X as large as possible ( < P )
-     */
-    do
+    if( (unsigned) x_size < mbedtls_mpi_size( &ctx->P ) )
     {
         MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
-
-        if( count++ > 10 )
-            return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
     }
-    while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
+    else
+    {
+        /* Generate X as large as possible ( <= P - 2 ) */
+        ret = dhm_random_below( &ctx->X, &ctx->P, f_rng, p_rng );
+        if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+            return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
+        if( ret != 0 )
+            return( ret );
+    }
 
     /*
      * Calculate GX = G^X mod P
@@ -193,16 +237,41 @@
     if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
         return( ret );
 
+cleanup:
+    return( ret );
+}
+
+/*
+ * Setup and write the ServerKeyExchange parameters
+ */
+int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
+                     unsigned char *output, size_t *olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    size_t n1, n2, n3;
+    unsigned char *p;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( output != NULL );
+    DHM_VALIDATE_RET( olen != NULL );
+    DHM_VALIDATE_RET( f_rng != NULL );
+
+    ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
+    if( ret != 0 )
+        goto cleanup;
+
     /*
-     * export P, G, GX
+     * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
+     * not required". We omit leading zeros for compactness.
      */
 #define DHM_MPI_EXPORT( X, n )                                          \
     do {                                                                \
         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 )
 
@@ -217,14 +286,10 @@
 
     *olen = p - output;
 
-    ctx->len = n1;
-
 cleanup:
-
-    if( ret != 0 )
-        return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret ) );
-
-    return( 0 );
+    if( ret != 0 && ret > -128 )
+        ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
+    return( ret );
 }
 
 /*
@@ -245,7 +310,6 @@
         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
     }
 
-    ctx->len = mbedtls_mpi_size( &ctx->P );
     return( 0 );
 }
 
@@ -259,7 +323,7 @@
     DHM_VALIDATE_RET( ctx != NULL );
     DHM_VALIDATE_RET( input != NULL );
 
-    if( ilen < 1 || ilen > ctx->len )
+    if( ilen < 1 || ilen > mbedtls_dhm_get_len( ctx ) )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
     if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
@@ -276,70 +340,25 @@
                      int (*f_rng)(void *, unsigned char *, size_t),
                      void *p_rng )
 {
-    int ret, count = 0;
+    int ret;
     DHM_VALIDATE_RET( ctx != NULL );
     DHM_VALIDATE_RET( output != NULL );
     DHM_VALIDATE_RET( f_rng != NULL );
 
-    if( olen < 1 || olen > ctx->len )
+    if( olen < 1 || olen > mbedtls_dhm_get_len( ctx ) )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
-    if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
-        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
-
-    /*
-     * generate X and calculate GX = G^X mod P
-     */
-    do
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
-
-        if( count++ > 10 )
-            return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
-    }
-    while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
-                          &ctx->P , &ctx->RP ) );
-
-    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
-        return( ret );
+    ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
+    if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED )
+        return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
+    if( ret != 0 )
+        goto cleanup;
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
 
 cleanup:
-
-    if( ret != 0 )
-        return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret ) );
-
-    return( 0 );
-}
-
-/*
- * Pick a random R in the range [2, M) for blinding purposes
- */
-static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
-                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
-{
-    int ret, count;
-
-    count = 0;
-    do
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
-
-        if( count++ > 10 )
-            return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
-    }
-    while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 );
-
-cleanup:
+    if( ret != 0 && ret > -128 )
+        ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
     return( ret );
 }
 
@@ -390,7 +409,7 @@
      * We need to generate blinding values from scratch
      */
 
-    /* Vi = random( 2, P-1 ) */
+    /* Vi = random( 2, P-2 ) */
     MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
 
     /* Vf = Vi^-X mod P
@@ -425,7 +444,10 @@
     DHM_VALIDATE_RET( output != NULL );
     DHM_VALIDATE_RET( olen != NULL );
 
-    if( output_size < ctx->len )
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( output_size < mbedtls_dhm_get_len( ctx ) )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
     if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
@@ -434,28 +456,21 @@
     mbedtls_mpi_init( &GYb );
 
     /* Blind peer's value */
-    if( f_rng != NULL )
-    {
-        MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
-    }
-    else
-        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
+    MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
 
     /* Do modular exponentiation */
     MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
                           &ctx->P, &ctx->RP ) );
 
     /* Unblind secret value */
-    if( f_rng != NULL )
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
-    }
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
 
+    /* Output the secret without any leading zero byte. This is mandatory
+     * for TLS per RFC 5246 §8.1.2. */
     *olen = mbedtls_mpi_size( &ctx->K );
-
     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
 
 cleanup:
@@ -580,8 +595,6 @@
 
     ret = 0;
 
-    dhm->len = mbedtls_mpi_size( &dhm->P );
-
 exit:
 #if defined(MBEDTLS_PEM_PARSE_C)
     mbedtls_pem_free( &pem );
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 9220633..0b612ce 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -648,7 +648,8 @@
  * Convert a signature (given by context) to ASN.1
  */
 static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
-                                    unsigned char *sig, size_t *slen )
+                                    unsigned char *sig, size_t sig_size,
+                                    size_t *slen )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = {0};
@@ -662,6 +663,9 @@
     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
 
+    if( len > sig_size )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
     memcpy( sig, p, len );
     *slen = len;
 
@@ -674,7 +678,7 @@
 int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
                            mbedtls_md_type_t md_alg,
                            const unsigned char *hash, size_t hlen,
-                           unsigned char *sig, size_t *slen,
+                           unsigned char *sig, size_t sig_size, size_t *slen,
                            int (*f_rng)(void *, unsigned char *, size_t),
                            void *p_rng,
                            mbedtls_ecdsa_restart_ctx *rs_ctx )
@@ -712,7 +716,7 @@
 #endif /* MBEDTLS_ECDSA_SIGN_ALT */
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
-    MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
+    MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, sig_size, slen ) );
 
 cleanup:
     mbedtls_mpi_free( &r );
@@ -727,7 +731,7 @@
 int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
                                  mbedtls_md_type_t md_alg,
                                  const unsigned char *hash, size_t hlen,
-                                 unsigned char *sig, size_t *slen,
+                                 unsigned char *sig, size_t sig_size, size_t *slen,
                                  int (*f_rng)(void *, unsigned char *, size_t),
                                  void *p_rng )
 {
@@ -736,7 +740,8 @@
     ECDSA_VALIDATE_RET( sig  != NULL );
     ECDSA_VALIDATE_RET( slen != NULL );
     return( mbedtls_ecdsa_write_signature_restartable(
-                ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
+                ctx, md_alg, hash, hlen, sig, sig_size, slen,
+                f_rng, p_rng, NULL ) );
 }
 
 /*
diff --git a/library/ecjpake.c b/library/ecjpake.c
index 464ff51..738a977 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -128,6 +128,20 @@
     return( ret );
 }
 
+int mbedtls_ecjpake_set_point_format( mbedtls_ecjpake_context *ctx,
+                                      int point_format )
+{
+    switch( point_format )
+    {
+        case MBEDTLS_ECP_PF_UNCOMPRESSED:
+        case MBEDTLS_ECP_PF_COMPRESSED:
+            ctx->point_format = point_format;
+            return( 0 );
+        default:
+            return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+}
+
 /*
  * Check if context is ready for use
  */
@@ -166,10 +180,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 +220,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 +361,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;
 
@@ -948,6 +957,28 @@
     0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
 };
 
+/*
+ * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
+ *
+ * This is the linear congruential generator from numerical recipes,
+ * except we only use the low byte as the output. See
+ * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
+ */
+static int self_test_rng( void *ctx, unsigned char *out, size_t len )
+{
+    static uint32_t state = 42;
+
+    (void) ctx;
+
+    for( size_t i = 0; i < len; i++ )
+    {
+        state = state * 1664525u + 1013904223u;
+        out[i] = (unsigned char) state;
+    }
+
+    return( 0 );
+}
+
 /* Load my private keys and generate the corresponding public keys */
 static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
                               const unsigned char *xm1, size_t len1,
@@ -958,9 +989,9 @@
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
-                                      &ctx->grp.G, NULL, NULL ) );
+                                      &ctx->grp.G, self_test_rng, NULL ) );
     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
-                                      &ctx->grp.G, NULL, NULL ) );
+                                      &ctx->grp.G, self_test_rng, NULL ) );
 
 cleanup:
     return( ret );
diff --git a/library/ecp.c b/library/ecp.c
index 194e448..0212069 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -77,6 +77,7 @@
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
 
+#include "bn_mul.h"
 #include "ecp_invasive.h"
 
 #include <string.h>
@@ -99,17 +100,7 @@
 #define mbedtls_free       free
 #endif
 
-#include "ecp_alt.h"
-
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-#if defined(MBEDTLS_HMAC_DRBG_C)
-#include "mbedtls/hmac_drbg.h"
-#elif defined(MBEDTLS_CTR_DRBG_C)
-#include "mbedtls/ctr_drbg.h"
-#else
-#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
-#endif
-#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
+#include "ecp_internal_alt.h"
 
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
@@ -124,144 +115,6 @@
 static unsigned long add_count, dbl_count, mul_count;
 #endif
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-/*
- * Currently ecp_mul() takes a RNG function as an argument, used for
- * side-channel protection, but it can be NULL. The initial reasoning was
- * that people will pass non-NULL RNG when they care about side-channels, but
- * unfortunately we have some APIs that call ecp_mul() with a NULL RNG, with
- * no opportunity for the user to do anything about it.
- *
- * The obvious strategies for addressing that include:
- * - change those APIs so that they take RNG arguments;
- * - require a global RNG to be available to all crypto modules.
- *
- * Unfortunately those would break compatibility. So what we do instead is
- * have our own internal DRBG instance, seeded from the secret scalar.
- *
- * The following is a light-weight abstraction layer for doing that with
- * HMAC_DRBG (first choice) or CTR_DRBG.
- */
-
-#if defined(MBEDTLS_HMAC_DRBG_C)
-
-/* DRBG context type */
-typedef mbedtls_hmac_drbg_context ecp_drbg_context;
-
-/* DRBG context init */
-static inline void ecp_drbg_init( ecp_drbg_context *ctx )
-{
-    mbedtls_hmac_drbg_init( ctx );
-}
-
-/* DRBG context free */
-static inline void ecp_drbg_free( ecp_drbg_context *ctx )
-{
-    mbedtls_hmac_drbg_free( ctx );
-}
-
-/* DRBG function */
-static inline int ecp_drbg_random( void *p_rng,
-                                   unsigned char *output, size_t output_len )
-{
-    return( mbedtls_hmac_drbg_random( p_rng, output, output_len ) );
-}
-
-/* DRBG context seeding */
-static int ecp_drbg_seed( ecp_drbg_context *ctx,
-                   const mbedtls_mpi *secret, size_t secret_len )
-{
-    int ret;
-    unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES];
-    /* The list starts with strong hashes */
-    const mbedtls_md_type_t md_type = mbedtls_md_list()[0];
-    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_type );
-
-    if( secret_len > MBEDTLS_ECP_MAX_BYTES )
-    {
-        ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
-        goto cleanup;
-    }
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
-                                               secret_bytes, secret_len ) );
-
-    ret = mbedtls_hmac_drbg_seed_buf( ctx, md_info, secret_bytes, secret_len );
-
-cleanup:
-    mbedtls_platform_zeroize( secret_bytes, secret_len );
-
-    return( ret );
-}
-
-#elif defined(MBEDTLS_CTR_DRBG_C)
-
-/* DRBG context type */
-typedef mbedtls_ctr_drbg_context ecp_drbg_context;
-
-/* DRBG context init */
-static inline void ecp_drbg_init( ecp_drbg_context *ctx )
-{
-    mbedtls_ctr_drbg_init( ctx );
-}
-
-/* DRBG context free */
-static inline void ecp_drbg_free( ecp_drbg_context *ctx )
-{
-    mbedtls_ctr_drbg_free( ctx );
-}
-
-/* DRBG function */
-static inline int ecp_drbg_random( void *p_rng,
-                                   unsigned char *output, size_t output_len )
-{
-    return( mbedtls_ctr_drbg_random( p_rng, output, output_len ) );
-}
-
-/*
- * Since CTR_DRBG doesn't have a seed_buf() function the way HMAC_DRBG does,
- * we need to pass an entropy function when seeding. So we use a dummy
- * function for that, and pass the actual entropy as customisation string.
- * (During seeding of CTR_DRBG the entropy input and customisation string are
- * concatenated before being used to update the secret state.)
- */
-static int ecp_ctr_drbg_null_entropy(void *ctx, unsigned char *out, size_t len)
-{
-    (void) ctx;
-    memset( out, 0, len );
-    return( 0 );
-}
-
-/* DRBG context seeding */
-static int ecp_drbg_seed( ecp_drbg_context *ctx,
-                   const mbedtls_mpi *secret, size_t secret_len )
-{
-    int ret;
-    unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES];
-
-    if( secret_len > MBEDTLS_ECP_MAX_BYTES )
-    {
-        ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
-        goto cleanup;
-    }
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
-                                               secret_bytes, secret_len ) );
-
-    ret = mbedtls_ctr_drbg_seed( ctx, ecp_ctr_drbg_null_entropy, NULL,
-                                 secret_bytes, secret_len );
-
-cleanup:
-    mbedtls_platform_zeroize( secret_bytes, secret_len );
-
-    return( ret );
-}
-
-#else
-#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
-#endif /* DRBG modules */
-#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
-
 #if defined(MBEDTLS_ECP_RESTARTABLE)
 /*
  * Maximum number of "basic operations" to be done in a row.
@@ -309,10 +162,6 @@
         ecp_rsm_comb_core,      /* ecp_mul_comb_core()                      */
         ecp_rsm_final_norm,     /* do the final normalization               */
     } state;
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_context drbg_ctx;
-    unsigned char drbg_seeded;
-#endif
 };
 
 /*
@@ -325,10 +174,6 @@
     ctx->T = NULL;
     ctx->T_size = 0;
     ctx->state = ecp_rsm_init;
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_init( &ctx->drbg_ctx );
-    ctx->drbg_seeded = 0;
-#endif
 }
 
 /*
@@ -350,10 +195,6 @@
         mbedtls_free( ctx->T );
     }
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_free( &ctx->drbg_ctx );
-#endif
-
     ecp_restart_rsm_init( ctx );
 }
 
@@ -509,9 +350,9 @@
  *  - readable name
  *
  * Curves are listed in order: largest curves first, and for a given size,
- * fastest curves first. This provides the default order for the SSL module.
+ * fastest curves first.
  *
- * Reminder: update profiles in x509_crt.c when adding a new curves!
+ * Reminder: update profiles in x509_crt.c and ssl_tls.c when adding a new curve!
  */
 static const mbedtls_ecp_curve_info ecp_supported_curves[] =
 {
@@ -729,6 +570,18 @@
 }
 
 /*
+ * Check that the comb table (grp->T) is static initialized.
+ */
+static int ecp_group_is_static_comb_table( const mbedtls_ecp_group *grp ) {
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+    return grp->T != NULL && grp->T_size == 0;
+#else
+    (void) grp;
+    return 0;
+#endif
+}
+
+/*
  * Unallocate (the components of) a group
  */
 void mbedtls_ecp_group_free( mbedtls_ecp_group *grp )
@@ -747,7 +600,7 @@
         mbedtls_mpi_free( &grp->N );
     }
 
-    if( grp->T != NULL )
+    if( !ecp_group_is_static_comb_table(grp) && grp->T != NULL )
     {
         for( i = 0; i < grp->T_size; i++ )
             mbedtls_ecp_point_free( &grp->T[i] );
@@ -1159,8 +1012,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 );
 }
@@ -1701,26 +1553,11 @@
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_mpi l, ll;
-    int count = 0;
-    size_t p_size = ( grp->pbits + 7 ) / 8;
 
     mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll );
 
     /* Generate l such that 1 < l < p */
-    do
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
-
-        if( count++ > 10 )
-        {
-            ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
-            goto cleanup;
-        }
-    }
-    while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
 
     /* Z = l * Z */
     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Z,   &pt->Z,     &l  ) );
@@ -1736,6 +1573,8 @@
 cleanup:
     mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
 
+    if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+        ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
     return( ret );
 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) */
 }
@@ -2069,9 +1908,7 @@
         i = d;
         MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) );
-#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
         if( f_rng != 0 )
-#endif
             MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) );
     }
 
@@ -2205,9 +2042,7 @@
      *
      * Avoid the leak by randomizing coordinates before we normalize them.
      */
-#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
     if( f_rng != 0 )
-#endif
         MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) );
 
     MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
@@ -2245,11 +2080,16 @@
         w++;
 
     /*
-     * Make sure w is within bounds.
+     * If static comb table may not be used (!p_eq_g) or static comb table does
+     * not exists, make sure w is within bounds.
      * (The last test is useful only for very small curves in the test suite.)
+     *
+     * The user reduces MBEDTLS_ECP_WINDOW_SIZE does not changes the size of
+     * static comb table, because the size of static comb table is fixed when
+     * it is generated.
      */
 #if( MBEDTLS_ECP_WINDOW_SIZE < 6 )
-    if( w > MBEDTLS_ECP_WINDOW_SIZE )
+    if( (!p_eq_g || !ecp_group_is_static_comb_table(grp)) && w > MBEDTLS_ECP_WINDOW_SIZE )
         w = MBEDTLS_ECP_WINDOW_SIZE;
 #endif
     if( w >= grp->nbits )
@@ -2282,42 +2122,9 @@
     size_t d;
     unsigned char T_size = 0, T_ok = 0;
     mbedtls_ecp_point *T = NULL;
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_context drbg_ctx;
-
-    ecp_drbg_init( &drbg_ctx );
-#endif
 
     ECP_RS_ENTER( rsm );
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    if( f_rng == NULL )
-    {
-        /* Adjust pointers */
-        f_rng = &ecp_drbg_random;
-#if defined(MBEDTLS_ECP_RESTARTABLE)
-        if( rs_ctx != NULL && rs_ctx->rsm != NULL )
-            p_rng = &rs_ctx->rsm->drbg_ctx;
-        else
-#endif
-            p_rng = &drbg_ctx;
-
-        /* Initialize internal DRBG if necessary */
-#if defined(MBEDTLS_ECP_RESTARTABLE)
-        if( rs_ctx == NULL || rs_ctx->rsm == NULL ||
-            rs_ctx->rsm->drbg_seeded == 0 )
-#endif
-        {
-            const size_t m_len = ( grp->nbits + 7 ) / 8;
-            MBEDTLS_MPI_CHK( ecp_drbg_seed( p_rng, m, m_len ) );
-        }
-#if defined(MBEDTLS_ECP_RESTARTABLE)
-        if( rs_ctx != NULL && rs_ctx->rsm != NULL )
-            rs_ctx->rsm->drbg_seeded = 1;
-#endif
-    }
-#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
-
     /* Is P the base point ? */
 #if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
     p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
@@ -2389,10 +2196,6 @@
 
 cleanup:
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_free( &drbg_ctx );
-#endif
-
     /* does T belong to the group? */
     if( T == grp->T )
         T = NULL;
@@ -2485,25 +2288,10 @@
 #else
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_mpi l;
-    int count = 0;
-    size_t p_size = ( grp->pbits + 7 ) / 8;
     mbedtls_mpi_init( &l );
 
     /* Generate l such that 1 < l < p */
-    do
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
-
-        if( count++ > 10 )
-        {
-            ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
-            goto cleanup;
-        }
-    }
-    while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &l ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->Z, &P->Z, &l ) );
@@ -2511,6 +2299,8 @@
 cleanup:
     mbedtls_mpi_free( &l );
 
+    if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+        ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
     return( ret );
 #endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) */
 }
@@ -2592,22 +2382,10 @@
     unsigned char b;
     mbedtls_ecp_point RP;
     mbedtls_mpi PX;
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_context drbg_ctx;
-
-    ecp_drbg_init( &drbg_ctx );
-#endif
     mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX );
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
     if( f_rng == NULL )
-    {
-        const size_t m_len = ( grp->nbits + 7 ) / 8;
-        MBEDTLS_MPI_CHK( ecp_drbg_seed( &drbg_ctx, m, m_len ) );
-        f_rng = &ecp_drbg_random;
-        p_rng = &drbg_ctx;
-    }
-#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
     /* Save PX and read from P before writing to R, in case P == R */
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) );
@@ -2622,10 +2400,7 @@
     MOD_ADD( RP.X );
 
     /* Randomize coordinates of the starting point */
-#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    if( f_rng != NULL )
-#endif
-        MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
 
     /* Loop invariant: R = result so far, RP = R + P */
     i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */
@@ -2657,18 +2432,10 @@
      *
      * Avoid the leak by randomizing coordinates before we normalize them.
      */
-#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    if( f_rng != NULL )
-#endif
-        MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
-
+    MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
     MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
 
 cleanup:
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_free( &drbg_ctx );
-#endif
-
     mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX );
 
     return( ret );
@@ -2678,8 +2445,11 @@
 
 /*
  * Restartable multiplication R = m * P
+ *
+ * This internal function can be called without an RNG in case where we know
+ * the inputs are not sensitive.
  */
-int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+static int ecp_mul_restartable_internal( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
              const mbedtls_mpi *m, const mbedtls_ecp_point *P,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
              mbedtls_ecp_restart_ctx *rs_ctx )
@@ -2688,10 +2458,6 @@
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
     char is_grp_capable = 0;
 #endif
-    ECP_VALIDATE_RET( grp != NULL );
-    ECP_VALIDATE_RET( R   != NULL );
-    ECP_VALIDATE_RET( m   != NULL );
-    ECP_VALIDATE_RET( P   != NULL );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     /* reset ops count for this call if top-level */
@@ -2745,6 +2511,25 @@
 }
 
 /*
+ * Restartable multiplication R = m * P
+ */
+int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+             mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
+
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    return( ecp_mul_restartable_internal( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
+}
+
+/*
  * Multiplication R = m * P
  */
 int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
@@ -2837,8 +2622,8 @@
     }
     else
     {
-        MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P,
-                                                      NULL, NULL, rs_ctx ) );
+        MBEDTLS_MPI_CHK( ecp_mul_restartable_internal( grp, R, m, P,
+                                                       NULL, NULL, rs_ctx ) );
     }
 
 cleanup:
@@ -2961,6 +2746,97 @@
 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
 
 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
+#define ECP_MPI_INIT_ARRAY(x)   \
+    ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
+/*
+ * Constants for the two points other than 0, 1, -1 (mod p) in
+ * https://cr.yp.to/ecdh.html#validate
+ * See ecp_check_pubkey_x25519().
+ */
+static const mbedtls_mpi_uint x25519_bad_point_1[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ),
+};
+static const mbedtls_mpi_uint x25519_bad_point_2[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ),
+};
+static const mbedtls_mpi ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY(
+        x25519_bad_point_1 );
+static const mbedtls_mpi ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY(
+        x25519_bad_point_2 );
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+
+/*
+ * Check that the input point is not one of the low-order points.
+ * This is recommended by the "May the Fourth" paper:
+ * https://eprint.iacr.org/2017/806.pdf
+ * Those points are never sent by an honest peer.
+ */
+static int ecp_check_bad_points_mx( const mbedtls_mpi *X, const mbedtls_mpi *P,
+                                    const mbedtls_ecp_group_id grp_id )
+{
+    int ret;
+    mbedtls_mpi XmP;
+
+    mbedtls_mpi_init( &XmP );
+
+    /* Reduce X mod P so that we only need to check values less than P.
+     * We know X < 2^256 so we can proceed by subtraction. */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &XmP, X ) );
+    while( mbedtls_mpi_cmp_mpi( &XmP, P ) >= 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &XmP, &XmP, P ) );
+
+    /* Check against the known bad values that are less than P. For Curve448
+     * these are 0, 1 and -1. For Curve25519 we check the values less than P
+     * from the following list: https://cr.yp.to/ecdh.html#validate */
+    if( mbedtls_mpi_cmp_int( &XmP, 1 ) <= 0 ) /* takes care of 0 and 1 */
+    {
+        ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+        goto cleanup;
+    }
+
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+    if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
+    {
+        if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_1 ) == 0 )
+        {
+            ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+            goto cleanup;
+        }
+
+        if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_2 ) == 0 )
+        {
+            ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+            goto cleanup;
+        }
+    }
+#else
+    (void) grp_id;
+#endif
+
+    /* Final check: check if XmP + 1 is P (final because it changes XmP!) */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &XmP, &XmP, 1 ) );
+    if( mbedtls_mpi_cmp_mpi( &XmP, P ) == 0 )
+    {
+        ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    mbedtls_mpi_free( &XmP );
+
+    return( ret );
+}
+
 /*
  * Check validity of a public key for Montgomery curves with x-only schemes
  */
@@ -2972,7 +2848,13 @@
     if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 )
         return( MBEDTLS_ERR_ECP_INVALID_KEY );
 
-    return( 0 );
+    /* Implicit in all standards (as they don't consider negative numbers):
+     * X must be non-negative. This is normally ensured by the way it's
+     * encoded for transmission, but let's be extra sure. */
+    if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 )
+        return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+    return( ecp_check_bad_points_mx( &pt->X, &grp->P, grp->id ) );
 }
 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
 
@@ -3040,6 +2922,56 @@
     return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 }
 
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+MBEDTLS_STATIC_TESTABLE
+int mbedtls_ecp_gen_privkey_mx( size_t high_bit,
+                                mbedtls_mpi *d,
+                                int (*f_rng)(void *, unsigned char *, size_t),
+                                void *p_rng )
+{
+    int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    size_t n_random_bytes = high_bit / 8 + 1;
+
+    /* [Curve25519] page 5 */
+    /* Generate a (high_bit+1)-bit random number by generating just enough
+     * random bytes, then shifting out extra bits from the top (necessary
+     * when (high_bit+1) is not a multiple of 8). */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_random_bytes,
+                                              f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_random_bytes - high_bit - 1 ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, high_bit, 1 ) );
+
+    /* Make sure the last two bits are unset for Curve448, three bits for
+       Curve25519 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
+    if( high_bit == 254 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
+    }
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+static int mbedtls_ecp_gen_privkey_sw(
+    const mbedtls_mpi *N, mbedtls_mpi *d,
+    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret = mbedtls_mpi_random( d, 1, N, f_rng, p_rng );
+    switch( ret )
+    {
+        case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
+            return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
+        default:
+            return( ret );
+    }
+}
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
+
 /*
  * Generate a private key
  */
@@ -3048,89 +2980,21 @@
                      int (*f_rng)(void *, unsigned char *, size_t),
                      void *p_rng )
 {
-    int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
-    size_t n_size;
-
     ECP_VALIDATE_RET( grp   != NULL );
     ECP_VALIDATE_RET( d     != NULL );
     ECP_VALIDATE_RET( f_rng != NULL );
 
-    n_size = ( grp->nbits + 7 ) / 8;
-
 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
-    {
-        /* [M225] page 5 */
-        size_t b;
-
-        do {
-            MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
-        } while( mbedtls_mpi_bitlen( d ) == 0);
-
-        /* Make sure the most significant bit is nbits */
-        b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
-        if( b > grp->nbits )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
-        else
-            MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
-
-        /* Make sure the last two bits are unset for Curve448, three bits for
-           Curve25519 */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
-        if( grp->nbits == 254 )
-        {
-            MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
-        }
-    }
+        return( mbedtls_ecp_gen_privkey_mx( grp->nbits, d, f_rng, p_rng ) );
 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
 
 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
     if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
-    {
-        /* SEC1 3.2.1: Generate d such that 1 <= n < N */
-        int count = 0;
-        unsigned cmp = 0;
-
-        /*
-         * Match the procedure given in RFC 6979 (deterministic ECDSA):
-         * - use the same byte ordering;
-         * - keep the leftmost nbits bits of the generated octet string;
-         * - try until result is in the desired range.
-         * This also avoids any biais, which is especially important for ECDSA.
-         */
-        do
-        {
-            MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
-
-            /*
-             * Each try has at worst a probability 1/2 of failing (the msb has
-             * a probability 1/2 of being 0, and then the result will be < N),
-             * so after 30 tries failure probability is a most 2**(-30).
-             *
-             * For most curves, 1 try is enough with overwhelming probability,
-             * since N starts with a lot of 1s in binary, but some curves
-             * such as secp224k1 are actually very close to the worst case.
-             */
-            if( ++count > 30 )
-            {
-                ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
-                goto cleanup;
-            }
-
-            ret = mbedtls_mpi_lt_mpi_ct( d, &grp->N, &cmp );
-            if( ret != 0 )
-            {
-                goto cleanup;
-            }
-        }
-        while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || cmp != 1 );
-    }
+        return( mbedtls_ecp_gen_privkey_sw( &grp->N, d, f_rng, p_rng ) );
 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
 
-cleanup:
-    return( ret );
+    return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 }
 
 /*
@@ -3189,6 +3053,7 @@
 }
 
 #define ECP_CURVE25519_KEY_SIZE 32
+#define ECP_CURVE448_KEY_SIZE   56
 /*
  * Read a private key.
  */
@@ -3209,12 +3074,12 @@
     if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
     {
         /*
-         * If it is Curve25519 curve then mask the key as mandated by RFC7748
+         * Mask the key as mandated by RFC7748 for Curve25519 and Curve448.
          */
         if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
         {
             if( buflen != ECP_CURVE25519_KEY_SIZE )
-                return MBEDTLS_ERR_ECP_INVALID_KEY;
+                return( MBEDTLS_ERR_ECP_INVALID_KEY );
 
             MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) );
 
@@ -3235,8 +3100,23 @@
                                          ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 )
                     );
         }
-        else
-            ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+        else if( grp_id == MBEDTLS_ECP_DP_CURVE448 )
+        {
+            if( buflen != ECP_CURVE448_KEY_SIZE )
+                return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) );
+
+            /* Set the two least significant bits to 0 */
+            MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) );
+
+            /* Set the most significant bit to 1 */
+            MBEDTLS_MPI_CHK(
+                    mbedtls_mpi_set_bit( &key->d,
+                                         ECP_CURVE448_KEY_SIZE * 8 - 1, 1 )
+                    );
+        }
     }
 
 #endif
@@ -3274,14 +3154,16 @@
         if( key->grp.id == MBEDTLS_ECP_DP_CURVE25519 )
         {
             if( buflen < ECP_CURVE25519_KEY_SIZE )
-                return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+                return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
 
-            MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &key->d, buf, buflen ) );
         }
-        else
-            ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+        else if( key->grp.id == MBEDTLS_ECP_DP_CURVE448 )
+        {
+            if( buflen < ECP_CURVE448_KEY_SIZE )
+                return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+        }
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &key->d, buf, buflen ) );
     }
-
 #endif
 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
     if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
@@ -3299,7 +3181,9 @@
 /*
  * Check a public-private key pair
  */
-int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
+int mbedtls_ecp_check_pub_priv(
+        const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_ecp_point Q;
@@ -3323,7 +3207,7 @@
     mbedtls_ecp_group_copy( &grp, &prv->grp );
 
     /* Also checks d is valid */
-    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, f_rng, p_rng ) );
 
     if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) ||
         mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) ||
@@ -3342,6 +3226,28 @@
 
 #if defined(MBEDTLS_SELF_TEST)
 
+/*
+ * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
+ *
+ * This is the linear congruential generator from numerical recipes,
+ * except we only use the low byte as the output. See
+ * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
+ */
+static int self_test_rng( void *ctx, unsigned char *out, size_t len )
+{
+    static uint32_t state = 42;
+
+    (void) ctx;
+
+    for( size_t i = 0; i < len; i++ )
+    {
+        state = state * 1664525u + 1013904223u;
+        out[i] = (unsigned char) state;
+    }
+
+    return( 0 );
+}
+
 /* Adjust the exponent to be a valid private point for the specified curve.
  * This is sometimes necessary because we use a single set of exponents
  * for all curves but the validity of values depends on the curve. */
@@ -3397,7 +3303,7 @@
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[0] ) );
     MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
-    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, self_test_rng, NULL ) );
 
     for( i = 1; i < n_exponents; i++ )
     {
@@ -3410,7 +3316,7 @@
 
         MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[i] ) );
         MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
-        MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
+        MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, self_test_rng, NULL ) );
 
         if( add_count != add_c_prev ||
             dbl_count != dbl_c_prev ||
@@ -3488,7 +3394,7 @@
         mbedtls_printf( "  ECP SW test #1 (constant op_count, base point G): " );
     /* Do a dummy multiplication first to trigger precomputation */
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
-    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, self_test_rng, NULL ) );
     ret = self_test_point( verbose,
                            &grp, &R, &m, &grp.G,
                            sw_exponents,
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 165c315..421a067 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -25,6 +25,7 @@
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
 
+#include "bn_mul.h"
 #include "ecp_invasive.h"
 
 #include <string.h>
@@ -42,516 +43,15 @@
 #define inline __inline
 #endif
 
-/*
- * Conversion macros for embedded constants:
- * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
- */
-#if defined(MBEDTLS_HAVE_INT32)
+#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
 
-#define BYTES_TO_T_UINT_4( a, b, c, d )                       \
-    ( (mbedtls_mpi_uint) (a) <<  0 ) |                        \
-    ( (mbedtls_mpi_uint) (b) <<  8 ) |                        \
-    ( (mbedtls_mpi_uint) (c) << 16 ) |                        \
-    ( (mbedtls_mpi_uint) (d) << 24 )
+#define ECP_MPI_INIT_ARRAY(x)   \
+    ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
 
-#define BYTES_TO_T_UINT_2( a, b )                   \
-    BYTES_TO_T_UINT_4( a, b, 0, 0 )
-
-#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
-    BYTES_TO_T_UINT_4( a, b, c, d ),                \
-    BYTES_TO_T_UINT_4( e, f, g, h )
-
-#else /* 64-bits */
-
-#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
-    ( (mbedtls_mpi_uint) (a) <<  0 ) |                        \
-    ( (mbedtls_mpi_uint) (b) <<  8 ) |                        \
-    ( (mbedtls_mpi_uint) (c) << 16 ) |                        \
-    ( (mbedtls_mpi_uint) (d) << 24 ) |                        \
-    ( (mbedtls_mpi_uint) (e) << 32 ) |                        \
-    ( (mbedtls_mpi_uint) (f) << 40 ) |                        \
-    ( (mbedtls_mpi_uint) (g) << 48 ) |                        \
-    ( (mbedtls_mpi_uint) (h) << 56 )
-
-#define BYTES_TO_T_UINT_4( a, b, c, d )             \
-    BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
-
-#define BYTES_TO_T_UINT_2( a, b )                   \
-    BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
-
-#endif /* bits in mbedtls_mpi_uint */
-
-/*
- * Note: the constants are in little-endian order
- * to be directly usable in MPIs
- */
-
-/*
- * Domain parameters for secp192r1
- */
-#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
-static const mbedtls_mpi_uint secp192r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-static const mbedtls_mpi_uint secp192r1_b[] = {
-    BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
-    BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
-    BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
-};
-static const mbedtls_mpi_uint secp192r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
-    BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
-};
-static const mbedtls_mpi_uint secp192r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
-    BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
-    BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
-};
-static const mbedtls_mpi_uint secp192r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
-    BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
-
-/*
- * Domain parameters for secp224r1
- */
-#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
-static const mbedtls_mpi_uint secp224r1_p[] = {
-    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
-};
-static const mbedtls_mpi_uint secp224r1_b[] = {
-    BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
-    BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
-    BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
-    BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
-};
-static const mbedtls_mpi_uint secp224r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
-    BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
-    BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
-    BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
-};
-static const mbedtls_mpi_uint secp224r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
-    BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
-    BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
-    BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
-};
-static const mbedtls_mpi_uint secp224r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
-    BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
-
-/*
- * Domain parameters for secp256r1
- */
-#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
-static const mbedtls_mpi_uint secp256r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-static const mbedtls_mpi_uint secp256r1_b[] = {
-    BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
-    BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
-    BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
-    BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
-};
-static const mbedtls_mpi_uint secp256r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
-    BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
-    BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
-    BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
-};
-static const mbedtls_mpi_uint secp256r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
-    BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
-    BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
-    BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
-};
-static const mbedtls_mpi_uint secp256r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
-    BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
-
-/*
- * Domain parameters for secp384r1
- */
-#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
-static const mbedtls_mpi_uint secp384r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-static const mbedtls_mpi_uint secp384r1_b[] = {
-    BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
-    BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
-    BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
-    BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
-    BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
-    BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
-};
-static const mbedtls_mpi_uint secp384r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
-    BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
-    BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
-    BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
-    BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
-    BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
-};
-static const mbedtls_mpi_uint secp384r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
-    BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
-    BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
-    BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
-    BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
-    BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
-};
-static const mbedtls_mpi_uint secp384r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
-    BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
-    BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
-
-/*
- * Domain parameters for secp521r1
- */
-#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
-static const mbedtls_mpi_uint secp521r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
-};
-static const mbedtls_mpi_uint secp521r1_b[] = {
-    BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
-    BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
-    BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
-    BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
-    BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
-    BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
-    BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
-    BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
-    BYTES_TO_T_UINT_2( 0x51, 0x00 ),
-};
-static const mbedtls_mpi_uint secp521r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
-    BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
-    BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
-    BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
-    BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
-    BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
-    BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
-    BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
-    BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
-};
-static const mbedtls_mpi_uint secp521r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
-    BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
-    BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
-    BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
-    BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
-    BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
-    BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
-    BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
-    BYTES_TO_T_UINT_2( 0x18, 0x01 ),
-};
-static const mbedtls_mpi_uint secp521r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
-    BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
-    BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
-    BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
-    BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
-};
-#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
-static const mbedtls_mpi_uint secp192k1_p[] = {
-    BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-static const mbedtls_mpi_uint secp192k1_a[] = {
-    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
-};
-static const mbedtls_mpi_uint secp192k1_b[] = {
-    BYTES_TO_T_UINT_2( 0x03, 0x00 ),
-};
-static const mbedtls_mpi_uint secp192k1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
-    BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
-    BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
-};
-static const mbedtls_mpi_uint secp192k1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
-    BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
-    BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
-};
-static const mbedtls_mpi_uint secp192k1_n[] = {
-    BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
-    BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
-static const mbedtls_mpi_uint secp224k1_p[] = {
-    BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-static const mbedtls_mpi_uint secp224k1_a[] = {
-    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
-};
-static const mbedtls_mpi_uint secp224k1_b[] = {
-    BYTES_TO_T_UINT_2( 0x05, 0x00 ),
-};
-static const mbedtls_mpi_uint secp224k1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
-    BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
-    BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
-    BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
-};
-static const mbedtls_mpi_uint secp224k1_gy[] = {
-    BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
-    BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
-    BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
-    BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
-};
-static const mbedtls_mpi_uint secp224k1_n[] = {
-    BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
-    BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
-};
-#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
-
-#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
-static const mbedtls_mpi_uint secp256k1_p[] = {
-    BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-static const mbedtls_mpi_uint secp256k1_a[] = {
-    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
-};
-static const mbedtls_mpi_uint secp256k1_b[] = {
-    BYTES_TO_T_UINT_2( 0x07, 0x00 ),
-};
-static const mbedtls_mpi_uint secp256k1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
-    BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
-    BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
-    BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
-};
-static const mbedtls_mpi_uint secp256k1_gy[] = {
-    BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
-    BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
-    BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
-    BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
-};
-static const mbedtls_mpi_uint secp256k1_n[] = {
-    BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
-    BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
-    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-};
-#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
-
-/*
- * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
- */
-#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
-static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
-    BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
-    BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
-    BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
-    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
-};
-static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
-    BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
-    BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
-    BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
-    BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
-};
-static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
-    BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
-    BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
-    BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
-    BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
-};
-static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
-    BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
-    BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
-    BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
-};
-static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
-    BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
-    BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
-    BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
-};
-static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
-    BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
-    BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
-    BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
-    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
-};
-#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
-
-/*
- * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
- */
-#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
-static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
-    BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
-    BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
-    BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
-    BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
-    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
-    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
-};
-static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
-    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
-    BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
-    BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
-    BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
-    BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
-    BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
-};
-static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
-    BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
-    BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
-    BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
-    BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
-    BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
-    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
-};
-static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
-    BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
-    BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
-    BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
-    BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
-    BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
-};
-static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
-    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
-    BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
-    BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
-    BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
-    BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
-};
-static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
-    BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
-    BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
-    BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
-    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
-    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
-};
-#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
-
-/*
- * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
- */
-#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
-static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
-    BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
-    BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
-    BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
-    BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
-    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
-    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
-    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
-};
-static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
-    BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
-    BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
-    BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
-    BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
-    BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
-    BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
-    BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
-    BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
-};
-static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
-    BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
-    BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
-    BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
-    BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
-    BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
-    BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
-    BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
-    BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
-};
-static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
-    BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
-    BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
-    BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
-    BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
-    BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
-    BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
-    BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
-};
-static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
-    BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
-    BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
-    BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
-    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
-    BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
-    BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
-    BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
-};
-static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
-    BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
-    BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
-    BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
-    BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
-    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
-    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
-    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
-};
-#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+#define ECP_POINT_INIT_XY_Z0(x, y) { \
+    ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(1, 0, NULL) }
+#define ECP_POINT_INIT_XY_Z1(x, y) { \
+    ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(1, 1, mpi_one) }
 
 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) ||   \
     defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) ||   \
@@ -566,8 +66,4446 @@
     defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
 /* For these curves, we build the group parameters dynamically. */
 #define ECP_LOAD_GROUP
+static mbedtls_mpi_uint mpi_one[] = {1};
 #endif
 
+/*
+ * Note: the constants are in little-endian order
+ * to be directly usable in MPIs
+ */
+
+/*
+ * Domain parameters for secp192r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+static const mbedtls_mpi_uint secp192r1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp192r1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
+};
+static const mbedtls_mpi_uint secp192r1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
+};
+static const mbedtls_mpi_uint secp192r1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
+};
+static const mbedtls_mpi_uint secp192r1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint secp192r1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x9E, 0xE3, 0x60, 0x59, 0xD1, 0xC4, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0xBD, 0x22, 0xD7, 0x2D, 0x07, 0xBD, 0xB6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x2A, 0xCF, 0x33, 0xF0, 0xBE, 0xD1, 0xED ),
+};
+static const mbedtls_mpi_uint secp192r1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0x71, 0x4B, 0xA8, 0xED, 0x7E, 0xC9, 0x1A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x2A, 0xF6, 0xDF, 0x0E, 0xE8, 0x4C, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x35, 0xF7, 0x8A, 0xC3, 0xEC, 0xDE, 0x1E ),
+};
+static const mbedtls_mpi_uint secp192r1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x67, 0xC2, 0x1D, 0x32, 0x8F, 0x10, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x2D, 0x17, 0xF3, 0xE4, 0xFE, 0xD8, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0x45, 0x10, 0x70, 0x2C, 0x3E, 0x52, 0x3E ),
+};
+static const mbedtls_mpi_uint secp192r1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0xF1, 0x04, 0x5D, 0xEE, 0xD4, 0x56, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0xB7, 0x38, 0x27, 0x61, 0xAA, 0x81, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x37, 0xD7, 0x0E, 0x29, 0x0E, 0x11, 0x14 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0x35, 0x52, 0xC6, 0x31, 0xB7, 0x27, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xD4, 0x15, 0x98, 0x0F, 0xE7, 0xF3, 0x6A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0x31, 0x70, 0x35, 0x09, 0xA0, 0x2B, 0xC2 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x75, 0xA7, 0x4C, 0x88, 0xCF, 0x5B, 0xE4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0x17, 0x48, 0x8D, 0xF2, 0xF0, 0x86, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0xCF, 0xFE, 0x6B, 0xB0, 0xA5, 0x06, 0xAB ),
+};
+static const mbedtls_mpi_uint secp192r1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0x6A, 0xDC, 0x9A, 0x6D, 0x7B, 0x47, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0xFC, 0x51, 0x12, 0x62, 0x66, 0x0B, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0x40, 0x93, 0xA0, 0xB5, 0x5A, 0x58, 0xD7 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0xCB, 0xAF, 0xDC, 0x0B, 0xA1, 0x26, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x36, 0x9D, 0xA3, 0xD7, 0x3B, 0xAD, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x3B, 0x05, 0x9A, 0xA8, 0xAA, 0x69, 0xB2 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xD9, 0xD1, 0x4D, 0x4A, 0x6E, 0x96, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0x66, 0x32, 0x39, 0xC6, 0x57, 0x7D, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0xA0, 0x36, 0xC2, 0x45, 0xF9, 0x00, 0x62 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xEF, 0x59, 0x46, 0xDC, 0x60, 0xD9, 0x8F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0xB0, 0xE9, 0x41, 0xA4, 0x87, 0x76, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0xD4, 0x0E, 0xB2, 0xFA, 0x16, 0x56, 0xDC ),
+};
+static const mbedtls_mpi_uint secp192r1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0x62, 0xD2, 0xB1, 0x34, 0xB2, 0xF1, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB2, 0xED, 0x55, 0xC5, 0x47, 0xB5, 0x07, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xF6, 0x2F, 0x94, 0xC3, 0xDD, 0x54, 0x2F ),
+};
+static const mbedtls_mpi_uint secp192r1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xA6, 0xD4, 0x8C, 0xA9, 0xCE, 0x4D, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x4B, 0x46, 0xCC, 0xB2, 0x55, 0xC8, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0xAE, 0x31, 0xED, 0x89, 0x65, 0x59, 0x55 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0x0A, 0xD1, 0x1A, 0xC5, 0xF6, 0xEA, 0x43 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0xFC, 0x0C, 0x1A, 0xFB, 0xA0, 0xC8, 0x70 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0xFD, 0x53, 0x6F, 0x6D, 0xBF, 0xBA, 0xAF ),
+};
+static const mbedtls_mpi_uint secp192r1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0xB0, 0x7D, 0x83, 0x96, 0xE3, 0xCB, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x6E, 0x55, 0x2C, 0x20, 0x53, 0x2F, 0x46 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0x66, 0x00, 0x17, 0x08, 0xFE, 0xAC, 0x31 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x12, 0x97, 0x3A, 0xC7, 0x57, 0x45, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x25, 0x99, 0x00, 0xF6, 0x97, 0xB4, 0x64 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x74, 0xE6, 0xE6, 0xA3, 0xDF, 0x9C, 0xCC ),
+};
+static const mbedtls_mpi_uint secp192r1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0xF4, 0x76, 0xD5, 0x5F, 0x2A, 0xFD, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x80, 0x7E, 0x3E, 0xE5, 0xE8, 0xD6, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0xAD, 0x1E, 0x70, 0x79, 0x3E, 0x3D, 0x83 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x15, 0xBB, 0xB3, 0x42, 0x6A, 0xA1, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x58, 0xCB, 0x43, 0x25, 0x00, 0x14, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x4E, 0x93, 0x11, 0xE0, 0x32, 0x54, 0x98 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x52, 0xA2, 0xB4, 0x57, 0x32, 0xB9, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x43, 0xA1, 0xB1, 0xFB, 0x01, 0xE1, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xFB, 0x5A, 0x11, 0xB8, 0xC2, 0x03, 0xE5 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x2B, 0x71, 0x26, 0x4E, 0x7C, 0xC5, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0xF5, 0xD3, 0xA8, 0xE4, 0x95, 0x48, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0xAE, 0xD9, 0x5D, 0x9F, 0x6A, 0x22, 0xAD ),
+};
+static const mbedtls_mpi_uint secp192r1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0xCC, 0xA3, 0x4D, 0xA0, 0x1C, 0x34, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0x3C, 0x62, 0xF8, 0x5E, 0xA6, 0x58, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x6E, 0x66, 0x8A, 0x3D, 0x17, 0xFF, 0x0F ),
+};
+static const mbedtls_mpi_uint secp192r1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xCD, 0xA8, 0xDD, 0xD1, 0x20, 0x5C, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0xFE, 0x17, 0xE2, 0xCF, 0xEA, 0x63, 0xDE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x51, 0xC9, 0x16, 0xDE, 0xB4, 0xB2, 0xDD ),
+};
+static const mbedtls_mpi_uint secp192r1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xBE, 0x12, 0xD7, 0xA3, 0x0A, 0x50, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0x87, 0xC5, 0x8A, 0x76, 0x57, 0x07, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0x1F, 0xC6, 0x1B, 0x66, 0xC4, 0x3D, 0x8A ),
+};
+static const mbedtls_mpi_uint secp192r1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0xA4, 0x85, 0x13, 0x8F, 0xA7, 0x35, 0x19 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0x0D, 0xFD, 0xFF, 0x1B, 0xD1, 0xD6, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x7A, 0xD0, 0xC3, 0xB4, 0xEF, 0x39, 0x66 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0xFE, 0xA5, 0x9C, 0x34, 0x30, 0x49, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0xC5, 0x39, 0x26, 0x06, 0xE3, 0x01, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0x2B, 0x66, 0xFC, 0x95, 0x5F, 0x35, 0xF7 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0xCF, 0x54, 0x63, 0x99, 0x57, 0x05, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x6F, 0x00, 0x5F, 0x65, 0x08, 0x47, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x2A, 0x90, 0x6D, 0x67, 0xC6, 0xBC, 0x45 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0x4D, 0x88, 0x0A, 0x35, 0x9E, 0x33, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x17, 0x0C, 0xF8, 0xE1, 0x7A, 0x49, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x44, 0x06, 0x8F, 0x0B, 0x70, 0x2F, 0x71 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0x4B, 0xCB, 0xF9, 0x8E, 0x6A, 0xDA, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x43, 0xA1, 0x3F, 0xCE, 0x17, 0xD2, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x0D, 0xD2, 0x6C, 0x82, 0x37, 0xE5, 0xFC ),
+};
+static const mbedtls_mpi_uint secp192r1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4A, 0x3C, 0xF4, 0x92, 0xB4, 0x8A, 0x95, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0x96, 0xF1, 0x0A, 0x34, 0x2F, 0x74, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0xA1, 0xAA, 0xBA, 0x86, 0x77, 0x4F, 0xA2 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0x7F, 0xEF, 0x60, 0x50, 0x80, 0xD7, 0xD4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0xAC, 0xC9, 0xFE, 0xEC, 0x0A, 0x1A, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x2F, 0xBE, 0x91, 0xD7, 0xB7, 0x38, 0x48 ),
+};
+static const mbedtls_mpi_uint secp192r1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xAE, 0x85, 0x98, 0xFE, 0x05, 0x7F, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0xBE, 0xFD, 0x11, 0x31, 0x3D, 0x14, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0x75, 0xE8, 0x30, 0x01, 0xCB, 0x9B, 0x1C ),
+};
+static const mbedtls_ecp_point secp192r1_T[16] = {
+    ECP_POINT_INIT_XY_Z1(secp192r1_T_0_X, secp192r1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_1_X, secp192r1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_2_X, secp192r1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_3_X, secp192r1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_4_X, secp192r1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_5_X, secp192r1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_6_X, secp192r1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_7_X, secp192r1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_8_X, secp192r1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_9_X, secp192r1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_10_X, secp192r1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_11_X, secp192r1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_12_X, secp192r1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_13_X, secp192r1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_14_X, secp192r1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(secp192r1_T_15_X, secp192r1_T_15_Y),
+};
+#else
+#define secp192r1_T NULL
+#endif
+#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
+
+/*
+ * Domain parameters for secp224r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+static const mbedtls_mpi_uint secp224r1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
+};
+static const mbedtls_mpi_uint secp224r1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
+};
+static const mbedtls_mpi_uint secp224r1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
+};
+static const mbedtls_mpi_uint secp224r1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint secp224r1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBD, 0x0C, 0x0E, 0xB7, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0x63, 0x37, 0xBD, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0xF9, 0xB8, 0xD0, 0x3D, 0xD2, 0xD3, 0xFA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xFD, 0x99, 0x26, 0x19, 0xFE, 0x13, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x0E, 0x4C, 0x48, 0x7C, 0xA2, 0x17, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xA3, 0x13, 0x57, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9F, 0x16, 0x5C, 0x8F, 0xAA, 0xED, 0x0F, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0xC5, 0x43, 0x34, 0x93, 0x05, 0x2A, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0xE3, 0x6C, 0xCA, 0xC6, 0x14, 0xC2, 0x25 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0x43, 0x6C, 0xD7, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0x5A, 0x98, 0x1E, 0xC8, 0xA5, 0x42, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x49, 0x56, 0x78, 0xF8, 0xEF, 0xED, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0xBB, 0x64, 0xB6, 0x4C, 0x54, 0x5F, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0x0C, 0x33, 0xCC, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x79, 0xCB, 0x2E, 0x08, 0xFF, 0xD8, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2E, 0x1F, 0xD4, 0xD7, 0x57, 0xE9, 0x39, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0xD6, 0x3B, 0x0A, 0x1C, 0x87, 0xB7, 0x6A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0x30, 0xD8, 0x05, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x79, 0x74, 0x9A, 0xE6, 0xBB, 0xC2, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x5B, 0xA6, 0x67, 0xC1, 0x91, 0xE7, 0x64 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0xDF, 0x38, 0x82, 0x19, 0x2C, 0x4C, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x2E, 0x39, 0xC5, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0x36, 0x78, 0x4E, 0xAE, 0x5B, 0x02, 0x76 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x14, 0xF6, 0x8B, 0xF8, 0xF4, 0x92, 0x6B, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x4D, 0x71, 0x35, 0xE7, 0x0C, 0x2C, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0xA5, 0x1F, 0xAE, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0x1C, 0x4B, 0xDF, 0x5B, 0xF2, 0x51, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0x74, 0xB1, 0x5A, 0xC6, 0x0F, 0x0E, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x24, 0x09, 0x62, 0xAF, 0xFC, 0xDB, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0xE1, 0x80, 0x55, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0x82, 0xFE, 0xAD, 0xC3, 0xE5, 0xCF, 0xD8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0xA2, 0x62, 0x17, 0x76, 0xF0, 0x5A, 0xFA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xB8, 0xE5, 0xAC, 0xB7, 0x66, 0x38, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0xFD, 0x86, 0x05, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xD3, 0x0C, 0x3C, 0xD1, 0x66, 0xB0, 0xF1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x59, 0xB4, 0x8D, 0x90, 0x10, 0xB7, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0x47, 0x9B, 0xE6, 0x55, 0x8A, 0xE4, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0x49, 0xDB, 0x78, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x97, 0xED, 0xDE, 0xFF, 0xB3, 0xDF, 0x48 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xB9, 0x83, 0xB7, 0xEB, 0xBE, 0x40, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xD3, 0xD3, 0xCD, 0x0E, 0x82, 0x79, 0x3D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x83, 0x1B, 0xF0, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x22, 0xBB, 0x54, 0xD3, 0x31, 0x56, 0xFC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0x36, 0xE5, 0xE0, 0x89, 0x96, 0x8E, 0x71 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0xEF, 0x0A, 0xED, 0xD0, 0x11, 0x4A, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x00, 0x57, 0x27, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0xCA, 0x3D, 0xF7, 0x64, 0x9B, 0x6E, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0xE3, 0x70, 0x6B, 0x41, 0xD7, 0xED, 0x8F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0x44, 0x44, 0x80, 0xCE, 0x13, 0x37, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x73, 0x80, 0x79, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x4D, 0x70, 0x7D, 0x31, 0x0F, 0x1C, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x35, 0x88, 0x47, 0xC4, 0x24, 0x78, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xF0, 0xCD, 0x91, 0x81, 0xB3, 0xDE, 0xB6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xCE, 0xC6, 0xF7, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0x9C, 0x2D, 0xE8, 0xD2, 0x00, 0x8F, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x5E, 0x7C, 0x0E, 0x0C, 0x6E, 0x58, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x81, 0x21, 0xCE, 0x43, 0xF4, 0x24, 0x3D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9E, 0xBC, 0xF0, 0xF4, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x10, 0xC2, 0x74, 0x4A, 0x8F, 0x8A, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0x67, 0xF4, 0x2B, 0x38, 0x2B, 0x35, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xE7, 0x0C, 0xA9, 0xFA, 0x77, 0x5C, 0xBD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x33, 0x19, 0x2B, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x3E, 0x96, 0x22, 0x53, 0xE1, 0xE9, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x13, 0xBC, 0xA1, 0x16, 0xEC, 0x01, 0x1A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0x00, 0xC9, 0x7A, 0xC3, 0x73, 0xA5, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0xF4, 0x5E, 0xC1, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x95, 0xD6, 0xD9, 0x32, 0x30, 0x2B, 0xD0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x42, 0x09, 0x05, 0x61, 0x2A, 0x7E, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x84, 0xA2, 0x05, 0x88, 0x64, 0x65, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0x2D, 0x90, 0xB3, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0xE7, 0x2E, 0x85, 0x55, 0x80, 0x7C, 0x79 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xC1, 0xAC, 0x78, 0xB4, 0xAF, 0xFB, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0xC3, 0x28, 0x8E, 0x79, 0x18, 0x1F, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x46, 0xCF, 0x49, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0x5F, 0xA8, 0x6C, 0x46, 0x83, 0x43, 0xFA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xA9, 0x93, 0x11, 0xB6, 0x07, 0x57, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x2A, 0x9D, 0x03, 0x89, 0x7E, 0xD7, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x8C, 0x62, 0xCF, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0x2C, 0x13, 0x59, 0xCC, 0xFA, 0x84, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0xB9, 0x48, 0xBC, 0x57, 0xC7, 0xB3, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x0A, 0x38, 0x24, 0x2E, 0x3A, 0x28, 0x25 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x0A, 0x43, 0xB8, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0x25, 0xAB, 0xC1, 0xEE, 0x70, 0x3C, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0xDB, 0x45, 0x1D, 0x4A, 0x80, 0x75, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x1F, 0x4D, 0x2D, 0x9A, 0x05, 0xF4, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x10, 0xF0, 0x5A, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0x95, 0xE1, 0xDC, 0x15, 0x86, 0xC3, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0xDC, 0x27, 0xD1, 0x56, 0xA1, 0x14, 0x0D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0x0B, 0xD6, 0x77, 0x4E, 0x44, 0xA2, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x42, 0x71, 0x1F, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x86, 0xB2, 0xB0, 0xC8, 0x2F, 0x7B, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xEF, 0xCB, 0xDB, 0xBC, 0x9E, 0x3B, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0x03, 0x86, 0xDD, 0x5B, 0xF5, 0x8D, 0x46 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0x95, 0x79, 0xD6, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x32, 0x14, 0xDA, 0x9B, 0x4F, 0x07, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0x3E, 0xFB, 0x06, 0xEE, 0xA7, 0x40, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0x1F, 0xDF, 0x71, 0x61, 0xFD, 0x8B, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0x8B, 0xAB, 0x8B, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x34, 0xB3, 0xB4, 0xBC, 0x9F, 0xB0, 0x5E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x58, 0x48, 0xA8, 0x77, 0xBB, 0x13, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0xC6, 0xF7, 0x34, 0xCC, 0x89, 0x21, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x33, 0xDD, 0x1F, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0x81, 0xEF, 0xA4, 0xF2, 0x10, 0x0B, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0xF7, 0x6E, 0x72, 0x4A, 0xDF, 0xDD, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x23, 0x0A, 0x53, 0x03, 0x16, 0x62, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0x76, 0xFD, 0x3C, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x14, 0xA1, 0xFA, 0xA0, 0x18, 0xBE, 0x07 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0x2A, 0xE1, 0xD7, 0xB0, 0x6C, 0xA0, 0xDE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0xC0, 0xB0, 0xC6, 0x63, 0x24, 0xCD, 0x4E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0x38, 0x2C, 0xB1, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0xCD, 0x7D, 0x20, 0x0C, 0xFE, 0xAC, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x97, 0x9F, 0xA2, 0xB6, 0x45, 0xF7, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x99, 0xF3, 0xD2, 0x20, 0x02, 0xEB, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0x18, 0x5B, 0x7B, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0xDD, 0x77, 0x91, 0x60, 0xEA, 0xFD, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0xD3, 0xB5, 0xD6, 0x90, 0x17, 0x0E, 0x1A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0xF4, 0x28, 0xC1, 0xF2, 0x53, 0xF6, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0x58, 0xDC, 0x61, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x20, 0x01, 0xFB, 0xF1, 0xBD, 0x5F, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x7F, 0x06, 0xDA, 0x11, 0xCB, 0xBA, 0xA6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x41, 0x00, 0xA4, 0x1B, 0x30, 0x33, 0x79 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0xFF, 0x27, 0xCA, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_ecp_point secp224r1_T[16] = {
+    ECP_POINT_INIT_XY_Z1(secp224r1_T_0_X, secp224r1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_1_X, secp224r1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_2_X, secp224r1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_3_X, secp224r1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_4_X, secp224r1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_5_X, secp224r1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_6_X, secp224r1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_7_X, secp224r1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_8_X, secp224r1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_9_X, secp224r1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_10_X, secp224r1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_11_X, secp224r1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_12_X, secp224r1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_13_X, secp224r1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_14_X, secp224r1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(secp224r1_T_15_X, secp224r1_T_15_Y),
+};
+#else
+#define secp224r1_T NULL
+#endif
+#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
+
+/*
+ * Domain parameters for secp256r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+static const mbedtls_mpi_uint secp256r1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp256r1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
+};
+static const mbedtls_mpi_uint secp256r1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
+};
+static const mbedtls_mpi_uint secp256r1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
+};
+static const mbedtls_mpi_uint secp256r1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint secp256r1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
+};
+static const mbedtls_mpi_uint secp256r1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
+};
+static const mbedtls_mpi_uint secp256r1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0xC8, 0xBA, 0x04, 0xB7, 0x4B, 0xD2, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0xC6, 0x23, 0x3A, 0xA0, 0x09, 0x3A, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x9D, 0x4C, 0xF9, 0x58, 0x23, 0xCC, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0xED, 0x7B, 0x29, 0x87, 0x0F, 0xFA, 0x3C ),
+};
+static const mbedtls_mpi_uint secp256r1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x69, 0xF2, 0x40, 0x0B, 0xA3, 0x98, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xA8, 0x48, 0x02, 0x0D, 0x1C, 0x12, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0xAF, 0x09, 0x83, 0x80, 0xAA, 0x58, 0xA7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0x12, 0xBE, 0x70, 0x94, 0x76, 0xE3, 0xE4 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x7D, 0xEF, 0x86, 0xFF, 0xE3, 0x37, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x86, 0x8B, 0x08, 0x27, 0x7C, 0xD7, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0x54, 0x4C, 0x25, 0x4F, 0x9A, 0xFE, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0xFD, 0xF0, 0x6D, 0x37, 0x03, 0x69, 0xD6 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xD5, 0xDA, 0xAD, 0x92, 0x49, 0xF0, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF9, 0x73, 0x43, 0x9E, 0xAF, 0xA7, 0xD1, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x41, 0x07, 0xDF, 0x78, 0x95, 0x3E, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x3D, 0xD1, 0xE6, 0x3C, 0xA5, 0xE2, 0x20 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x6A, 0x5D, 0x52, 0x35, 0xD7, 0xBF, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0xA2, 0xBE, 0x96, 0xF4, 0xF8, 0x02, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x20, 0x49, 0x54, 0xEA, 0xB3, 0x82, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2E, 0xDB, 0xEA, 0x02, 0xD1, 0x75, 0x1C, 0x62 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0x85, 0xF4, 0x9E, 0x4C, 0xDC, 0x39, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0x6D, 0xC4, 0x57, 0xD8, 0x03, 0x5D, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x7F, 0x2D, 0x52, 0x6F, 0xC9, 0xDA, 0x4F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x64, 0xFA, 0xB4, 0xFE, 0xA4, 0xC4, 0xD7 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0x37, 0xB9, 0xC0, 0xAA, 0x59, 0xC6, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x58, 0xD9, 0xED, 0x58, 0x99, 0x65, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0x7D, 0x26, 0x8C, 0x4A, 0xF9, 0x05, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x73, 0x9A, 0xC9, 0xE7, 0x46, 0xDC, 0x00 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0xD0, 0x55, 0xDF, 0x00, 0x0A, 0xF5, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0xBF, 0x56, 0x81, 0x2D, 0x20, 0xEB, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0xC1, 0x28, 0x52, 0xAB, 0xE3, 0xD1, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0x34, 0x79, 0x45, 0x57, 0xA5, 0x12, 0x03 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0xCF, 0xB8, 0x7E, 0xF7, 0x92, 0x96, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x01, 0x8C, 0x0D, 0x23, 0xF2, 0xE3, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0x2E, 0xE3, 0x84, 0x52, 0x7A, 0x34, 0x76 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0xA1, 0xB0, 0x15, 0x90, 0xE2, 0x53, 0x3C ),
+};
+static const mbedtls_mpi_uint secp256r1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x98, 0xE7, 0xFA, 0xA5, 0x7D, 0x8B, 0x53 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0x35, 0xD2, 0x00, 0xD1, 0x1B, 0x9F, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x69, 0x08, 0x9A, 0x72, 0xF0, 0xA9, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0xFE, 0x0E, 0x14, 0xDA, 0x7C, 0x0E, 0xD3 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0xF6, 0xE8, 0xF8, 0x87, 0xF7, 0xFC, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0xBE, 0x7F, 0x3F, 0x7A, 0x2B, 0xD7, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCF, 0x32, 0xF2, 0x2D, 0x94, 0x6D, 0x42, 0xFD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x9A, 0xE3, 0x5F, 0x42, 0xBB, 0x84, 0xED ),
+};
+static const mbedtls_mpi_uint secp256r1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x95, 0x29, 0x73, 0xA1, 0x67, 0x3E, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x30, 0x54, 0x35, 0x8E, 0x0A, 0xDD, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0xD7, 0xA1, 0x97, 0x61, 0x3B, 0xF8, 0x0C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x33, 0x3C, 0x58, 0x55, 0x34, 0x23, 0xA3 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0x5D, 0x16, 0x5F, 0x7B, 0xBC, 0xBB, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0xEE, 0x4E, 0x8A, 0xC1, 0x51, 0xCC, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x0D, 0x4D, 0x1B, 0x53, 0x23, 0x1D, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x2A, 0x38, 0x66, 0x52, 0x84, 0xE1, 0x95 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0x9B, 0x83, 0x0A, 0x81, 0x4F, 0xAD, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xFF, 0x42, 0x41, 0x6E, 0xA9, 0xA2, 0xA0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xA1, 0x4F, 0x1F, 0x89, 0x82, 0xAA, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0xB8, 0x0F, 0x6B, 0x8F, 0x8C, 0xD6, 0x68 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0xB3, 0xBB, 0x51, 0x69, 0xA2, 0x11, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x4F, 0x0F, 0x8D, 0xBD, 0x26, 0x0F, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xCB, 0xEC, 0x6B, 0x34, 0xC3, 0x3D, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0x5D, 0x1E, 0x10, 0xD5, 0x44, 0xE2, 0x54 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x9E, 0xB1, 0xF1, 0x6E, 0x4C, 0xAD, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xE3, 0xC2, 0x58, 0xC0, 0xFB, 0x34, 0x43 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x25, 0x9C, 0xDF, 0x35, 0x07, 0x41, 0xBD, 0x19 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x6E, 0x10, 0xEC, 0x0E, 0xEC, 0xBB, 0xD6 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0xCF, 0xEF, 0x3F, 0x83, 0x1A, 0x88, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0x29, 0xB5, 0xB9, 0xE0, 0xC9, 0xA3, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0x46, 0x1E, 0x77, 0xCD, 0x7E, 0xB3, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x21, 0xD0, 0xD4, 0xA3, 0x16, 0x08, 0xEE ),
+};
+static const mbedtls_mpi_uint secp256r1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0xCA, 0xA8, 0xB3, 0xBF, 0x29, 0x99, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0xF2, 0x05, 0xC1, 0xCF, 0x5D, 0x91, 0x48 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9F, 0x01, 0x49, 0xDB, 0x82, 0xDF, 0x5F, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x06, 0x90, 0xAD, 0xE3, 0x38, 0xA4, 0xC4 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xD2, 0x3A, 0xE8, 0x03, 0xC5, 0x6D, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0x35, 0xD0, 0xAE, 0x1D, 0x7A, 0x9F, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0x1E, 0xD2, 0xCB, 0xAC, 0x88, 0x27, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0xB9, 0x9C, 0xE0, 0x31, 0xDD, 0x99, 0x86 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0xF9, 0x9B, 0x32, 0x96, 0x41, 0x58, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF9, 0x5A, 0x2A, 0xB8, 0x96, 0x0E, 0xB2, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x78, 0x2C, 0xC7, 0x08, 0x99, 0x19, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x59, 0x28, 0xE9, 0x84, 0x54, 0xE6, 0x16 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x38, 0x30, 0xDB, 0x70, 0x2C, 0x0A, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x5C, 0x9D, 0xE9, 0xD5, 0x46, 0x0B, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x0B, 0x60, 0x4B, 0x37, 0x7D, 0xB9, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x24, 0xF3, 0x3D, 0x79, 0x7F, 0x6C, 0x18 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7F, 0xE5, 0x1C, 0x4F, 0x60, 0x24, 0xF7, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0xD8, 0xE2, 0x91, 0x7F, 0x89, 0x49, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0xA7, 0x2E, 0x8D, 0x6A, 0xB3, 0x39, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0x89, 0xB5, 0x9A, 0xB8, 0x8D, 0x42, 0x9C ),
+};
+static const mbedtls_mpi_uint secp256r1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0x45, 0xE6, 0x4B, 0x3F, 0x4F, 0x1E, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x65, 0x5E, 0x59, 0x22, 0xCC, 0x72, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x93, 0x1A, 0x27, 0x1E, 0x34, 0xC5, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0xF2, 0xA5, 0x58, 0x5C, 0x15, 0x2E, 0xC6 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0x7F, 0xBA, 0x58, 0x5A, 0x84, 0x6F, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0xA6, 0x36, 0x7E, 0xDC, 0xF7, 0xE1, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x4D, 0xAA, 0xEE, 0x57, 0x76, 0x3A, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4E, 0x7E, 0x26, 0x18, 0x22, 0x23, 0x9F, 0xFF ),
+};
+static const mbedtls_mpi_uint secp256r1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x4C, 0x64, 0xC7, 0x55, 0x02, 0x3F, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0x02, 0x90, 0xBB, 0xC3, 0xEC, 0x30, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9F, 0x6F, 0x64, 0xF4, 0x16, 0x69, 0x48, 0xA4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x44, 0x9C, 0x95, 0x0C, 0x7D, 0x67, 0x5E ),
+};
+static const mbedtls_mpi_uint secp256r1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0x91, 0x8B, 0xD8, 0xD0, 0xD7, 0xE7, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0xF9, 0x48, 0x62, 0x6F, 0xA8, 0x93, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0x3A, 0x99, 0x02, 0xD5, 0x0B, 0x3D, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xD3, 0x00, 0x31, 0xE6, 0x0C, 0x9F, 0x44 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0xB2, 0xAA, 0xFD, 0x88, 0x15, 0xDF, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4C, 0x35, 0x27, 0x31, 0x44, 0xCD, 0xC0, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xF8, 0x91, 0xA5, 0x71, 0x94, 0x84, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0xCB, 0xD0, 0x93, 0xE9, 0x88, 0xDA, 0xE4 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0xC6, 0x39, 0x16, 0x5D, 0xA3, 0x1E, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x07, 0x37, 0x26, 0x36, 0x2A, 0xFE, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0xBC, 0xF3, 0xD0, 0xDE, 0x50, 0xFC, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0x2E, 0x06, 0x10, 0x15, 0x4D, 0xFA, 0xF7 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0x65, 0x69, 0x5B, 0x66, 0xA2, 0x75, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0x16, 0x00, 0x5A, 0xB0, 0x30, 0x25, 0x1A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xFB, 0x86, 0x42, 0x80, 0xC1, 0xC4, 0x76 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0x1D, 0x83, 0x8E, 0x94, 0x01, 0x5F, 0x82 ),
+};
+static const mbedtls_mpi_uint secp256r1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x39, 0x37, 0x70, 0xEF, 0x1F, 0xA1, 0xF0, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0x10, 0x5B, 0xCE, 0xC4, 0x9B, 0x6F, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x11, 0x11, 0x24, 0x4F, 0x4C, 0x79, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0x3A, 0x72, 0xBC, 0xFE, 0x72, 0x58, 0x43 ),
+};
+static const mbedtls_ecp_point secp256r1_T[16] = {
+    ECP_POINT_INIT_XY_Z1(secp256r1_T_0_X, secp256r1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_1_X, secp256r1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_2_X, secp256r1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_3_X, secp256r1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_4_X, secp256r1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_5_X, secp256r1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_6_X, secp256r1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_7_X, secp256r1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_8_X, secp256r1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_9_X, secp256r1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_10_X, secp256r1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_11_X, secp256r1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_12_X, secp256r1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_13_X, secp256r1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_14_X, secp256r1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(secp256r1_T_15_X, secp256r1_T_15_Y),
+};
+#else
+#define secp256r1_T NULL
+#endif
+
+#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+
+/*
+ * Domain parameters for secp384r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+static const mbedtls_mpi_uint secp384r1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp384r1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
+};
+static const mbedtls_mpi_uint secp384r1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
+};
+static const mbedtls_mpi_uint secp384r1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
+};
+static const mbedtls_mpi_uint secp384r1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint secp384r1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
+};
+static const mbedtls_mpi_uint secp384r1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0x92, 0x00, 0x2C, 0x78, 0xDB, 0x1F, 0x37 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xF3, 0xEB, 0xB7, 0x06, 0xF7, 0xB6, 0xBC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xBC, 0x2C, 0xCF, 0xD8, 0xED, 0x53, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0x75, 0x7B, 0xA3, 0xAB, 0xC3, 0x2C, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0x9D, 0x78, 0x41, 0xF6, 0x76, 0x84, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x56, 0xE8, 0x52, 0xB3, 0xCB, 0xA8, 0xBD ),
+};
+static const mbedtls_mpi_uint secp384r1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xF2, 0xAE, 0xA4, 0xB6, 0x89, 0x1B, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x0F, 0xCE, 0x1C, 0x7C, 0xF6, 0x50, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4C, 0xEB, 0x90, 0xE6, 0x4D, 0xC7, 0xD4, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x49, 0x2D, 0x8A, 0x01, 0x99, 0x60, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x80, 0x9B, 0x9B, 0x6A, 0xB0, 0x07, 0xD9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0xA2, 0xEE, 0x59, 0xBE, 0x95, 0xBC, 0x23 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x9D, 0x56, 0xAE, 0x59, 0xFB, 0x1F, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCF, 0xAC, 0x91, 0x80, 0x87, 0xA8, 0x6E, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x08, 0xA7, 0x08, 0x94, 0x32, 0xFC, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9F, 0x29, 0x9E, 0x84, 0xF4, 0xE5, 0x6E, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0x21, 0xB9, 0x50, 0x24, 0xF8, 0x9C, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x04, 0x01, 0xC2, 0xFB, 0x77, 0x3E, 0xDE ),
+};
+static const mbedtls_mpi_uint secp384r1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x38, 0xEE, 0xE3, 0xC7, 0x9D, 0xEC, 0xA6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x88, 0xCF, 0x43, 0xFA, 0x92, 0x5E, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0xCA, 0x43, 0xF8, 0x3B, 0x49, 0x7E, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0xE7, 0xEB, 0x17, 0x45, 0x86, 0xC2, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x69, 0x57, 0x32, 0xE0, 0x9C, 0xD1, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x10, 0xB8, 0x4D, 0xB8, 0xF4, 0x0D, 0xE3 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x60, 0xDC, 0x9A, 0xB2, 0x79, 0x39, 0x27, 0x16 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0x71, 0xE4, 0x3B, 0x4D, 0x60, 0x0C, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0xBD, 0x19, 0x40, 0xFA, 0x19, 0x2A, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xF8, 0x1E, 0x43, 0xA1, 0x50, 0x8D, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0x18, 0x7C, 0x41, 0xFA, 0x7C, 0x1B, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x59, 0x24, 0xC4, 0xE9, 0xB7, 0xD3, 0xAD ),
+};
+static const mbedtls_mpi_uint secp384r1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x01, 0x3D, 0x63, 0x54, 0x45, 0x6F, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0xB2, 0x19, 0xA3, 0x86, 0x1D, 0x42, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x02, 0x87, 0x18, 0x92, 0x52, 0x1A, 0x71 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x18, 0xB1, 0x5D, 0x18, 0x1B, 0x37, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0x74, 0x61, 0xBA, 0x18, 0xAF, 0x40, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x7D, 0x3C, 0x52, 0x0F, 0x07, 0xB0, 0x6F ),
+};
+static const mbedtls_mpi_uint secp384r1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x39, 0x13, 0xAA, 0x60, 0x15, 0x99, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0x00, 0xCB, 0xC6, 0xB1, 0xDB, 0x97, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xFA, 0x60, 0xB8, 0x24, 0xE4, 0x7D, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x75, 0xB3, 0x70, 0xB2, 0x83, 0xB1, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0xE3, 0x6C, 0xCD, 0x33, 0x62, 0x7A, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0x30, 0xDC, 0x0F, 0x9F, 0xBB, 0xB8, 0xAA ),
+};
+static const mbedtls_mpi_uint secp384r1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xD5, 0x0A, 0x60, 0x81, 0xB9, 0xC5, 0x16 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0xAA, 0x2F, 0xD6, 0xF2, 0x73, 0xDF, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x7B, 0x74, 0xC9, 0xB3, 0x5B, 0x95, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x04, 0xEB, 0x15, 0xC8, 0x5F, 0x00, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0x50, 0x20, 0x28, 0xD1, 0x01, 0xAF, 0xF0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x4F, 0x31, 0x81, 0x2F, 0x94, 0x48 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0x2F, 0xD8, 0xB6, 0x63, 0x7C, 0xE9, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x8C, 0xB9, 0x14, 0xD9, 0x37, 0x63, 0xDE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x02, 0xB8, 0x46, 0xAD, 0xCE, 0x7B, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x82, 0x47, 0x2D, 0x66, 0xA7, 0xE9, 0x33, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0xF9, 0x93, 0x94, 0xA8, 0x48, 0xB3, 0x4F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0x4A, 0xAC, 0x51, 0x08, 0x72, 0x2F, 0x1A ),
+};
+static const mbedtls_mpi_uint secp384r1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0xAD, 0xA0, 0xF9, 0x81, 0xE1, 0x78, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0x9A, 0x63, 0xD8, 0xBA, 0x79, 0x1A, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x31, 0x7B, 0x7A, 0x5A, 0x5D, 0x7D, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x96, 0x12, 0x4B, 0x19, 0x09, 0xE0, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0x8A, 0x57, 0xEE, 0x4E, 0x6E, 0x7E, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x9D, 0x69, 0xDC, 0xB3, 0xDA, 0xD8, 0x08 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x49, 0x03, 0x03, 0x33, 0x6F, 0x28, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0xDB, 0xA7, 0x05, 0x8C, 0xF3, 0x4D, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x92, 0xB1, 0xA8, 0xEC, 0x0D, 0x64, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4E, 0xFC, 0xFD, 0xD0, 0x4B, 0x88, 0x1B, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x9C, 0x51, 0x69, 0xCE, 0x71, 0x73, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0x5A, 0x14, 0x23, 0x1A, 0x46, 0x63, 0x5F ),
+};
+static const mbedtls_mpi_uint secp384r1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x4C, 0x70, 0x44, 0x18, 0xCD, 0xEF, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x49, 0xDD, 0x64, 0x7E, 0x7E, 0x4D, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA2, 0x32, 0x7C, 0x09, 0xD0, 0x3F, 0xD6, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xE0, 0x4F, 0x65, 0x0C, 0x7A, 0x54, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0xFA, 0xFB, 0x4A, 0xB4, 0x79, 0x5A, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x5D, 0x1B, 0x2B, 0xDA, 0xBC, 0x9A, 0x74 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0xAC, 0x56, 0xF7, 0x5F, 0x51, 0x68, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0xE0, 0x1D, 0xBC, 0x13, 0x4E, 0xAC, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xF5, 0xC5, 0xE6, 0xD2, 0x88, 0xBA, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x0E, 0x28, 0x23, 0x58, 0x67, 0xFA, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9E, 0x80, 0x4B, 0xD8, 0xC4, 0xDF, 0x15, 0xE4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x0E, 0x58, 0xE6, 0x2C, 0x59, 0xC2, 0x03 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x26, 0x27, 0x99, 0x16, 0x2B, 0x22, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xF3, 0x8F, 0xC3, 0x2A, 0x9B, 0xFC, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x2E, 0x83, 0x3D, 0xFE, 0x9E, 0x3C, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x57, 0xCD, 0x2D, 0xC1, 0x49, 0x38, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0x42, 0x8B, 0x33, 0x89, 0x1F, 0xEA, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x1D, 0x13, 0xD7, 0x50, 0xBB, 0x3E, 0xEB ),
+};
+static const mbedtls_mpi_uint secp384r1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD2, 0x9A, 0x52, 0xD2, 0x54, 0x7C, 0x97, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x33, 0x6E, 0xED, 0xD9, 0x87, 0x50, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x35, 0x7E, 0x16, 0x40, 0x15, 0x83, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0x2B, 0xA4, 0xAB, 0x03, 0x91, 0xEA, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x47, 0x39, 0xEF, 0x05, 0x59, 0xD0, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x24, 0x0D, 0x76, 0x11, 0x53, 0x08, 0xAF ),
+};
+static const mbedtls_mpi_uint secp384r1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x2F, 0xDD, 0xBD, 0x50, 0x48, 0xB1, 0xE5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0x1C, 0x84, 0x55, 0x78, 0x14, 0xEB, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x5E, 0x3E, 0xA6, 0xAF, 0xF6, 0xC7, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x11, 0xE2, 0x65, 0xCA, 0x41, 0x95, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x83, 0xD8, 0xE6, 0x4D, 0x22, 0x06, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x7F, 0x25, 0x2A, 0xAA, 0x28, 0x46, 0x97 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0xDB, 0x15, 0x56, 0x84, 0xCB, 0xC0, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0xDB, 0x0E, 0x08, 0xC9, 0xF5, 0xD4, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x62, 0xD0, 0x1A, 0x7C, 0x13, 0xD5, 0x07 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0xAD, 0x53, 0xE0, 0x32, 0x21, 0xA0, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x38, 0x81, 0x21, 0x23, 0x0E, 0xD2, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x51, 0x05, 0xD0, 0x1E, 0x82, 0xA9, 0x71 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0xC3, 0x27, 0xBF, 0xC6, 0xAA, 0xB7, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x65, 0x45, 0xDF, 0xB9, 0x46, 0x17, 0x46 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x38, 0x3F, 0xB2, 0xB1, 0x5D, 0xCA, 0x1C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0x29, 0x6C, 0x63, 0xE9, 0xD7, 0x48, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xF1, 0xD7, 0x99, 0x8C, 0xC2, 0x05, 0x99 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xE6, 0x5E, 0x82, 0x6D, 0xE5, 0x7E, 0xD5 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x61, 0xFA, 0x7D, 0x01, 0xDB, 0xB6, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0xC6, 0x58, 0x39, 0xF4, 0xC6, 0x82, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x5A, 0x7A, 0x80, 0x08, 0xCD, 0xAA, 0xD8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x8C, 0xC6, 0x3F, 0x3C, 0xA5, 0x68, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0xF5, 0xD5, 0x17, 0xAE, 0x36, 0xD8, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0xAD, 0x92, 0xC5, 0x57, 0x6C, 0xDA, 0x91 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x67, 0x17, 0xC0, 0x40, 0x78, 0x8C, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x9F, 0xF4, 0xAA, 0xDA, 0x5C, 0x7E, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xDB, 0x42, 0x3E, 0x72, 0x64, 0xA0, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0xF9, 0x41, 0x17, 0x43, 0xE3, 0xE8, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xDD, 0xCC, 0x43, 0x7E, 0x16, 0x05, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0x4B, 0xCF, 0x48, 0x8F, 0x41, 0x90, 0xE5 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x0C, 0x6B, 0x9D, 0x22, 0x04, 0xBC, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x63, 0x79, 0x2F, 0x6A, 0x0E, 0x8A, 0xDE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x67, 0x3F, 0x02, 0xB8, 0x91, 0x7F, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x14, 0x64, 0xA0, 0x33, 0xF4, 0x6B, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x44, 0x71, 0x87, 0xB8, 0x88, 0x3F, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0x2B, 0x85, 0x05, 0xC5, 0x44, 0x53, 0x15 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0x2B, 0xFE, 0xD1, 0x1C, 0x73, 0xE3, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0x33, 0xA1, 0xD3, 0x69, 0x1C, 0x9D, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x5A, 0xBA, 0xB6, 0xAE, 0x1B, 0x94, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0x74, 0x90, 0x5C, 0x57, 0xB0, 0x3A, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x2F, 0x93, 0x20, 0x24, 0x54, 0x1D, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x78, 0x9D, 0x71, 0x67, 0x5D, 0x49, 0x98 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0xC8, 0x0E, 0x11, 0x8D, 0xE0, 0x8F, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0x7F, 0x79, 0x6C, 0x5F, 0xB7, 0xBC, 0xB1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0xE1, 0x83, 0x3C, 0x12, 0xBB, 0xEE, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0xC2, 0xC4, 0x1B, 0x41, 0x71, 0xB9, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0xEE, 0xBB, 0x1D, 0x89, 0x50, 0x88, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x1C, 0x55, 0x74, 0xEB, 0xDE, 0x92, 0x3F ),
+};
+static const mbedtls_mpi_uint secp384r1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0x38, 0x92, 0x06, 0x19, 0xD0, 0xB3, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0x99, 0x26, 0xA3, 0x5F, 0xE2, 0xC1, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0xFC, 0xFD, 0xC3, 0xB6, 0x26, 0x24, 0x8F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xAD, 0xE7, 0x49, 0xB7, 0x64, 0x4B, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x4E, 0x95, 0xAD, 0x07, 0xFE, 0xB6, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0x15, 0xE7, 0x2D, 0x19, 0xA9, 0x08, 0x10 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0xBD, 0xAC, 0x0A, 0x3F, 0x6B, 0xFF, 0xFA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0xE4, 0x74, 0x14, 0xD9, 0x70, 0x1D, 0x71 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0xB0, 0x71, 0xBB, 0xD8, 0x18, 0x96, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0xB8, 0x19, 0x90, 0x80, 0xB5, 0xEE, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0x21, 0x20, 0xA6, 0x17, 0x48, 0x03, 0x6F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x1D, 0xBB, 0x6D, 0x94, 0x20, 0x34, 0xF1 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0x82, 0x67, 0x4B, 0x8E, 0x4E, 0xBE, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0xDA, 0x77, 0xF8, 0x23, 0x55, 0x2B, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0x02, 0xDE, 0x25, 0x35, 0x2D, 0x74, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x0C, 0xB8, 0x0B, 0x39, 0xBA, 0xAD, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0x0E, 0x28, 0x4D, 0xE1, 0x3D, 0xE4, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0xEC, 0x0A, 0xD4, 0xB8, 0xC4, 0x8D, 0xB0 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0x68, 0xCE, 0xC2, 0x55, 0x4D, 0x0C, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x20, 0x93, 0x32, 0x90, 0xD6, 0xAE, 0x47 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x78, 0xAB, 0x43, 0x9E, 0xEB, 0x73, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0x97, 0xC3, 0x83, 0xA6, 0x3C, 0xF1, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0x25, 0x25, 0x66, 0x08, 0x26, 0xFA, 0x4B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0xFB, 0x44, 0x5D, 0x82, 0xEC, 0x3B, 0xAC ),
+};
+static const mbedtls_mpi_uint secp384r1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0x90, 0xEA, 0xB5, 0x04, 0x99, 0xD0, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4A, 0xF2, 0x22, 0xA0, 0xEB, 0xFD, 0x45, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0xA4, 0x81, 0x32, 0xFC, 0xFA, 0xEE, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0xBB, 0xA4, 0x6A, 0x77, 0x41, 0x5C, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x1E, 0xAA, 0x4F, 0xF0, 0x10, 0xB3, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x74, 0x13, 0x14, 0x9E, 0x90, 0xD7, 0xE6 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0xBD, 0x70, 0x4F, 0xA8, 0xD1, 0x06, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x4E, 0x2E, 0x68, 0xFC, 0x35, 0xFA, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x60, 0x53, 0x75, 0xED, 0xF2, 0x5F, 0xC2, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x39, 0x87, 0x6B, 0x9F, 0x05, 0xE2, 0x22, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0x1A, 0xA8, 0xB7, 0x03, 0x9E, 0x6D, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0xD0, 0x69, 0x88, 0xA8, 0x39, 0x9E, 0x3A ),
+};
+static const mbedtls_mpi_uint secp384r1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0xEF, 0x68, 0xFE, 0xEC, 0x24, 0x08, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x06, 0x4B, 0x92, 0x0D, 0xB7, 0x34, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xF4, 0xDD, 0x1A, 0xA0, 0x4A, 0xE4, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0x63, 0x4F, 0x4F, 0xCE, 0xBB, 0xD6, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xEE, 0x8D, 0xDF, 0x3F, 0x73, 0xB7, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x06, 0xB6, 0x80, 0x4D, 0x81, 0xD9, 0x53 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_16_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0xF5, 0x13, 0xDF, 0x13, 0x19, 0x97, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0xF9, 0xB3, 0x33, 0x66, 0x82, 0x21, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xFC, 0x39, 0x16, 0x23, 0x43, 0x76, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x48, 0x25, 0xA1, 0x64, 0x95, 0x1C, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0xAC, 0x15, 0x57, 0xD9, 0xDE, 0xA0, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x5F, 0xB8, 0x3D, 0x48, 0x91, 0x24, 0xCC ),
+};
+static const mbedtls_mpi_uint secp384r1_T_16_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0xF2, 0xC8, 0x54, 0xD1, 0x32, 0xBD, 0xC4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0x3B, 0xF0, 0xAA, 0x9D, 0xD8, 0xF4, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0xC3, 0xBB, 0x6C, 0x66, 0xAC, 0x25, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x25, 0x10, 0xB2, 0xE1, 0x41, 0xDE, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0xE8, 0x30, 0xB8, 0x37, 0xBC, 0x2A, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x57, 0x01, 0x4A, 0x1E, 0x78, 0x9F, 0x85 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_17_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBD, 0x19, 0xCD, 0x12, 0x0B, 0x51, 0x4F, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x4B, 0x3D, 0x24, 0xA4, 0x16, 0x59, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xEB, 0xD3, 0x59, 0x2E, 0x75, 0x7C, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0xB9, 0xB4, 0xA5, 0xD9, 0x2E, 0x29, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x16, 0x05, 0x75, 0x02, 0xB3, 0x06, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0x7C, 0x9F, 0x79, 0x91, 0xF1, 0x4F, 0x23 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_17_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x98, 0x7C, 0x84, 0xE1, 0xFF, 0x30, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0xE2, 0xC2, 0x5F, 0x55, 0x40, 0xBD, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x65, 0x87, 0x3F, 0xC4, 0xC2, 0x24, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0x30, 0x0A, 0x60, 0x15, 0xD1, 0x24, 0x48 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x99, 0xD9, 0xB6, 0xAE, 0xB1, 0xAF, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x80, 0xEE, 0xA2, 0x0F, 0x74, 0xB9, 0xF3 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_18_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0xE6, 0x0F, 0x37, 0xC1, 0x10, 0x99, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0xAD, 0x9D, 0x5D, 0x80, 0x01, 0xA6, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x0F, 0x10, 0x2A, 0x9D, 0x20, 0x38, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x60, 0xCB, 0xCE, 0x5A, 0xA0, 0xA7, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xCF, 0x14, 0xDF, 0xBF, 0xE5, 0x74, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0x12, 0x1A, 0xDD, 0x59, 0x02, 0x5D, 0xC6 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_18_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0xC9, 0xF8, 0xF5, 0xB6, 0x13, 0x4D, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0x45, 0xB1, 0x93, 0xB3, 0xA2, 0x79, 0xDC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xF6, 0xCF, 0xF7, 0xE6, 0x29, 0x9C, 0xCC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x50, 0x65, 0x80, 0xBC, 0x59, 0x0A, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xF0, 0x24, 0x35, 0xA2, 0x46, 0xF0, 0x0C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBD, 0x26, 0xC0, 0x9D, 0x61, 0x56, 0x62, 0x67 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_19_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xBB, 0xC2, 0x24, 0x43, 0x2E, 0x37, 0x54 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0xF7, 0xCE, 0x35, 0xFC, 0x77, 0xF3, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0x34, 0x96, 0xD5, 0x4A, 0x76, 0x9D, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0x3B, 0x0F, 0xEA, 0xA8, 0x12, 0x0B, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0x3F, 0x5D, 0x2D, 0x1C, 0xD4, 0x9E, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x2E, 0xDD, 0xC7, 0x6E, 0xAB, 0xAF, 0xDC ),
+};
+static const mbedtls_mpi_uint secp384r1_T_19_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0xB2, 0x7B, 0x0C, 0x9A, 0x83, 0x8E, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x51, 0x90, 0x92, 0x79, 0x32, 0x19, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x89, 0xF9, 0xD0, 0xCF, 0x2C, 0xA5, 0x8F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x50, 0x21, 0xDE, 0x50, 0x41, 0x9D, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x7D, 0x2B, 0x9E, 0x9D, 0x95, 0xA8, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0xA5, 0x20, 0x87, 0x88, 0x97, 0x5F, 0xAA ),
+};
+static const mbedtls_mpi_uint secp384r1_T_20_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x59, 0xB4, 0x66, 0x7E, 0xE8, 0x5A, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x5C, 0x7E, 0xB2, 0xAD, 0xD9, 0xC9, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x82, 0x97, 0x49, 0xA3, 0x13, 0x83, 0x07, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x26, 0xC7, 0x13, 0x35, 0x0D, 0xB0, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0x60, 0xAB, 0xFA, 0x4B, 0x93, 0x18, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x2D, 0x1C, 0x31, 0x4C, 0xE4, 0x61, 0xAE ),
+};
+static const mbedtls_mpi_uint secp384r1_T_20_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0x4D, 0x1E, 0x51, 0x59, 0x6E, 0x91, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x54, 0x4D, 0x51, 0xED, 0x36, 0xCC, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0xA8, 0x56, 0xC7, 0x78, 0x27, 0x33, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xB7, 0x95, 0xC9, 0x8B, 0xC8, 0x6A, 0xBC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0xE9, 0x13, 0x96, 0xB3, 0xE1, 0xF9, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x46, 0xB0, 0x5E, 0xC3, 0x94, 0x03, 0x05 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_21_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x5B, 0x29, 0x30, 0x41, 0x1A, 0x9E, 0xB6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0xCA, 0x83, 0x31, 0x5B, 0xA7, 0xCB, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x41, 0x50, 0x44, 0x4D, 0x64, 0x31, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCF, 0x84, 0xC2, 0x5D, 0x97, 0xA5, 0x3C, 0x18 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0x0F, 0xA5, 0xFD, 0x8E, 0x5A, 0x47, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x58, 0x02, 0x2D, 0x40, 0xB1, 0x0B, 0xBA ),
+};
+static const mbedtls_mpi_uint secp384r1_T_21_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x33, 0x8C, 0x67, 0xCE, 0x23, 0x43, 0x99 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x53, 0x47, 0x72, 0x44, 0x1F, 0x5B, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xC1, 0xD9, 0xA4, 0x50, 0x88, 0x63, 0x18 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0xF2, 0x75, 0x69, 0x73, 0x00, 0xC4, 0x31 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x90, 0x1D, 0xDF, 0x1A, 0x00, 0xD8, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0xB1, 0x89, 0x48, 0xA8, 0x70, 0x62, 0xEF ),
+};
+static const mbedtls_mpi_uint secp384r1_T_22_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x8A, 0x55, 0x50, 0x7B, 0xEF, 0x8A, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0x1B, 0x23, 0x48, 0x23, 0x63, 0x91, 0xB6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0D, 0x04, 0x54, 0x3C, 0x24, 0x9B, 0xC7, 0x9A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x25, 0x38, 0xC3, 0x84, 0xFB, 0xFF, 0x9F, 0x49 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0x2A, 0xE0, 0x6D, 0x68, 0x8A, 0x5C, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC4, 0x93, 0x53, 0x85, 0xA1, 0x0D, 0xAF, 0x63 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_22_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0x88, 0x95, 0x4C, 0x0B, 0xD0, 0x06, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0xAF, 0x8D, 0x49, 0xA2, 0xC8, 0xB4, 0xE0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0x76, 0x53, 0x09, 0x88, 0x43, 0x87, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0xA4, 0x77, 0x3F, 0x5E, 0x21, 0xB4, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0x9E, 0x86, 0x64, 0xCC, 0x91, 0xC1, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x17, 0x56, 0xCB, 0xC3, 0x7D, 0x5B, 0xB1 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_23_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x74, 0x9F, 0xB5, 0x91, 0x21, 0xB1, 0x1C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xED, 0xE1, 0x11, 0xEF, 0x45, 0xAF, 0xC1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x31, 0xBE, 0xB2, 0xBC, 0x72, 0x65, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0x4B, 0x8C, 0x77, 0xCE, 0x1E, 0x42, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xC9, 0xAA, 0xB9, 0xD9, 0x86, 0x99, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x23, 0x80, 0xC6, 0x4E, 0x35, 0x0B, 0x6D ),
+};
+static const mbedtls_mpi_uint secp384r1_T_23_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0xD8, 0xA2, 0x0A, 0x39, 0x32, 0x1D, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0xC8, 0x86, 0xF1, 0x12, 0x9A, 0x4A, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xF1, 0x7C, 0xAA, 0x70, 0x8E, 0xBC, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x01, 0x47, 0x8F, 0xDD, 0x8B, 0xA5, 0xC8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x08, 0x21, 0xF4, 0xAB, 0xC7, 0xF5, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0x76, 0xA5, 0x95, 0xC4, 0x0F, 0x88, 0x1D ),
+};
+static const mbedtls_mpi_uint secp384r1_T_24_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x42, 0x2A, 0x52, 0xCD, 0x75, 0x51, 0x49 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0x36, 0xE5, 0x04, 0x2B, 0x44, 0xC6, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xEE, 0x16, 0x13, 0x07, 0x83, 0xB5, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0x59, 0xC6, 0xA2, 0x19, 0x05, 0xD3, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x8B, 0xA8, 0x16, 0x09, 0xB7, 0xEA, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0xEE, 0x14, 0xAF, 0xB5, 0xFD, 0xD0, 0xEF ),
+};
+static const mbedtls_mpi_uint secp384r1_T_24_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0x7C, 0xCA, 0x71, 0x3E, 0x6E, 0x66, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0x31, 0x0E, 0x3F, 0xE5, 0x91, 0xC4, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x3D, 0xC2, 0x3E, 0x95, 0x37, 0x58, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x1F, 0x02, 0x03, 0xF3, 0xEF, 0xEE, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x5B, 0x1A, 0xFC, 0x38, 0xCD, 0xE8, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x57, 0x42, 0x85, 0xC6, 0x21, 0x68, 0x71 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_25_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xA2, 0x4A, 0x66, 0xB1, 0x0A, 0xE6, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x0C, 0x94, 0x9D, 0x5E, 0x99, 0xB2, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x03, 0x40, 0xCA, 0xB2, 0xB3, 0x30, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x78, 0x48, 0x27, 0x34, 0x1E, 0xE2, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x72, 0x5B, 0xAC, 0xC1, 0x6D, 0xE3, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0xAB, 0x46, 0xCB, 0xEA, 0x5E, 0x4B, 0x0B ),
+};
+static const mbedtls_mpi_uint secp384r1_T_25_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x08, 0xAD, 0x4E, 0x51, 0x9F, 0x2A, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x5C, 0x7D, 0x4C, 0xD6, 0xCF, 0xDD, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0x76, 0x26, 0xE0, 0x8B, 0x10, 0xD9, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0xA7, 0x23, 0x4E, 0x5F, 0xD2, 0x42, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0xE5, 0xA4, 0xEC, 0x77, 0x21, 0x34, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0x14, 0x65, 0xEA, 0x4A, 0x85, 0xC3, 0x2F ),
+};
+static const mbedtls_mpi_uint secp384r1_T_26_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0xD8, 0x40, 0x27, 0x73, 0x15, 0x7E, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xBB, 0x53, 0x7E, 0x0F, 0x40, 0xC8, 0xD4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0x37, 0x19, 0x73, 0xEF, 0x5A, 0x5E, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0x73, 0x2B, 0x49, 0x7E, 0xAC, 0x97, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0xB2, 0xC3, 0x1E, 0x0E, 0xE7, 0xD2, 0x21 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0x08, 0xD6, 0xDD, 0xAC, 0x21, 0xD6, 0x3E ),
+};
+static const mbedtls_mpi_uint secp384r1_T_26_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x26, 0xBE, 0x6D, 0x6D, 0xF2, 0x38, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x6C, 0x31, 0xA7, 0x49, 0x50, 0x3A, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0x99, 0xC6, 0xF5, 0xD2, 0xC2, 0x30, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0xE4, 0xF6, 0x8B, 0x8B, 0x97, 0xE9, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x21, 0xB7, 0x0D, 0xFC, 0x15, 0x54, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x83, 0x1C, 0xA4, 0xCD, 0x6B, 0x9D, 0xF2 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_27_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xE8, 0x4C, 0x48, 0xE4, 0xAA, 0x69, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0x7A, 0x27, 0xFC, 0x37, 0x96, 0x1A, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0xE7, 0x30, 0xA5, 0xCF, 0x13, 0x46, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0xD8, 0xAF, 0x74, 0x23, 0x4D, 0x56, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0x3D, 0x44, 0x14, 0x1B, 0x97, 0x83, 0xF0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x47, 0xD7, 0x5F, 0xFD, 0x98, 0x38, 0xF7 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_27_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0x73, 0x64, 0x36, 0xFD, 0x7B, 0xC1, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0x5D, 0x32, 0xD2, 0x47, 0x94, 0x89, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0xE9, 0x30, 0xAC, 0x06, 0xC8, 0x65, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x6C, 0xB9, 0x1B, 0xF7, 0x61, 0x49, 0x53 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD7, 0xFF, 0x32, 0x43, 0x80, 0xDA, 0xA6, 0xB1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xF8, 0x04, 0x01, 0x95, 0x35, 0xCE, 0x21 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_28_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x06, 0x46, 0x0D, 0x51, 0xE2, 0xD8, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x14, 0x57, 0x1D, 0x6F, 0x79, 0xA0, 0xCD, 0xA6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0xFB, 0x36, 0xCA, 0xAD, 0xF5, 0x9E, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x7A, 0x1D, 0x9E, 0x1D, 0x95, 0x48, 0xDC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0x26, 0xA5, 0xB7, 0x15, 0x2C, 0xC2, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x42, 0x72, 0xAA, 0x11, 0xDC, 0xC9, 0xB6 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_28_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x6C, 0x64, 0xA7, 0x62, 0x3C, 0xAB, 0xD4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x48, 0x6A, 0x44, 0xD8, 0x60, 0xC0, 0xA8, 0x80 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x82, 0x76, 0x58, 0x12, 0x57, 0x3C, 0x89, 0x46 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x82, 0x4F, 0x83, 0xCE, 0xCB, 0xB8, 0xD0, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0x84, 0x04, 0xB0, 0xAD, 0xEB, 0xFA, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xA4, 0xC3, 0x41, 0x44, 0x4E, 0x65, 0x3E ),
+};
+static const mbedtls_mpi_uint secp384r1_T_29_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x16, 0xA9, 0x1C, 0xE7, 0x65, 0x20, 0xC1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0x53, 0x32, 0xF8, 0xC0, 0xA6, 0xBD, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xF0, 0xE6, 0x57, 0x31, 0xCC, 0x26, 0x6F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0xE3, 0x54, 0x1C, 0x34, 0xD3, 0x17, 0xBC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xAE, 0xED, 0xFB, 0xCD, 0xE7, 0x1E, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x16, 0x1C, 0x34, 0x40, 0x00, 0x1F, 0xB6 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_29_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0x32, 0x00, 0xC2, 0xD4, 0x3B, 0x1A, 0x09 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xE0, 0x99, 0x8F, 0x0C, 0x4A, 0x16, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x73, 0x18, 0x1B, 0xD4, 0x94, 0x29, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xA4, 0x2D, 0xB1, 0x9D, 0x74, 0x32, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0xF4, 0xB1, 0x0C, 0x37, 0x62, 0x8B, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xFF, 0xDA, 0xE2, 0x35, 0xA3, 0xB6, 0x42 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_30_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0x49, 0x99, 0x65, 0xC5, 0xED, 0x16, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0x42, 0x9A, 0xF3, 0xA7, 0x4E, 0x6F, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x0A, 0x7E, 0xC0, 0xD7, 0x4E, 0x07, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x7A, 0x31, 0x69, 0xA6, 0xB9, 0x15, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0xE0, 0x72, 0xA4, 0x3F, 0xB9, 0xF8, 0x0C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0x75, 0x32, 0x85, 0xA2, 0xDE, 0x37, 0x12 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_30_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xC0, 0x0D, 0xCF, 0x25, 0x41, 0xA4, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0xFC, 0xB2, 0x48, 0xC3, 0x85, 0x83, 0x4B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0xBE, 0x0B, 0x58, 0x2D, 0x7A, 0x9A, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0xF3, 0x81, 0x18, 0x1B, 0x74, 0x4F, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0x43, 0xA3, 0x0A, 0x16, 0x8B, 0xA3, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4A, 0x18, 0x81, 0x7B, 0x8D, 0xA2, 0x35, 0x77 ),
+};
+static const mbedtls_mpi_uint secp384r1_T_31_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0xC4, 0x3F, 0x2C, 0xE7, 0x5F, 0x99, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0x2B, 0xB7, 0xB6, 0xAD, 0x5A, 0x56, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x00, 0xA4, 0x48, 0xC8, 0xE8, 0xBA, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0xA1, 0xB5, 0x13, 0x5A, 0xCD, 0x99, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x95, 0xAD, 0xFC, 0xE2, 0x7E, 0xE7, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0x6B, 0xD1, 0x34, 0x99, 0x53, 0x63, 0x0B ),
+};
+static const mbedtls_mpi_uint secp384r1_T_31_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x8A, 0x77, 0x5D, 0x2B, 0xAB, 0x01, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4E, 0x85, 0xD0, 0xD5, 0x49, 0x83, 0x4D, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0xC6, 0x91, 0x30, 0x3B, 0x00, 0xAF, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0xAE, 0x61, 0x07, 0xE1, 0xB6, 0xE2, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0x43, 0x41, 0xFE, 0x9B, 0xB6, 0xF0, 0xA5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x97, 0xAE, 0xAD, 0x89, 0x88, 0x9E, 0x41 ),
+};
+static const mbedtls_ecp_point secp384r1_T[32] = {
+    ECP_POINT_INIT_XY_Z1(secp384r1_T_0_X, secp384r1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_1_X, secp384r1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_2_X, secp384r1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_3_X, secp384r1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_4_X, secp384r1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_5_X, secp384r1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_6_X, secp384r1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_7_X, secp384r1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_8_X, secp384r1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_9_X, secp384r1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_10_X, secp384r1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_11_X, secp384r1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_12_X, secp384r1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_13_X, secp384r1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_14_X, secp384r1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_15_X, secp384r1_T_15_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_16_X, secp384r1_T_16_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_17_X, secp384r1_T_17_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_18_X, secp384r1_T_18_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_19_X, secp384r1_T_19_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_20_X, secp384r1_T_20_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_21_X, secp384r1_T_21_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_22_X, secp384r1_T_22_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_23_X, secp384r1_T_23_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_24_X, secp384r1_T_24_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_25_X, secp384r1_T_25_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_26_X, secp384r1_T_26_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_27_X, secp384r1_T_27_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_28_X, secp384r1_T_28_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_29_X, secp384r1_T_29_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_30_X, secp384r1_T_30_Y),
+    ECP_POINT_INIT_XY_Z0(secp384r1_T_31_X, secp384r1_T_31_Y),
+};
+#else
+#define secp384r1_T NULL
+#endif
+
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
+/*
+ * Domain parameters for secp521r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+static const mbedtls_mpi_uint secp521r1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
+};
+static const mbedtls_mpi_uint secp521r1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x51, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x18, 0x01 ),
+};
+static const mbedtls_mpi_uint secp521r1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
+};
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint secp521r1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xB1, 0x2D, 0xEB, 0x27, 0x2F, 0xE8, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x4B, 0x44, 0x25, 0xDB, 0x5C, 0x5F, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0x85, 0x28, 0x78, 0x2E, 0x75, 0x34, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x57, 0x0F, 0x73, 0x78, 0x7A, 0xE3, 0x53 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xD8, 0xEC, 0xDC, 0xDA, 0x04, 0xAD, 0xAB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x8A, 0x09, 0xF3, 0x58, 0x79, 0xD8, 0x29 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0x03, 0xCB, 0x50, 0x1A, 0x7F, 0x56, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xA6, 0x78, 0x38, 0x85, 0x67, 0x0B, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0xD5, 0xD2, 0x22, 0xC4, 0x00, 0x3B, 0xBA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x93, 0x0E, 0x7B, 0x85, 0x51, 0xC3, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xA6, 0x5F, 0x54, 0x49, 0x02, 0x81, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xE9, 0x6B, 0x3A, 0x92, 0xE7, 0x72, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x5F, 0x28, 0x9E, 0x91, 0x27, 0x88, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x28, 0x31, 0xB3, 0x84, 0xCA, 0x12, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xF9, 0xAC, 0x22, 0x10, 0x0A, 0x64, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0xC6, 0x33, 0x1F, 0x69, 0x19, 0x18, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x48, 0xB8, 0xC7, 0x37, 0x5A, 0x00, 0x36 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xCC, 0x32, 0xE0, 0xEE, 0x03, 0xC2, 0xBA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC4, 0x29, 0xC2, 0xE4, 0x6E, 0x24, 0x20, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x6B, 0x7F, 0x7B, 0xF9, 0xB0, 0xB8, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x7B, 0x3C, 0xE1, 0x19, 0xA1, 0x23, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0xE3, 0xC2, 0x53, 0xC0, 0x07, 0x13, 0xA9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFE, 0x36, 0x35, 0x9F, 0x5E, 0x59, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x55, 0x89, 0x84, 0xBC, 0xEF, 0xA2, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x1A, 0x08, 0x67, 0xB4, 0xE7, 0x22, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0x26, 0xDF, 0x81, 0x3C, 0x5F, 0x1C, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x4D, 0xD0, 0x0A, 0x48, 0x06, 0xF4, 0x48 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x18, 0x39, 0xF7, 0xD1, 0x20, 0x77, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0x8F, 0x44, 0x13, 0xCB, 0x78, 0x11, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0xE2, 0x49, 0xEA, 0x43, 0x79, 0x08, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0xD1, 0xD8, 0x73, 0x2C, 0x71, 0x2F, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xE5, 0xE7, 0xF4, 0x46, 0xAB, 0x20, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0x0B, 0xB9, 0x71, 0x1A, 0x27, 0xB7, 0xA7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0xA2, 0x2C, 0xD1, 0xDA, 0xBC, 0xC1, 0xBD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xA3, 0x10, 0x1F, 0x90, 0xF2, 0xA5, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0xFB, 0x20, 0xF4, 0xC0, 0x70, 0xC0, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8F, 0xA7, 0x99, 0xF0, 0xA5, 0xD3, 0x09, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0xE8, 0x14, 0x39, 0xBE, 0xCB, 0x60, 0xAF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9F, 0xD6, 0x14, 0xA9, 0xC9, 0x20, 0xC3, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0xA8, 0x5B, 0xFD, 0x2D, 0x96, 0xBC, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x04, 0x45, 0xBE, 0xCE, 0x75, 0x95, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0xDA, 0x58, 0x49, 0x35, 0x09, 0x8D, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0xF0, 0xC0, 0x36, 0xF2, 0xA6, 0x2D, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xFC, 0x3D, 0xA8, 0xFB, 0x3C, 0xD2, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x4D, 0x71, 0x09, 0x18, 0x42, 0xF0, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xC1, 0xCE, 0x9E, 0x6A, 0x49, 0x60, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0xB1, 0x00, 0xF7, 0xA1, 0x7A, 0x31, 0xB4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0xC3, 0x86, 0xCD, 0x20, 0x4A, 0x17, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0xAB, 0x8B, 0x47, 0x8D, 0xAA, 0xA6, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC4, 0x97, 0xF0, 0xBC, 0x2D, 0xDC, 0x9D, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x86, 0xB0, 0x74, 0xB2, 0xF4, 0xF6, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xBD, 0xAC, 0xE3, 0x8F, 0x43, 0x5C, 0xB1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xC3, 0xE2, 0x6E, 0x25, 0x49, 0xCD, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x5E, 0x08, 0xB3, 0xB9, 0xAC, 0x5F, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0xB7, 0xD1, 0xF4, 0xDC, 0x19, 0xE9, 0xC8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0xE4, 0xFA, 0xE1, 0x36, 0x3E, 0xED, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x67, 0x92, 0x84, 0x6E, 0x48, 0x03, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9E, 0x95, 0xEF, 0x8F, 0xB2, 0x82, 0x6B, 0x1C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xFA, 0xB9, 0x55, 0x23, 0xFE, 0x09, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x79, 0x85, 0x4B, 0x0E, 0xD4, 0x35, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0x27, 0x45, 0x81, 0xE0, 0x88, 0x52, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0x63, 0xA2, 0x4B, 0xBC, 0x5D, 0xB1, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x8C, 0x83, 0xD9, 0x3E, 0xD3, 0x42, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0x03, 0x3A, 0x31, 0xBA, 0xE9, 0x3A, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0x10, 0xCD, 0x2D, 0x00, 0xFE, 0x32, 0xA7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0x6E, 0x1F, 0xDA, 0xF8, 0x6F, 0x4D, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x79, 0x7D, 0x09, 0xE5, 0xD3, 0x03, 0x21 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0xC3, 0xBE, 0xDF, 0x07, 0x65, 0x49, 0xCC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x57, 0x33, 0xEF, 0xAE, 0x4F, 0x04, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0xE9, 0x9B, 0xFE, 0xBF, 0xE6, 0x85, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBD, 0xBA, 0xAA, 0x06, 0xC4, 0xC6, 0xB8, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x83, 0x01, 0xA9, 0xF6, 0x51, 0xE7, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xA6, 0x15, 0x8E, 0xAB, 0x1F, 0x10, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x08, 0x27, 0x1A, 0xA1, 0x21, 0xAD, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0x09, 0x90, 0x6E, 0x50, 0x90, 0x9A, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x9A, 0xFE, 0xD7, 0xA1, 0xF5, 0xA2, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x7D, 0xE3, 0xDC, 0x21, 0xFB, 0xA4, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xBF, 0x07, 0xFF, 0x45, 0xDF, 0x51, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0x5C, 0x34, 0x02, 0x62, 0x9B, 0x08, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0xCE, 0x9A, 0x6A, 0xEC, 0x75, 0xF6, 0x46 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x59, 0xF4, 0x78, 0x3C, 0x60, 0xB1, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0x37, 0x84, 0x6A, 0xDC, 0xF2, 0x9A, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x9A, 0x9A, 0x15, 0x36, 0xE0, 0x2B, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x38, 0x9C, 0x50, 0x3D, 0x1E, 0x37, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x79, 0xF0, 0x92, 0xF2, 0x8B, 0x18, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xE0, 0x82, 0x1E, 0x80, 0x82, 0x4B, 0xD7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xBB, 0x59, 0x6B, 0x8A, 0x77, 0x41, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0xF9, 0xD4, 0xB8, 0x4A, 0x82, 0xCF, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0x8C, 0xC8, 0x9B, 0x72, 0x9E, 0xF7, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0xCE, 0xE9, 0x77, 0x0A, 0x19, 0x59, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xA1, 0x41, 0x6A, 0x72, 0x4B, 0xB4, 0xDC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0x35, 0x43, 0xE2, 0x8C, 0xBE, 0x0D, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0xEB, 0xAD, 0xF3, 0xA9, 0xA6, 0x68, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0x2F, 0xE2, 0x48, 0x0C, 0xDB, 0x1F, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x1E, 0x60, 0x9B, 0x2A, 0xD2, 0xC1, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0x64, 0xB5, 0xD2, 0xF6, 0xF6, 0x6E, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0x3D, 0x30, 0x78, 0x10, 0x18, 0x41, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0x1D, 0x1C, 0xE0, 0x6D, 0x83, 0xD1, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x03, 0x0B, 0xF5, 0x2F, 0x6C, 0x04, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x3E, 0xD5, 0xFC, 0x31, 0x5B, 0x3A, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x82, 0x2F, 0xFB, 0xFE, 0xF8, 0x76, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0x26, 0xDA, 0x9C, 0x36, 0xF5, 0x93, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4C, 0xE7, 0x6E, 0xD2, 0x7D, 0x81, 0x09, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0x03, 0xF9, 0x58, 0x48, 0x24, 0xA2, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0x79, 0x0C, 0x8E, 0x6B, 0x95, 0xF3, 0xC4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0x10, 0x5C, 0x87, 0x03, 0x39, 0xCF, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0xF0, 0xF7, 0xC1, 0x07, 0xA4, 0xF4, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0xE8, 0x02, 0x89, 0x65, 0xC4, 0x72, 0x36 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x88, 0xEA, 0x96, 0x67, 0x0B, 0x5D, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x75, 0x60, 0xA8, 0xBD, 0x74, 0xDF, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6E, 0xE5, 0x71, 0x50, 0x67, 0xD0, 0xD2, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xFC, 0xE5, 0xC7, 0x77, 0xB0, 0x7F, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x86, 0x69, 0xCD, 0x0D, 0x9A, 0xBD, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0x17, 0xBC, 0xBB, 0x59, 0x85, 0x7D, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xA8, 0x76, 0xAC, 0x80, 0xA9, 0x72, 0xE0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x78, 0xC1, 0xE2, 0x4D, 0xAF, 0xF9, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x97, 0x8E, 0x74, 0xC4, 0x4B, 0xB2, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0xD8, 0xF6, 0xF3, 0xAF, 0x2F, 0x52, 0xE5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0x57, 0xF4, 0xCE, 0xEE, 0x43, 0xED, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x46, 0x38, 0xDE, 0x20, 0xFD, 0x59, 0x18 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x18, 0xE8, 0x58, 0xB9, 0x76, 0x2C, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0x54, 0xE4, 0xFE, 0xC7, 0xBC, 0x31, 0x37 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xF8, 0x89, 0xEE, 0x70, 0xB5, 0xB0, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x22, 0x26, 0x9A, 0x53, 0xB9, 0x38, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xA7, 0x19, 0x8C, 0x74, 0x7E, 0x88, 0x46 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xDA, 0x0A, 0xE8, 0xDA, 0xA5, 0xBE, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0x5C, 0xF7, 0xB1, 0x0C, 0x72, 0xFB, 0x09 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0xE2, 0x23, 0xE7, 0x46, 0xB7, 0xE0, 0x91 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0x36, 0xBC, 0xBD, 0x48, 0x11, 0x8E, 0x72 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0xBB, 0xA1, 0xF7, 0x0B, 0x9E, 0xBF, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x28, 0xE1, 0xA2, 0x8F, 0xFC, 0xFC, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0xFE, 0x19, 0x0A, 0xE5, 0xE7, 0x69, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0xCD, 0x12, 0xF5, 0xBE, 0xD3, 0x04, 0xF1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xA8, 0x0D, 0x81, 0x59, 0xC4, 0x79, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0xF3, 0x4B, 0x92, 0x65, 0xC3, 0x31, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0xB5, 0x4F, 0x4D, 0x91, 0xD4, 0xE2, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x09, 0x41, 0x79, 0x1D, 0x4D, 0x0D, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x31, 0x18, 0xBA, 0xA0, 0xF2, 0x6E, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x5B, 0x4D, 0x4F, 0xAF, 0xC9, 0x8C, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x48, 0x99, 0x9C, 0x06, 0x68, 0xDE, 0xD8, 0x29 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x04, 0xE1, 0xB5, 0x9D, 0x00, 0xBC, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x95, 0x92, 0x8D, 0x72, 0xD3, 0x37, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0x4B, 0x27, 0xA2, 0xE8, 0xA4, 0x26, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0x45, 0x9C, 0xA9, 0xCB, 0x9F, 0xBA, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x7E, 0x1B, 0x64, 0xF4, 0xE8, 0xA5, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0x20, 0xA9, 0xCA, 0xF3, 0x89, 0xE5, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0xED, 0xFC, 0xAB, 0xD9, 0x0A, 0xB9, 0x07 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x6F, 0x46, 0x7C, 0xCD, 0x78, 0xFF, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0xAB, 0x71, 0x5A, 0x94, 0xAB, 0x20, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x2E, 0xEE, 0x87, 0x57, 0x1F, 0xAD, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0x4C, 0x3D, 0xFB, 0x7E, 0xA1, 0x8B, 0x07 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0xCF, 0x07, 0x86, 0xBA, 0x53, 0x37, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x26, 0xB2, 0xB9, 0xE2, 0x91, 0xE3, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0xC9, 0x54, 0x84, 0x08, 0x3D, 0x0B, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0xA8, 0x77, 0x2F, 0x64, 0x45, 0x99, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x96, 0x16, 0x1F, 0xDB, 0x96, 0x28, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x2B, 0x8D, 0xFF, 0xA2, 0x4F, 0x55, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0xE6, 0x48, 0xBD, 0x99, 0x3D, 0x12, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x84, 0x59, 0xDA, 0xB9, 0xB6, 0x66, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x78, 0x41, 0x92, 0xDF, 0xF4, 0x3F, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x86, 0x6F, 0x4F, 0xBF, 0x67, 0xDF, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x2B, 0x1E, 0x5F, 0x00, 0xEA, 0xF6, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0xB9, 0x6A, 0x89, 0xD8, 0xC0, 0xD7, 0xA7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x9A, 0x32, 0x23, 0xA0, 0x02, 0x91, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x7F, 0x6A, 0x15, 0x64, 0x6A, 0x8B, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0x57, 0x82, 0x58, 0xA9, 0x56, 0xB5, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x50, 0x92, 0x60, 0xCC, 0x81, 0x24, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0x3D, 0xAD, 0xDA, 0xD9, 0x51, 0x3E, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0xFE, 0x8F, 0xB0, 0x0B, 0xDE, 0x2E, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0xD2, 0xBE, 0xEF, 0xAC, 0x76, 0x71, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0xE8, 0x72, 0x0B, 0xAC, 0xFE, 0xCA, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x5B, 0xC7, 0xFC, 0xE3, 0x3C, 0x7C, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x04, 0xA7, 0xB9, 0x9B, 0x93, 0xC0, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x48, 0x4B, 0x8E, 0x32, 0xC5, 0xF0, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x42, 0x07, 0xC1, 0xF2, 0xF1, 0x72, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0x37, 0x54, 0x9C, 0x88, 0xD2, 0x62, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x19, 0x8A, 0x89, 0x58, 0xA2, 0x0F, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0xCC, 0x4C, 0x97, 0x30, 0x66, 0x34, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x6A, 0x1E, 0x1F, 0xDB, 0xC9, 0x5E, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0x4D, 0x49, 0xFF, 0x9B, 0x9C, 0xAC, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD7, 0xE4, 0x4B, 0xF2, 0xD4, 0x1A, 0xD2, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xDA, 0xE8, 0x61, 0x9F, 0xC8, 0x49, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0xCB, 0xF2, 0x2D, 0x85, 0xF6, 0x8D, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xC5, 0xCD, 0x2C, 0x79, 0xC6, 0x0E, 0x4F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x1D, 0x55, 0x0F, 0xF8, 0x22, 0x9F, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0x56, 0xBA, 0xE7, 0x57, 0x32, 0xEC, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x9A, 0xC6, 0x4C, 0x09, 0xC4, 0x52, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x1E, 0x6F, 0xF4, 0x7D, 0x27, 0xDD, 0xAF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x11, 0x16, 0xEC, 0x79, 0x83, 0xAD, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0x4E, 0x92, 0x1F, 0x19, 0x7D, 0x65, 0xDC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0xFF, 0x78, 0x15, 0x45, 0x63, 0x32, 0xE4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x91, 0xD0, 0x78, 0x58, 0xDA, 0x50, 0x47 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0xDE, 0x40, 0xF6, 0x41, 0xB4, 0x3B, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0x8D, 0xE0, 0xE1, 0xA9, 0xF0, 0x35, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xD4, 0xBA, 0x7B, 0xCC, 0x1B, 0x3A, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x5A, 0x2E, 0x74, 0x47, 0x14, 0xC3, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0xF0, 0x8B, 0x06, 0x15, 0x8E, 0x0E, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0xD2, 0xEB, 0x97, 0x50, 0x7D, 0x31, 0xFC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x93, 0x4C, 0xDB, 0x97, 0x79, 0x44, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0xA2, 0xA0, 0x0B, 0xC8, 0x3A, 0x8A, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0x50, 0x92, 0x9E, 0x24, 0x1F, 0xCB, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0x16, 0xC9, 0xC5, 0x3D, 0x5A, 0xAF, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0xE3, 0x97, 0xE4, 0xA8, 0x50, 0xF6, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x45, 0x57, 0x97, 0x42, 0x78, 0x92, 0x49, 0x0D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0xEB, 0x62, 0x24, 0xFB, 0x8F, 0x32, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x0C, 0x36, 0x6E, 0x8F, 0xE8, 0xE8, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0xD3, 0x7C, 0xC7, 0x8D, 0x3F, 0x5C, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0x64, 0x6A, 0x73, 0x10, 0x79, 0xB8, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0xF9, 0xEF, 0xA5, 0x20, 0x4A, 0x5C, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xF3, 0xF4, 0x49, 0x5B, 0x73, 0xAA, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0xF2, 0xEA, 0x0F, 0x00, 0xAD, 0x53, 0xAB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0xB8, 0x66, 0xED, 0xC4, 0x2B, 0x4C, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0x2F, 0xC1, 0x9A, 0x37, 0xD2, 0x7F, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xA7, 0x81, 0x38, 0x64, 0xC9, 0x37, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0x3B, 0x6C, 0x9F, 0x5B, 0xD9, 0x8B, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x14, 0xD9, 0x08, 0xD8, 0xD2, 0x7E, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x71, 0xE6, 0x3D, 0xD1, 0xB0, 0xE7, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0x81, 0x23, 0xEC, 0x2D, 0x42, 0x45, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x5B, 0x44, 0x6B, 0x89, 0x03, 0x67, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x27, 0xAE, 0x80, 0x5A, 0x33, 0xBE, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0xB6, 0x64, 0x1A, 0xDF, 0xD3, 0x85, 0x91 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x8C, 0x22, 0xBA, 0xD0, 0xBD, 0xCC, 0xA0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0x3C, 0x01, 0x3A, 0xFF, 0x9D, 0xC7, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0xC7, 0x64, 0xB4, 0x59, 0x4E, 0x9F, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x34, 0x0A, 0x41, 0x94, 0xA8, 0xF2, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xD4, 0xE4, 0xF0, 0x97, 0x45, 0x6D, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8F, 0x1F, 0x4D, 0x6D, 0xFE, 0xA0, 0xC4, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x28, 0x5C, 0x40, 0xBB, 0x65, 0xD4, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0xA8, 0x87, 0x35, 0x20, 0x3A, 0x89, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xFD, 0x4F, 0xAB, 0x2D, 0xD1, 0xD0, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0xE8, 0x00, 0xFC, 0x69, 0x52, 0xF8, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x9A, 0x99, 0xE1, 0xDC, 0x9C, 0x3F, 0xD9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x08, 0x98, 0xD9, 0xCA, 0x73, 0xD5, 0xA9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x2C, 0xE0, 0xA7, 0x3E, 0x91, 0xD7, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x04, 0xB0, 0x54, 0x09, 0xF4, 0x72, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0xEE, 0x28, 0xCC, 0xE8, 0x50, 0x78, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0D, 0x91, 0x03, 0x76, 0xDB, 0x68, 0x24, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xE0, 0x56, 0xB2, 0x5D, 0x12, 0xD3, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0D, 0x42, 0x59, 0x8B, 0xDF, 0x67, 0xB5, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0xCC, 0xE5, 0x31, 0x53, 0x7A, 0x46, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_16_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0x8D, 0x59, 0xB5, 0x1B, 0x0F, 0xF4, 0xAF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x2F, 0xD1, 0x2C, 0xE0, 0xD8, 0x04, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xF4, 0xD7, 0xBA, 0xB0, 0xA3, 0x7E, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0x08, 0x51, 0x56, 0xA6, 0x76, 0x67, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0x17, 0x63, 0xFE, 0x56, 0xD0, 0xD9, 0x71 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0xF6, 0xC3, 0x14, 0x47, 0xC5, 0xA7, 0x31 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x4C, 0x80, 0xF6, 0xA2, 0x57, 0xA7, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0xB3, 0x7B, 0xF8, 0x2F, 0xE1, 0x3E, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_16_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0xF4, 0xF9, 0x6B, 0x7B, 0x90, 0xDF, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x82, 0xEF, 0x62, 0xA1, 0x4C, 0x53, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x99, 0x76, 0x01, 0xBA, 0x8D, 0x0F, 0x54 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xF4, 0x58, 0x73, 0x56, 0xFE, 0xDD, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xCE, 0xF9, 0xE8, 0xA1, 0x34, 0xC3, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x5F, 0xDC, 0x6A, 0x3D, 0xD8, 0x7F, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0xF4, 0x51, 0xB8, 0xB8, 0xC1, 0xD7, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x7D, 0x58, 0xD1, 0xD4, 0x1B, 0x4D, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_17_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x95, 0xDF, 0x00, 0xD8, 0x21, 0xDE, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0x47, 0x3C, 0xC3, 0xB2, 0x01, 0x53, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0x17, 0x43, 0x23, 0xBD, 0xCA, 0x71, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0xBA, 0x0F, 0x4F, 0xDC, 0x41, 0x54, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x39, 0x26, 0x70, 0x53, 0x32, 0x18, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0x46, 0x07, 0x97, 0x3A, 0x57, 0xE0, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x92, 0x4F, 0xCE, 0xDF, 0x25, 0x80, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0x6F, 0x9A, 0x03, 0x05, 0x4B, 0xD1, 0x47 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_17_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x25, 0x01, 0x72, 0x30, 0x90, 0x17, 0x51, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xFB, 0x41, 0x65, 0x5C, 0xB4, 0x2D, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xCD, 0xCD, 0xAA, 0x41, 0xCC, 0xBB, 0x07 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0xCE, 0x08, 0x0A, 0x63, 0xE9, 0xA2, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xA8, 0x21, 0x7F, 0x7A, 0x5B, 0x9B, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x6B, 0x89, 0x44, 0x0A, 0x7F, 0x85, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0xDE, 0x7C, 0x19, 0x5C, 0x65, 0x26, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD7, 0xAC, 0x62, 0x29, 0x4A, 0xF1, 0xD0, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_18_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0x00, 0x40, 0x87, 0xEB, 0xA9, 0x58, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0x51, 0x0B, 0xFF, 0x56, 0x35, 0x51, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0xAC, 0x08, 0x94, 0x71, 0xDA, 0xEC, 0x99 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x4D, 0xC5, 0x7B, 0x31, 0x8B, 0x8D, 0x5E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x05, 0xF1, 0x3E, 0x9E, 0x8F, 0x17, 0x8F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0x9C, 0x4B, 0x62, 0x94, 0xAD, 0x49, 0xFC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xC9, 0xC6, 0x8F, 0xFD, 0x33, 0x44, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x96, 0x17, 0x7F, 0x42, 0xBE, 0xF7, 0x0D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_18_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0x29, 0x39, 0x13, 0x08, 0x8D, 0x91, 0x47 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x79, 0xF9, 0x2F, 0xA9, 0x0A, 0xCF, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0x87, 0x7A, 0xA3, 0x19, 0xAB, 0x55, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x0B, 0x01, 0xC5, 0x56, 0x19, 0x9D, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0xDE, 0x82, 0x3B, 0xEA, 0xD3, 0x0B, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x6B, 0xC7, 0xF3, 0x0F, 0x82, 0x87, 0x6C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0x2E, 0x23, 0xF2, 0x39, 0x9D, 0x49, 0x70 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0xDE, 0xAF, 0x7A, 0xEE, 0xB0, 0xDA, 0x70 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_19_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0x4E, 0x2A, 0x50, 0xFD, 0x8E, 0xC0, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0x0F, 0x7C, 0x76, 0x63, 0xD8, 0x89, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x2D, 0xB9, 0x4E, 0xF4, 0xEE, 0x85, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x95, 0x5C, 0x96, 0x5D, 0xAA, 0x59, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0xDB, 0xD2, 0x68, 0x8E, 0x5A, 0x94, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x02, 0xBF, 0x77, 0x9F, 0xB9, 0x4C, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0xDC, 0xC0, 0xCF, 0x81, 0x1E, 0xC4, 0x6C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0xCC, 0x37, 0x86, 0xDC, 0xE2, 0x64, 0x72 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_19_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x30, 0xB1, 0x59, 0x20, 0x9D, 0x98, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x0C, 0x9D, 0xF8, 0x20, 0xDC, 0x90, 0xBA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xA0, 0xF4, 0xE7, 0x3E, 0x9C, 0x9E, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0x25, 0xA2, 0xB0, 0x54, 0xCD, 0x2E, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0xD9, 0x42, 0xB0, 0x80, 0xB0, 0xA3, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9F, 0xFE, 0x9D, 0x8D, 0x40, 0xFF, 0x27, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0x9D, 0xA6, 0x88, 0x3A, 0x8B, 0x6F, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x39, 0xEE, 0x1F, 0x3F, 0xB1, 0x4F, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_20_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xD7, 0x9E, 0xFF, 0xD2, 0x35, 0x67, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x4F, 0x15, 0x5D, 0xE3, 0xE8, 0x53, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0xF7, 0x24, 0x98, 0xA2, 0xCB, 0x11, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x2E, 0x25, 0xE1, 0x94, 0xC5, 0xA3, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x82, 0x6E, 0xBA, 0xE7, 0x43, 0x25, 0xB0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0x65, 0xB4, 0x49, 0x73, 0x18, 0x35, 0x54 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0x5B, 0xBC, 0x62, 0x86, 0x4C, 0xC1, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0xF2, 0x95, 0xA2, 0xBB, 0xA2, 0x35, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_20_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x59, 0x62, 0xB0, 0x4B, 0x1E, 0xB4, 0xD8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0D, 0x55, 0xCE, 0xB0, 0x69, 0xBA, 0x63, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6E, 0x69, 0x86, 0xDB, 0x34, 0x7D, 0x68, 0x64 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x06, 0xCA, 0x55, 0x44, 0x36, 0x2B, 0xBA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0xD4, 0xC4, 0x3D, 0xCD, 0x9E, 0x69, 0xA4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x44, 0xE4, 0xBF, 0x31, 0xE6, 0x40, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x4F, 0xFA, 0x75, 0xE3, 0xFB, 0x97, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0xC0, 0xBD, 0x1C, 0x48, 0xB0, 0x26, 0xD0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_21_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x7B, 0x32, 0xFA, 0xF2, 0x6D, 0x84, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x21, 0x03, 0x1D, 0x0D, 0x22, 0x55, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0xF9, 0x42, 0x03, 0x9C, 0xC2, 0xCB, 0xBA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0xA1, 0x96, 0xD9, 0x9D, 0x11, 0x6F, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x40, 0x57, 0xEB, 0x40, 0x2D, 0xC0, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0x96, 0xBB, 0x4F, 0x2F, 0x23, 0xA8, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0x29, 0x85, 0x21, 0xA5, 0x50, 0x62, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x7D, 0x92, 0xCF, 0x87, 0x0C, 0x22, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_21_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x0E, 0xA5, 0x32, 0x5B, 0xDF, 0x9C, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0x96, 0x37, 0x2C, 0x88, 0x35, 0x30, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xB4, 0x69, 0xFF, 0xEB, 0xC6, 0x94, 0x08 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x55, 0x60, 0xAD, 0xAA, 0x58, 0x14, 0x88 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0xFF, 0xF2, 0xB2, 0xD5, 0xA7, 0xD9, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0xAE, 0x54, 0xD2, 0x60, 0x31, 0xF3, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x92, 0x83, 0xE3, 0xF1, 0x42, 0x83, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0xD2, 0xC8, 0xB7, 0x76, 0x45, 0x7F, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_22_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4A, 0x11, 0xA4, 0xFB, 0x7A, 0x01, 0xBC, 0xC8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0x27, 0x73, 0x8D, 0x02, 0x91, 0x27, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x62, 0xF6, 0xDD, 0x6B, 0xFA, 0x5B, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0xCA, 0xA2, 0x44, 0x2C, 0xF0, 0x28, 0xD8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0xF1, 0x7A, 0xA2, 0x42, 0x4C, 0x50, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0x83, 0x3E, 0x50, 0xAB, 0x9C, 0xF7, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0xED, 0x78, 0xCB, 0x76, 0x69, 0xDA, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x01, 0x1E, 0x43, 0x27, 0x47, 0x6E, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_22_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0x4F, 0x54, 0xB9, 0x3E, 0xBD, 0xD5, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x35, 0x40, 0x69, 0x7F, 0x74, 0x9D, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x06, 0x6F, 0x67, 0x68, 0x2B, 0x4D, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0x65, 0x41, 0xFC, 0x7C, 0x1E, 0xE8, 0xC8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x79, 0x37, 0xAF, 0xFD, 0xD2, 0xDA, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0xA8, 0x69, 0x56, 0x62, 0xA4, 0xE4, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x71, 0x73, 0x21, 0x8A, 0x17, 0x81, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x14, 0x55, 0x8F, 0x7B, 0xB8, 0xAF, 0xF7, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_23_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0xD1, 0xBD, 0xBE, 0x8C, 0xBC, 0x60, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0xA6, 0x57, 0x8C, 0xAE, 0x5C, 0x19, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0x43, 0xE4, 0xD9, 0xD8, 0x7B, 0xE7, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0xB9, 0xE4, 0x85, 0x7C, 0x2E, 0xFC, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0x2E, 0x01, 0x2A, 0x6D, 0x56, 0xBE, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0x0C, 0x25, 0x9B, 0xAE, 0x86, 0x37, 0x43 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4A, 0x22, 0xB3, 0xCB, 0x99, 0x66, 0xB7, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0xF7, 0x90, 0xF0, 0x1B, 0x09, 0x27, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_23_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x16, 0x08, 0xEF, 0x39, 0x64, 0x49, 0x31 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0xA0, 0xE3, 0x97, 0xA9, 0x07, 0x54, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xFF, 0xE2, 0x00, 0x07, 0x21, 0x88, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0xFD, 0x59, 0x53, 0x05, 0x6C, 0x42, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8F, 0xF7, 0x39, 0x5C, 0x82, 0x36, 0xE8, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2E, 0x83, 0xA8, 0xE2, 0xA8, 0x43, 0x07, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xAF, 0x2B, 0x79, 0xED, 0xD8, 0x39, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x20, 0x91, 0x7A, 0xC4, 0x07, 0xEF, 0x6C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_24_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0x10, 0x2F, 0xAA, 0x0C, 0x94, 0x0E, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x81, 0x87, 0x41, 0x23, 0xEB, 0x55, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0x53, 0xCC, 0x79, 0xB6, 0xEB, 0x6C, 0xCC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0x77, 0x73, 0x9D, 0xFC, 0x64, 0x6F, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0x40, 0xE3, 0x6D, 0x1C, 0x16, 0x71, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0xF4, 0x1B, 0xFF, 0x1C, 0x2F, 0xA5, 0xD7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x0E, 0x0B, 0x11, 0xF4, 0x8D, 0x93, 0xAF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0xC5, 0x64, 0x6F, 0x24, 0x19, 0xF2, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_24_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xB3, 0xAF, 0xA5, 0x0E, 0x4F, 0x5E, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0x77, 0xCA, 0xF2, 0x6D, 0xC5, 0xF6, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0x18, 0x8E, 0x33, 0x68, 0x6C, 0xE8, 0xE0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x8B, 0x80, 0x90, 0x19, 0x7F, 0x90, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0x80, 0x6B, 0x68, 0xE2, 0x7D, 0xD4, 0xD0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0xC1, 0x67, 0xB3, 0x72, 0xCB, 0xBF, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0xD5, 0xD3, 0x1D, 0x14, 0x58, 0x0A, 0x80 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0x7A, 0x65, 0x98, 0xB3, 0x07, 0x4B, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_25_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0x87, 0x0F, 0x5F, 0xCF, 0xA2, 0x01, 0x08 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0xC9, 0xC8, 0x6E, 0x35, 0x87, 0xA5, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x3E, 0x91, 0xA0, 0xAB, 0x24, 0x1E, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xBC, 0x02, 0x35, 0x70, 0xC1, 0x5F, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x59, 0xA0, 0x50, 0x04, 0x80, 0x52, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0x56, 0x6E, 0x42, 0x8F, 0x8C, 0x91, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xA2, 0xCB, 0xA5, 0xDE, 0x14, 0x24, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0xCB, 0x74, 0x28, 0xE6, 0xA7, 0xE7, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_25_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0x73, 0xA8, 0x8F, 0x9E, 0x0E, 0x63, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0x1B, 0x77, 0xC7, 0xC1, 0x38, 0xF9, 0xDC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0x3C, 0xCF, 0xA8, 0x7A, 0xD7, 0xF3, 0xC4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x5F, 0x9A, 0xC9, 0xAD, 0xE9, 0x1A, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0xCF, 0x2B, 0x5E, 0xD5, 0x81, 0x95, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x88, 0x75, 0x29, 0x1F, 0xC7, 0xC7, 0xD0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0xA9, 0x5A, 0x4D, 0x63, 0x95, 0xF9, 0x4E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xCD, 0x04, 0x8F, 0xCD, 0x91, 0xDE, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_26_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0xD4, 0xFD, 0x25, 0x11, 0x99, 0x6E, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x83, 0x01, 0x3D, 0xFB, 0x56, 0xA5, 0x4E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x3A, 0xDC, 0x74, 0xC2, 0xD7, 0xCF, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8F, 0xBD, 0xF1, 0xDD, 0xA3, 0x07, 0x03, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0xBE, 0xE9, 0x2E, 0x58, 0x84, 0x66, 0xFC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x20, 0x78, 0x37, 0x79, 0x0B, 0xA6, 0x64 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0xF2, 0xAC, 0x65, 0xC8, 0xC9, 0x2F, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x93, 0xE5, 0x0D, 0x0C, 0xC6, 0xB8, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_26_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0xAD, 0x5C, 0x19, 0x12, 0x61, 0x0E, 0x25 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x39, 0x4F, 0x0B, 0x1F, 0x49, 0x7E, 0xCD, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0x2E, 0x30, 0x61, 0xDB, 0x08, 0x68, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x78, 0xAF, 0xB3, 0x08, 0xC1, 0x69, 0xE5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC4, 0x5F, 0x5D, 0xC1, 0x57, 0x6F, 0xD8, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0xD3, 0x6A, 0xF7, 0xFD, 0x86, 0xE5, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x63, 0xBD, 0x70, 0x7B, 0x47, 0xE8, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0x62, 0xC8, 0x7E, 0x9D, 0x11, 0x2B, 0xA5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_27_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0x84, 0xFD, 0xD5, 0x9A, 0x56, 0x7F, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0xBB, 0xA4, 0x6F, 0x12, 0x6E, 0x4D, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x08, 0xA1, 0x82, 0x9C, 0x62, 0x74, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9E, 0x58, 0x22, 0x05, 0x1D, 0x15, 0x35, 0x79 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0x88, 0xCF, 0x5C, 0x05, 0x78, 0xFB, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x6B, 0x2F, 0x79, 0x09, 0x73, 0x67, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0xA0, 0x80, 0xD8, 0xE8, 0xEC, 0xFB, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xE7, 0x0B, 0xB7, 0x81, 0x48, 0x7B, 0xD9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_27_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x53, 0xA9, 0xED, 0x61, 0x92, 0xD7, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x49, 0xD9, 0x5D, 0x9B, 0x4E, 0x89, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0x12, 0xEB, 0x9A, 0xC9, 0xCB, 0xC1, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0xDC, 0x95, 0x16, 0xFE, 0x29, 0x70, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x33, 0xB1, 0xD6, 0x78, 0xB9, 0xE2, 0x36 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xCE, 0x88, 0xC3, 0xFD, 0x7A, 0x6B, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x1E, 0x50, 0x1E, 0xAF, 0xB1, 0x25, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0xE7, 0xD7, 0xD5, 0xBD, 0x7A, 0x12, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_28_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xAA, 0xA2, 0x80, 0x5D, 0x8F, 0xCD, 0xC8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x48, 0x39, 0x79, 0x64, 0xA1, 0x67, 0x3C, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xC7, 0x49, 0xFF, 0x7F, 0xAC, 0xAB, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0x54, 0x3E, 0x83, 0xF0, 0x3D, 0xBC, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x92, 0x4A, 0x38, 0x42, 0x8A, 0xAB, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x0B, 0x4F, 0xEE, 0x9E, 0x92, 0xA5, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xDD, 0x19, 0x96, 0xF2, 0xF0, 0x6B, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0xFC, 0xDD, 0xB2, 0x8A, 0xE5, 0x4C, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_28_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x06, 0x49, 0xAC, 0x99, 0x7E, 0xF8, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0xC8, 0x01, 0x51, 0xEA, 0xF6, 0x52, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0x89, 0x66, 0x2B, 0x1F, 0x9B, 0x2A, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x0F, 0x95, 0x07, 0x2B, 0x6C, 0x6E, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0xC3, 0xB4, 0xBB, 0x91, 0x1F, 0xA3, 0x72 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x6E, 0x54, 0x28, 0x7B, 0x9C, 0x79, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0x45, 0xFF, 0xA6, 0xDA, 0xA2, 0x83, 0x71 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xDE, 0x8F, 0x17, 0x37, 0x82, 0xCB, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_29_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0x94, 0x3F, 0x26, 0xC9, 0x1D, 0xD9, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x97, 0x28, 0x20, 0xCD, 0xC1, 0xF3, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0xC9, 0xB5, 0x60, 0x9B, 0x1E, 0xDC, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0xB9, 0x5B, 0x7D, 0xA0, 0xB2, 0x8C, 0xF0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0xD1, 0x42, 0xE6, 0x39, 0x33, 0x6D, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0xC0, 0xFC, 0xD2, 0x14, 0x5D, 0x3E, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0x4A, 0x3E, 0x40, 0x16, 0x93, 0x15, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x24, 0xC1, 0x27, 0x27, 0xE5, 0x4B, 0xD8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_29_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x50, 0xD8, 0xBC, 0xC1, 0x46, 0x22, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x0E, 0x60, 0xA1, 0xB3, 0x50, 0xD4, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0xB1, 0x26, 0xB6, 0x6D, 0x47, 0x5A, 0x6F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x45, 0xAC, 0x11, 0x35, 0x3E, 0xB9, 0xF4, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0x97, 0xFA, 0xBB, 0x6B, 0x39, 0x13, 0xD8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x7B, 0x34, 0x12, 0x75, 0x8E, 0x9B, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x9E, 0xCD, 0x29, 0xB6, 0xEF, 0x8D, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0xAC, 0xE9, 0x25, 0x27, 0xBB, 0x78, 0x47 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_30_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x7A, 0xA8, 0xD3, 0xE3, 0x66, 0xE5, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0x4C, 0xC4, 0x2C, 0x76, 0x81, 0x50, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x71, 0x08, 0xB8, 0x52, 0x7C, 0xAF, 0xDC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x45, 0x59, 0x24, 0xDD, 0xFB, 0x2F, 0xD0, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xCD, 0x56, 0xE9, 0xAC, 0x91, 0xE6, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0x64, 0x20, 0xC6, 0x9F, 0xE4, 0xEF, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x2C, 0x8F, 0x8C, 0x97, 0xF6, 0x22, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xF4, 0x88, 0xAA, 0xA8, 0xD7, 0xA5, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_30_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x6C, 0xAE, 0x83, 0xB1, 0x55, 0x55, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x67, 0x84, 0x47, 0x7C, 0x83, 0x5C, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0x10, 0x4D, 0xDD, 0x30, 0x60, 0xB0, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xA7, 0x36, 0x76, 0x24, 0x32, 0x9F, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x42, 0x81, 0xFB, 0xA4, 0x2E, 0x13, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x94, 0x91, 0xFF, 0x99, 0xA0, 0x09, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x83, 0xA1, 0x76, 0xAF, 0x37, 0x5C, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xA8, 0x04, 0x86, 0xC4, 0xA9, 0x79, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_31_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x8C, 0xC2, 0x34, 0xFB, 0x83, 0x28, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x03, 0x7D, 0x5E, 0x9E, 0x0E, 0xB0, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA2, 0x02, 0x46, 0x7F, 0xB9, 0xAC, 0xBB, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0xED, 0x48, 0xC2, 0x96, 0x4D, 0x56, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0xB5, 0xC5, 0xD1, 0xE6, 0x1C, 0x7E, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x2E, 0x18, 0x71, 0x2D, 0x7B, 0xD7, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0x46, 0x9D, 0xDE, 0xAA, 0x78, 0x8E, 0xB1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xD7, 0x69, 0x2E, 0xE1, 0xD9, 0x48, 0xDE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_T_31_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xFF, 0x9E, 0x09, 0x22, 0x22, 0xE6, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x14, 0x28, 0x13, 0x1B, 0x62, 0x12, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0x7F, 0x67, 0x03, 0xB0, 0xC0, 0xF3, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xC3, 0x0F, 0xFB, 0x25, 0x48, 0x3E, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0x6E, 0x53, 0x98, 0x36, 0xB3, 0xD3, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0x81, 0x54, 0x22, 0xA4, 0xCC, 0xC1, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xBA, 0xFC, 0xA9, 0xDF, 0x68, 0x86, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x92, 0x0E, 0xC3, 0xF2, 0x58, 0xE8, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_ecp_point secp521r1_T[32] = {
+    ECP_POINT_INIT_XY_Z1(secp521r1_T_0_X, secp521r1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_1_X, secp521r1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_2_X, secp521r1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_3_X, secp521r1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_4_X, secp521r1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_5_X, secp521r1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_6_X, secp521r1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_7_X, secp521r1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_8_X, secp521r1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_9_X, secp521r1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_10_X, secp521r1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_11_X, secp521r1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_12_X, secp521r1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_13_X, secp521r1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_14_X, secp521r1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_15_X, secp521r1_T_15_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_16_X, secp521r1_T_16_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_17_X, secp521r1_T_17_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_18_X, secp521r1_T_18_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_19_X, secp521r1_T_19_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_20_X, secp521r1_T_20_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_21_X, secp521r1_T_21_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_22_X, secp521r1_T_22_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_23_X, secp521r1_T_23_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_24_X, secp521r1_T_24_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_25_X, secp521r1_T_25_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_26_X, secp521r1_T_26_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_27_X, secp521r1_T_27_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_28_X, secp521r1_T_28_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_29_X, secp521r1_T_29_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_30_X, secp521r1_T_30_Y),
+    ECP_POINT_INIT_XY_Z0(secp521r1_T_31_X, secp521r1_T_31_Y),
+};
+#else
+#define secp521r1_T NULL
+#endif
+#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+static const mbedtls_mpi_uint secp192k1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp192k1_a[] = {
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp192k1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x03, 0x00 ),
+};
+static const mbedtls_mpi_uint secp192k1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
+};
+static const mbedtls_mpi_uint secp192k1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
+};
+static const mbedtls_mpi_uint secp192k1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint secp192k1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
+};
+static const mbedtls_mpi_uint secp192k1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
+};
+static const mbedtls_mpi_uint secp192k1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x77, 0x3D, 0x0D, 0x85, 0x48, 0xA8, 0xA9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x07, 0xDF, 0x1D, 0xB3, 0xB3, 0x01, 0x54 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0x86, 0xF6, 0xAF, 0x19, 0x2A, 0x88, 0x2E ),
+};
+static const mbedtls_mpi_uint secp192k1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0x90, 0xB6, 0x2F, 0x48, 0x36, 0x4C, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x11, 0x14, 0xA6, 0xCB, 0xBA, 0x15, 0xD9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0xB0, 0xF2, 0xD4, 0xC9, 0xDA, 0xBA, 0xD7 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0xC1, 0x9C, 0xE6, 0xBB, 0xFB, 0xCF, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x19, 0xAC, 0x5A, 0xC9, 0x8A, 0x1C, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0xF6, 0x76, 0x86, 0x89, 0x27, 0x8D, 0x28 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0xE0, 0x6F, 0x34, 0xBA, 0x5E, 0xD3, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0xDC, 0xA6, 0x87, 0xC9, 0x9D, 0xC0, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x11, 0x7E, 0xD6, 0xF7, 0x33, 0xFC, 0xE4 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x37, 0x3E, 0xC0, 0x7F, 0x62, 0xE7, 0x54 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x3B, 0x69, 0x9D, 0x44, 0xBC, 0x82, 0x99 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x84, 0xB3, 0x5F, 0x2B, 0xA5, 0x9E, 0x2C ),
+};
+static const mbedtls_mpi_uint secp192k1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x95, 0xEB, 0x4C, 0x04, 0xB4, 0xF4, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0xAD, 0x4B, 0xD5, 0x9A, 0xEB, 0xC4, 0x4E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xB1, 0xC5, 0x59, 0xE3, 0xD5, 0x16, 0x2A ),
+};
+static const mbedtls_mpi_uint secp192k1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x48, 0x2A, 0xCC, 0xAC, 0xD0, 0xEE, 0x50, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0x83, 0xE0, 0x5B, 0x14, 0x44, 0x52, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x15, 0x2D, 0x78, 0xF6, 0x51, 0x32, 0xCF ),
+};
+static const mbedtls_mpi_uint secp192k1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x36, 0x9B, 0xDD, 0xF8, 0xDD, 0xEF, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0xB1, 0x6A, 0x2B, 0xAF, 0xEB, 0x2B, 0xB1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x87, 0x7A, 0x66, 0x5D, 0x5B, 0xDF, 0x8F ),
+};
+static const mbedtls_mpi_uint secp192k1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x45, 0xE5, 0x81, 0x9B, 0xEB, 0x37, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x29, 0xE2, 0x20, 0x64, 0x23, 0x6B, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0x1D, 0x41, 0xE1, 0x9B, 0x61, 0x7B, 0xD9 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0x57, 0xA3, 0x0A, 0x13, 0xE4, 0x59, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0x6E, 0x4A, 0x48, 0x84, 0x90, 0xAC, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0xB8, 0xF5, 0xF3, 0xDE, 0xA0, 0xA1, 0x1D ),
+};
+static const mbedtls_mpi_uint secp192k1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0x32, 0x81, 0xA9, 0x91, 0x5A, 0x4E, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0xA8, 0x90, 0xBE, 0x0F, 0xEC, 0xC0, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0x30, 0xD7, 0x08, 0xAE, 0xC4, 0x3A, 0xA5 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x55, 0xE3, 0x76, 0xB3, 0x64, 0x74, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x75, 0xD4, 0xDB, 0x98, 0xD7, 0x39, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0xEB, 0x8A, 0xAB, 0x16, 0xD9, 0xD4, 0x0B ),
+};
+static const mbedtls_mpi_uint secp192k1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0xBE, 0xF9, 0xC7, 0xC7, 0xBA, 0xF3, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x85, 0x59, 0xF3, 0x60, 0x41, 0x02, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0x1C, 0x4A, 0xA4, 0xC7, 0xED, 0x66, 0xBC ),
+};
+static const mbedtls_mpi_uint secp192k1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0x9C, 0x2E, 0x46, 0x52, 0x18, 0x87, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x35, 0x5A, 0x75, 0xAC, 0x4D, 0x75, 0x91 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0x2F, 0xAC, 0xFC, 0xBC, 0xE6, 0x93, 0x5E ),
+};
+static const mbedtls_mpi_uint secp192k1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x4D, 0xC9, 0x18, 0xE9, 0x00, 0xEB, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x69, 0x72, 0x07, 0x5A, 0x59, 0xA8, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x65, 0x83, 0x20, 0x10, 0xF9, 0x69, 0x82 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0x56, 0x7F, 0x9F, 0xBF, 0x46, 0x0C, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0xCF, 0xF0, 0xDC, 0xDF, 0x2D, 0xE6, 0xE5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0xF0, 0x72, 0x3A, 0x7A, 0x03, 0xE5, 0x22 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xAA, 0x57, 0x13, 0x37, 0xA7, 0x2C, 0xD4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0xAC, 0xA2, 0x23, 0xF9, 0x84, 0x60, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0xEB, 0x51, 0x70, 0x64, 0x78, 0xCA, 0x05 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0xCC, 0x30, 0x62, 0x93, 0x46, 0x13, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x26, 0xCC, 0x6C, 0x3D, 0x5C, 0xDA, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xAA, 0xB8, 0x03, 0xA4, 0x1A, 0x00, 0x96 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF9, 0x9D, 0xE6, 0xCC, 0x4E, 0x2E, 0xC2, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xC3, 0x8A, 0xAE, 0x6F, 0x40, 0x05, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x8F, 0x4A, 0x4D, 0x35, 0xD3, 0x50, 0x9D ),
+};
+static const mbedtls_mpi_uint secp192k1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0xFD, 0x98, 0xAB, 0xC7, 0x03, 0xB4, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x40, 0xD2, 0x9F, 0xCA, 0xD0, 0x53, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x84, 0x00, 0x6F, 0xC8, 0xAD, 0xED, 0x8D ),
+};
+static const mbedtls_mpi_uint secp192k1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xD3, 0x57, 0xD7, 0xC3, 0x07, 0xBD, 0xD7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0xBA, 0x47, 0x1D, 0x3D, 0xEF, 0x98, 0x6C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xC0, 0x6C, 0x7F, 0x12, 0xEE, 0x9F, 0x67 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x02, 0xDA, 0x79, 0xAA, 0xC9, 0x27, 0xC4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x79, 0xC7, 0x71, 0x84, 0xCB, 0xE5, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x37, 0x06, 0xBA, 0xB5, 0xD5, 0x18, 0x4C ),
+};
+static const mbedtls_mpi_uint secp192k1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x65, 0x72, 0x6C, 0xF2, 0x63, 0x27, 0x6A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0xBC, 0x71, 0xDF, 0x75, 0xF8, 0x98, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x70, 0x9B, 0xDC, 0xE7, 0x18, 0x71, 0xFF ),
+};
+static const mbedtls_mpi_uint secp192k1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x5B, 0x9F, 0x00, 0x5A, 0xB6, 0x80, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xE0, 0xBB, 0xFC, 0x5E, 0x78, 0x9C, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x60, 0x03, 0x68, 0x83, 0x3D, 0x2E, 0x4C, 0xDD ),
+};
+static const mbedtls_mpi_uint secp192k1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0x49, 0x23, 0xA8, 0xCB, 0x3B, 0x1A, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0x3D, 0xA7, 0x46, 0xCF, 0x75, 0xB6, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0xFD, 0x30, 0x01, 0xB6, 0xEF, 0xF9, 0xE8 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDC, 0xFA, 0xDA, 0xB8, 0x29, 0x42, 0xC9, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0xD7, 0xA0, 0xE6, 0x6B, 0x86, 0x61, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0xE9, 0xD3, 0x37, 0xD8, 0xE7, 0x35, 0xA9 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xC8, 0x8E, 0xB1, 0xCB, 0xB1, 0xB5, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0xD7, 0x46, 0x7D, 0xAF, 0xE2, 0xDC, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x46, 0xE7, 0xD8, 0x76, 0x31, 0x90, 0x76 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xD3, 0xF4, 0x74, 0xE1, 0x67, 0xD8, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x70, 0x3C, 0xC8, 0xAF, 0x5F, 0xF4, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0x4E, 0xED, 0x5C, 0x43, 0xB3, 0x16, 0x35 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0xAE, 0xD1, 0xDD, 0x31, 0x14, 0xD3, 0xF0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x14, 0x06, 0x13, 0x12, 0x1C, 0x81, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xF9, 0x0C, 0x91, 0xF7, 0x67, 0x59, 0x63 ),
+};
+static const mbedtls_mpi_uint secp192k1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0x91, 0xE2, 0xF4, 0x9D, 0xEB, 0x88, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x82, 0x30, 0x9C, 0xAE, 0x18, 0x4D, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0x79, 0xCF, 0x17, 0xA5, 0x1E, 0xE8, 0xC8 ),
+};
+static const mbedtls_ecp_point secp192k1_T[16] = {
+    ECP_POINT_INIT_XY_Z1(secp192k1_T_0_X, secp192k1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_1_X, secp192k1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_2_X, secp192k1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_3_X, secp192k1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_4_X, secp192k1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_5_X, secp192k1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_6_X, secp192k1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_7_X, secp192k1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_8_X, secp192k1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_9_X, secp192k1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_10_X, secp192k1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_11_X, secp192k1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_12_X, secp192k1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_13_X, secp192k1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_14_X, secp192k1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(secp192k1_T_15_X, secp192k1_T_15_Y),
+};
+#else
+#define secp192k1_T NULL
+#endif
+
+#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+static const mbedtls_mpi_uint secp224k1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp224k1_a[] = {
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x05, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
+};
+static const mbedtls_mpi_uint secp224k1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
+};
+static const mbedtls_mpi_uint secp224k1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
+};
+
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint secp224k1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0x5B, 0x45, 0xA1, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0x9F, 0x08, 0x7E, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0x6C, 0x22, 0x22, 0x40, 0x89, 0xAE, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0x92, 0xE1, 0x87, 0x56, 0x35, 0xAF, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0xAF, 0x08, 0x35, 0x27, 0xEA, 0x04, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0x53, 0xFD, 0xCF, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0xD0, 0x9F, 0x8D, 0xF3, 0x63, 0x54, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x39, 0xDB, 0x0F, 0x61, 0x54, 0x26, 0xD1, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x21, 0xF7, 0x1B, 0xB5, 0x1D, 0xF6, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x05, 0xDA, 0x8F, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x26, 0x73, 0xBC, 0xE4, 0x29, 0x62, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x95, 0x17, 0x8B, 0xC3, 0x9B, 0xAC, 0xCC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xDB, 0x77, 0xDF, 0xDD, 0x13, 0x04, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0xFC, 0x22, 0x93, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x65, 0xF1, 0x5A, 0x37, 0xEF, 0x79, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0x01, 0x37, 0xAC, 0x9A, 0x5B, 0x51, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x75, 0x13, 0xA9, 0x4A, 0xAD, 0xFE, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0x82, 0x6F, 0x66, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0x5E, 0xF0, 0x40, 0xC3, 0xA6, 0xE2, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x9A, 0x6F, 0xCF, 0x11, 0x26, 0x66, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0x73, 0xA8, 0xCF, 0x2B, 0x12, 0x36, 0x37 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xB3, 0x0A, 0x58, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0x79, 0x00, 0x55, 0x04, 0x34, 0x90, 0x1A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0x54, 0x1C, 0xC2, 0x45, 0x0C, 0x1B, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x19, 0xAB, 0xA8, 0xFC, 0x73, 0xDC, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0xFB, 0x93, 0xCE, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0x75, 0xD0, 0x66, 0x95, 0x86, 0xCA, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xEA, 0x29, 0x16, 0x6A, 0x38, 0xDF, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0xA2, 0x36, 0x2F, 0xDC, 0xBB, 0x5E, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x89, 0x59, 0x49, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0xA3, 0x99, 0x9D, 0xB8, 0x77, 0x9D, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0x93, 0x43, 0x47, 0xC6, 0x5C, 0xF9, 0xFD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x00, 0x79, 0x42, 0x64, 0xB8, 0x25, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x54, 0xB4, 0x33, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x0C, 0x42, 0x90, 0x83, 0x0B, 0x31, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x2E, 0xAE, 0xC8, 0xC7, 0x5F, 0xD2, 0x70 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0xBC, 0xAD, 0x41, 0xE7, 0x32, 0x3A, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0x97, 0x52, 0x83, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x13, 0x7A, 0xBD, 0xAE, 0x94, 0x60, 0xFD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x9B, 0x95, 0xB4, 0x6E, 0x68, 0xB2, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x49, 0xBE, 0x51, 0xFE, 0x66, 0x15, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x37, 0xE4, 0xFE, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x9B, 0xEE, 0x64, 0xC9, 0x1B, 0xBD, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x5F, 0x34, 0xA9, 0x0B, 0xB7, 0x25, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0x13, 0xB1, 0x38, 0xFB, 0x9D, 0x78, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x39, 0xE7, 0x1B, 0xFA, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0xB3, 0xB7, 0x44, 0x92, 0x6B, 0x00, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x82, 0x44, 0x3E, 0x18, 0x1A, 0x58, 0x6A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0xF8, 0xC0, 0xE4, 0xEE, 0xC1, 0xBF, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x32, 0x27, 0xB2, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0x9A, 0x42, 0x62, 0x8B, 0x26, 0x54, 0x21 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0x85, 0x74, 0xA0, 0x79, 0xA8, 0xEE, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0x36, 0x60, 0xB3, 0x28, 0x4D, 0x55, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0x27, 0x82, 0x29, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0D, 0xFC, 0x73, 0x77, 0xAF, 0x5C, 0xAC, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0xED, 0xE5, 0xF6, 0x1D, 0xA8, 0x67, 0x43 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0xDE, 0x33, 0x1C, 0xF1, 0x80, 0x73, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0xE2, 0xDE, 0x3C, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x3E, 0x6B, 0xFE, 0xF0, 0x04, 0x28, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0xB2, 0x14, 0x9D, 0x18, 0x11, 0x7D, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xC4, 0xD6, 0x2E, 0x6E, 0x57, 0x4D, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0x55, 0x1B, 0xDE, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xF7, 0x17, 0xBC, 0x45, 0xAB, 0x16, 0xAB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xB0, 0xEF, 0x61, 0xE3, 0x20, 0x7C, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x85, 0x41, 0x4D, 0xF1, 0x7E, 0x4D, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0xC2, 0x9B, 0x5E, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x2E, 0x49, 0x3D, 0x3E, 0x4B, 0xD3, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0x2B, 0x9D, 0xD5, 0x27, 0xFA, 0xCA, 0xE0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0xB3, 0x6A, 0xE0, 0x79, 0x14, 0x28, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x1E, 0xDC, 0xF5, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x44, 0x56, 0xCD, 0xFC, 0x9F, 0x09, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0x8C, 0x59, 0xA4, 0x64, 0x2A, 0x3A, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xA0, 0xB5, 0x86, 0x4E, 0x69, 0xDA, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x8B, 0x11, 0x38, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x17, 0x16, 0x12, 0x17, 0xDC, 0x00, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x76, 0x24, 0x6C, 0x97, 0x2C, 0xB5, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x82, 0x71, 0xE3, 0xB0, 0xBB, 0x4E, 0x50, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6E, 0x48, 0x26, 0xD5, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x5F, 0x28, 0xF6, 0x01, 0x5A, 0x60, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x95, 0xFE, 0xD0, 0xAD, 0x15, 0xD4, 0xD9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x5B, 0x7A, 0xFD, 0x80, 0xF7, 0x9F, 0x64 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0xBC, 0x1B, 0xDF, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0xE6, 0xDF, 0x14, 0x29, 0xF4, 0xD4, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0x12, 0xDD, 0xEC, 0x5B, 0x8A, 0x59, 0xE5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x92, 0x3E, 0x35, 0x08, 0xE9, 0xCF, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0x35, 0x29, 0x97, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0xDB, 0xD6, 0x6A, 0xC5, 0x43, 0xA4, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x33, 0x50, 0x61, 0x70, 0xA1, 0xE9, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x15, 0x6E, 0x5F, 0x01, 0x0C, 0x8C, 0xFA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0xA1, 0x9A, 0x9D, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6E, 0xC6, 0xF7, 0xE2, 0x4A, 0xCD, 0x9B, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x4D, 0x5A, 0xB8, 0xE2, 0x6D, 0xA6, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0x3F, 0xB6, 0x17, 0xE3, 0x2C, 0x6F, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xA4, 0x59, 0x51, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x4F, 0x7C, 0x49, 0xCD, 0x6E, 0xEB, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0xC9, 0x1F, 0xB7, 0x4D, 0x98, 0xC7, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4C, 0xFD, 0x98, 0x20, 0x95, 0xBB, 0x20, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0xF2, 0x73, 0x92, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0xEF, 0xFB, 0x30, 0xFA, 0x12, 0x1A, 0xB0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0x4C, 0x24, 0xB4, 0x5B, 0xC9, 0x4C, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xDD, 0x5E, 0x84, 0x95, 0x4D, 0x26, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0xFA, 0xF9, 0x3A, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0xA3, 0x2E, 0x7A, 0xDC, 0xA7, 0x53, 0xA9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x9F, 0x81, 0x84, 0xB2, 0x0D, 0xFE, 0x31 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x89, 0x1B, 0x77, 0x0C, 0x89, 0x71, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0x7F, 0xB2, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0xE9, 0x2C, 0x79, 0xA6, 0x3C, 0xAD, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xE0, 0x23, 0x02, 0x86, 0x0F, 0x77, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0x93, 0x6D, 0xE9, 0xF9, 0x3C, 0xBE, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xE7, 0x24, 0x92, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x3C, 0x5B, 0x4B, 0x1B, 0x25, 0x37, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xE8, 0x38, 0x1B, 0xA1, 0x5A, 0x2E, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0x19, 0xFD, 0xF4, 0x78, 0x01, 0x6B, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0x69, 0x37, 0x4F, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0xE2, 0xBF, 0xD3, 0xEC, 0x95, 0x9C, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x7B, 0xFC, 0xD5, 0xD3, 0x25, 0x5E, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x39, 0x55, 0x09, 0xA2, 0x58, 0x6A, 0xC9, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0xCC, 0x3B, 0xD9, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8F, 0x08, 0x65, 0x5E, 0xCB, 0xAB, 0x48, 0xC8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x79, 0x8B, 0xC0, 0x11, 0xC0, 0x69, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xE8, 0x8C, 0x4C, 0xC5, 0x28, 0xE4, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x1F, 0x34, 0x5C, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_ecp_point secp224k1_T[16] = {
+    ECP_POINT_INIT_XY_Z1(secp224k1_T_0_X, secp224k1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_1_X, secp224k1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_2_X, secp224k1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_3_X, secp224k1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_4_X, secp224k1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_5_X, secp224k1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_6_X, secp224k1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_7_X, secp224k1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_8_X, secp224k1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_9_X, secp224k1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_10_X, secp224k1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_11_X, secp224k1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_12_X, secp224k1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_13_X, secp224k1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_14_X, secp224k1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(secp224k1_T_15_X, secp224k1_T_15_Y),
+};
+#else
+#define secp224k1_T NULL
+#endif
+#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+static const mbedtls_mpi_uint secp256k1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp256k1_a[] = {
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp256k1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x07, 0x00 ),
+};
+static const mbedtls_mpi_uint secp256k1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
+};
+static const mbedtls_mpi_uint secp256k1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
+};
+static const mbedtls_mpi_uint secp256k1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint secp256k1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xEE, 0xD7, 0x1E, 0x67, 0x86, 0x32, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x73, 0xB1, 0xA9, 0xD5, 0xCC, 0x27, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x0E, 0x11, 0x01, 0x71, 0xFE, 0x92, 0x73 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0x28, 0x63, 0x6D, 0x72, 0x09, 0xA6, 0xC0 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0x69, 0xDC, 0x3E, 0x2C, 0x75, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0xB7, 0x3F, 0x30, 0x26, 0x3C, 0xDF, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xBE, 0xB9, 0x5D, 0x0E, 0xE8, 0x5E, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0xC3, 0x05, 0xD6, 0xB7, 0xD5, 0x24, 0xFC ),
+};
+static const mbedtls_mpi_uint secp256k1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0xCF, 0x7B, 0xDC, 0xCD, 0xC3, 0x39, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xDA, 0xB9, 0xE5, 0x64, 0xA7, 0x47, 0x91 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0x46, 0xA8, 0x61, 0xF6, 0x23, 0xEB, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xC1, 0xFF, 0xE4, 0x55, 0xD5, 0xC2, 0xBF ),
+};
+static const mbedtls_mpi_uint secp256k1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xBE, 0xB9, 0x59, 0x24, 0x13, 0x4A, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x45, 0x12, 0xDE, 0xBA, 0x4F, 0xEF, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0x08, 0xBF, 0xC1, 0x66, 0xAA, 0x0A, 0xBC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xFE, 0x30, 0x55, 0x31, 0x86, 0xA7, 0xB4 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0xBF, 0x18, 0x81, 0x67, 0x27, 0x42, 0xBD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x05, 0x83, 0xA4, 0xDD, 0x57, 0xD3, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x20, 0x63, 0xAB, 0xE4, 0x90, 0x70, 0xD0, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x5D, 0xFD, 0xA0, 0xEF, 0xCF, 0x1C, 0x54 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0x80, 0xE4, 0xF6, 0x09, 0xBC, 0x57, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x9F, 0x6E, 0x88, 0x54, 0x6E, 0x51, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x5F, 0x85, 0xFB, 0x84, 0x3E, 0x4A, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x19, 0xF5, 0x55, 0xC9, 0x07, 0xD8, 0xCE ),
+};
+static const mbedtls_mpi_uint secp256k1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0xB4, 0xC3, 0xD9, 0x5C, 0xA0, 0xD4, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0D, 0x30, 0xAF, 0x59, 0x9B, 0xF8, 0x04, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xA6, 0xFD, 0x66, 0x7B, 0xC3, 0x39, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE0, 0xBF, 0xF0, 0xC2, 0xE9, 0x71, 0xA4, 0x9E ),
+};
+static const mbedtls_mpi_uint secp256k1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x14, 0x2D, 0xB9, 0x88, 0x28, 0xF1, 0xBE, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x14, 0xF3, 0x1A, 0x0E, 0xB9, 0x01, 0x66, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0xA7, 0xA4, 0xF4, 0x05, 0xD0, 0xAA, 0x53 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x39, 0x1E, 0x47, 0xE5, 0x68, 0xC8, 0xC0 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xB9, 0xFC, 0xE0, 0x33, 0x8A, 0x7D, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0x93, 0xA5, 0x53, 0x55, 0x16, 0xB4, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0x5F, 0xEA, 0x9B, 0x29, 0x52, 0x71, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB2, 0xF0, 0x24, 0xB8, 0x7D, 0xB7, 0xA0, 0x9B ),
+};
+static const mbedtls_mpi_uint secp256k1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x00, 0x27, 0xB2, 0xDF, 0x73, 0xA2, 0xE0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x2E, 0x4D, 0x7C, 0xDE, 0x7A, 0x23, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x65, 0x60, 0xC7, 0x97, 0x1E, 0xA4, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0x13, 0x5B, 0x77, 0x59, 0xCB, 0x36, 0xE1 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0xBC, 0x9F, 0x9E, 0x2D, 0x53, 0x2A, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x5F, 0x64, 0x9F, 0x1A, 0x19, 0xE6, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9E, 0x7B, 0x39, 0xD2, 0xDB, 0x85, 0x84, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0xC7, 0x0D, 0x58, 0x6E, 0x3F, 0x52, 0x15 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x68, 0x19, 0x0B, 0x68, 0xC9, 0x1E, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD2, 0x4E, 0x21, 0x49, 0x3D, 0x55, 0xCC, 0x25 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xF9, 0x25, 0x45, 0x54, 0x45, 0xB1, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0xB3, 0xF7, 0xCD, 0x80, 0xA4, 0x04, 0x05 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x1E, 0x88, 0xC4, 0xAA, 0x18, 0x7E, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0xAC, 0xD9, 0xB2, 0xA1, 0xC0, 0x71, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0xA2, 0xF1, 0x15, 0xA6, 0x5F, 0x6C, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0x5B, 0x05, 0xBC, 0xB7, 0xC6, 0x4E, 0x72 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x80, 0xF8, 0x5C, 0x20, 0x2A, 0xE1, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x48, 0x2E, 0x68, 0x82, 0x7F, 0xEB, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA2, 0x3B, 0x25, 0xDB, 0x32, 0x4D, 0x88, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x6E, 0xA6, 0xB6, 0x6D, 0x62, 0x78, 0x22 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x4D, 0x3E, 0x86, 0x58, 0xC3, 0xEB, 0xBA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x89, 0x33, 0x18, 0x21, 0x1D, 0x9B, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0x9D, 0xFF, 0xC3, 0x79, 0xC1, 0x88, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0xD4, 0x48, 0x53, 0xE8, 0xAD, 0x21, 0x16 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x7B, 0xDE, 0xCB, 0xD8, 0x39, 0x17, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0xF3, 0x03, 0xF2, 0x5C, 0xBC, 0xC8, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0xAE, 0x4C, 0xB0, 0x16, 0xA4, 0x93, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x8B, 0x6B, 0xDC, 0xD7, 0x9A, 0x3E, 0x7E ),
+};
+static const mbedtls_mpi_uint secp256k1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x2D, 0x7A, 0xD2, 0x59, 0x05, 0xA2, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x56, 0x09, 0x32, 0xF1, 0xE8, 0xE3, 0x72 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0xCA, 0xE5, 0x2E, 0xF0, 0xFB, 0x18, 0x19 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x85, 0xA9, 0x23, 0x15, 0x31, 0x1F, 0x0E ),
+};
+static const mbedtls_mpi_uint secp256k1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0xE5, 0xB1, 0x86, 0xB9, 0x6E, 0x8D, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x77, 0xFC, 0xC9, 0xA3, 0x3F, 0x89, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x6A, 0xDC, 0x25, 0xB0, 0xC7, 0x41, 0x54 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0x11, 0x6B, 0xA6, 0x11, 0x62, 0xD4, 0x2D ),
+};
+static const mbedtls_mpi_uint secp256k1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x7D, 0x34, 0xB3, 0x20, 0x7F, 0x37, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBD, 0xD4, 0x45, 0xE8, 0xC2, 0xE9, 0xC5, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x32, 0x3B, 0x25, 0x7E, 0x79, 0xAF, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0xE4, 0x54, 0x71, 0xBE, 0x35, 0x4E, 0xD0 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x94, 0xDD, 0x8F, 0xB5, 0xC2, 0xDD, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x49, 0xE9, 0x1C, 0x2F, 0x08, 0x49, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0xB6, 0x03, 0x88, 0x6F, 0xB8, 0x15, 0x67 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xD3, 0x1C, 0xF3, 0xA5, 0xEB, 0x79, 0x01 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x25, 0xF9, 0x43, 0x88, 0x89, 0x0D, 0x06, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0x2D, 0xF5, 0x98, 0x32, 0xF6, 0xB1, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x73, 0x8F, 0x2B, 0x50, 0x27, 0x0A, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0xE3, 0xBD, 0x16, 0x05, 0xC8, 0x93, 0x12 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0x6A, 0xF7, 0xE3, 0x3D, 0xDE, 0x5F, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0xA3, 0x9C, 0x22, 0x3C, 0x33, 0x36, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x20, 0x24, 0x4C, 0x69, 0x45, 0x78, 0x14, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xF8, 0xD4, 0xBF, 0xB8, 0xC0, 0xA1, 0x25 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x88, 0xE1, 0x91, 0x03, 0xEB, 0xB3, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0x11, 0xA1, 0xEF, 0x14, 0x0D, 0xC4, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xD4, 0x0D, 0x1D, 0x96, 0x33, 0x5C, 0x19 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x45, 0x2A, 0x1A, 0xE6, 0x57, 0x04, 0x9B ),
+};
+static const mbedtls_mpi_uint secp256k1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0xB5, 0xA7, 0x80, 0xE9, 0x93, 0x97, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0xB9, 0x7C, 0xA0, 0xC9, 0x57, 0x26, 0x43 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9E, 0xEF, 0x56, 0xDA, 0x66, 0xF6, 0x1B, 0x9A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x89, 0x6B, 0x91, 0xE0, 0xA9, 0x65, 0x2B ),
+};
+static const mbedtls_mpi_uint secp256k1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0x98, 0x96, 0x9B, 0x06, 0x7D, 0x5E, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0xFA, 0xC1, 0x5F, 0x19, 0x37, 0x94, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCF, 0xBE, 0x6B, 0x1A, 0x05, 0xE4, 0xBF, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0xCD, 0x5D, 0x35, 0xB4, 0x51, 0xF7, 0x64 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0xEF, 0x96, 0xDB, 0xF2, 0x61, 0x63, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x04, 0x88, 0xC9, 0x9F, 0x1B, 0x94, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x30, 0x79, 0x7E, 0x24, 0xE7, 0x5F, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0xB8, 0x90, 0xB7, 0x94, 0x25, 0xBB, 0x0F ),
+};
+static const mbedtls_mpi_uint secp256k1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x79, 0xEA, 0xAD, 0xC0, 0x6D, 0x18, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0xA4, 0x58, 0x2A, 0x8D, 0x95, 0xB3, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0xC4, 0xC2, 0x12, 0x0D, 0x79, 0xE2, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0x6F, 0xBE, 0x97, 0x4D, 0xA4, 0x20, 0x07 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x31, 0x71, 0xC6, 0xA6, 0x91, 0xEB, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x9B, 0xA8, 0x4A, 0xE7, 0x77, 0xE1, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x06, 0xD3, 0x3D, 0x94, 0x30, 0xEF, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xDF, 0xCA, 0xFA, 0xF5, 0x28, 0xF8, 0xC9 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0xE1, 0x32, 0xFD, 0x3E, 0x81, 0xF8, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xF2, 0x4B, 0x1D, 0x19, 0xC9, 0x0F, 0xCC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xB1, 0x8A, 0x22, 0x8B, 0x05, 0x6B, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0x21, 0xEF, 0x30, 0xEC, 0x09, 0x2A, 0x89 ),
+};
+static const mbedtls_mpi_uint secp256k1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x84, 0x4A, 0x46, 0x07, 0x6C, 0x3C, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x18, 0x3A, 0xF4, 0xCC, 0xF5, 0xB2, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0x8F, 0xCD, 0x0A, 0x9C, 0xF4, 0xBD, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x89, 0x7F, 0x8A, 0xB1, 0x52, 0x3A, 0xAB ),
+};
+static const mbedtls_ecp_point secp256k1_T[16] = {
+    ECP_POINT_INIT_XY_Z1(secp256k1_T_0_X, secp256k1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_1_X, secp256k1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_2_X, secp256k1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_3_X, secp256k1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_4_X, secp256k1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_5_X, secp256k1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_6_X, secp256k1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_7_X, secp256k1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_8_X, secp256k1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_9_X, secp256k1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_10_X, secp256k1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_11_X, secp256k1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_12_X, secp256k1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_13_X, secp256k1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_14_X, secp256k1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(secp256k1_T_15_X, secp256k1_T_15_Y),
+};
+#else
+#define secp256k1_T NULL
+#endif
+#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
+
+/*
+ * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
+ */
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
+};
+
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint brainpoolP256r1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0xA2, 0xED, 0x52, 0xC9, 0x8C, 0xE3, 0xA5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0xC9, 0xC4, 0x87, 0x3F, 0x93, 0x7A, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0x12, 0x53, 0x61, 0x3E, 0x76, 0x08, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x8C, 0x74, 0xF4, 0x08, 0xC3, 0x76, 0x80 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0xDD, 0x09, 0xA6, 0xED, 0xEE, 0xC4, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xD9, 0xBE, 0x4B, 0xA5, 0xB7, 0x2B, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x20, 0x12, 0xCA, 0x0A, 0x38, 0x24, 0xAB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x72, 0x71, 0x90, 0x7A, 0x2E, 0xB7, 0x23 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x66, 0xA1, 0x93, 0x10, 0x2A, 0x51, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0x10, 0x11, 0x12, 0xBC, 0xB0, 0xB6, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0x58, 0xD7, 0x0A, 0x84, 0x05, 0xA3, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0x8E, 0x95, 0x61, 0xD3, 0x0B, 0xDF, 0x36 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF9, 0x92, 0x12, 0x0F, 0x5E, 0x87, 0x70, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0xE9, 0x9B, 0xEB, 0x3A, 0xFB, 0xCF, 0xC4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDC, 0x92, 0xB9, 0xF7, 0x45, 0xD3, 0x06, 0xB6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x82, 0x28, 0x65, 0xE1, 0xC5, 0x6C, 0x57, 0x18 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x0E, 0x77, 0x01, 0x81, 0x9E, 0x38, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0xF0, 0xD5, 0xA5, 0x91, 0x2B, 0xDF, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0xEE, 0xB6, 0x25, 0xD6, 0x98, 0xDE, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0xA1, 0x55, 0x63, 0x39, 0xEB, 0xB5, 0x47 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0xD6, 0xB8, 0xE3, 0x13, 0xED, 0x7F, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0xE8, 0xAE, 0x36, 0xB8, 0xCD, 0x19, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF9, 0x82, 0x83, 0x7A, 0x7B, 0x46, 0x56, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4E, 0x60, 0x46, 0x15, 0x5A, 0xAC, 0x99, 0x30 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x61, 0x50, 0xC6, 0xFF, 0x10, 0x7D, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x51, 0xDF, 0xA9, 0x7D, 0x78, 0x26, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0x15, 0x9A, 0xF7, 0x01, 0xC1, 0xBB, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x0F, 0xE6, 0x2A, 0xBD, 0x4A, 0x9E, 0x87 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0xF8, 0xD1, 0x77, 0xD2, 0x49, 0xB3, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0x86, 0xFB, 0x9E, 0x1F, 0x5A, 0x60, 0x47 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0xC4, 0x8D, 0xCD, 0x86, 0x61, 0x2F, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0xF6, 0xB9, 0xAC, 0x37, 0x9D, 0xE9, 0x28 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x77, 0xAA, 0x97, 0x9C, 0x0B, 0x04, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0xA6, 0x60, 0x81, 0xCE, 0x25, 0x13, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0x00, 0xF3, 0xBB, 0x82, 0x99, 0x95, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x5A, 0xCE, 0x90, 0x71, 0x38, 0x2F, 0x10 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x1A, 0xC0, 0x84, 0x27, 0xD6, 0x9D, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x37, 0x52, 0x16, 0x13, 0x0E, 0xCE, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xBF, 0x5A, 0xDB, 0xDB, 0x6E, 0x1E, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xB7, 0x5E, 0xF9, 0x86, 0xDD, 0x8A, 0x5C ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xAB, 0x5C, 0x8D, 0x1D, 0xF2, 0x2D, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0xC5, 0xF8, 0xF7, 0x1D, 0x96, 0x0B, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x4C, 0xA7, 0x45, 0x20, 0x6A, 0x1E, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x5D, 0xEF, 0xDE, 0xEE, 0x39, 0x44, 0x19 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x2F, 0x6D, 0x52, 0xC9, 0x58, 0x60, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0xC9, 0x62, 0xCB, 0x38, 0x3C, 0x55, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xA5, 0x09, 0x10, 0x88, 0xDB, 0xE3, 0xBD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xE0, 0x3C, 0xCE, 0x06, 0x0B, 0x4B, 0x5D ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0x1D, 0xB4, 0x10, 0x76, 0x8F, 0xBA, 0x09 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x70, 0x5A, 0x07, 0xF5, 0x1A, 0x74, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0xE9, 0x94, 0xA8, 0xC0, 0xD5, 0x4A, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0x6D, 0xD4, 0xE8, 0x9B, 0xE9, 0x6D, 0x0E ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x00, 0x32, 0x41, 0x57, 0x84, 0x89, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0xC7, 0x14, 0xEC, 0xE9, 0x27, 0xFF, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0x67, 0x9E, 0xFB, 0xB6, 0xB8, 0x96, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0x4A, 0xE3, 0x97, 0x4B, 0x58, 0xDE, 0x30 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0x1E, 0x5C, 0xF5, 0x7F, 0xD5, 0xD4, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x08, 0x7A, 0xF1, 0xBD, 0x89, 0xC7, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0xF9, 0x11, 0x1B, 0xF5, 0x3C, 0x6D, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x50, 0xE5, 0x69, 0x1D, 0x59, 0xFC, 0x0C ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x2F, 0xF8, 0x3F, 0xEC, 0x55, 0x99, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0xA7, 0x29, 0x90, 0x43, 0x81, 0x31, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0x18, 0x44, 0x50, 0x5D, 0x76, 0xCB, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0xC5, 0x5B, 0x9A, 0x03, 0xE6, 0x17, 0x39 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x89, 0xFC, 0x55, 0x94, 0x91, 0x6A, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x46, 0x35, 0xF2, 0x3A, 0x42, 0x08, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0xD2, 0x76, 0x49, 0x42, 0x87, 0xD3, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0xEA, 0xA0, 0x52, 0xF1, 0x6A, 0x30, 0x57 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0xB2, 0x57, 0xA3, 0x8A, 0x4D, 0x1B, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0xA3, 0x99, 0x94, 0xB5, 0x3D, 0x64, 0x09 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0xC3, 0xD7, 0x53, 0xF6, 0x49, 0x1C, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0x23, 0x41, 0x4D, 0xFB, 0x7A, 0x5C, 0x53 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0xB8, 0x15, 0x65, 0x5C, 0x85, 0x94, 0xD7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x37, 0xC7, 0xF8, 0x7E, 0xAE, 0x6C, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xD8, 0x11, 0x54, 0x98, 0x44, 0xE3, 0xF1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0x4D, 0xA6, 0x4B, 0x28, 0xF2, 0x57, 0x9E ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xD0, 0xEB, 0x1E, 0xAA, 0x30, 0xD3, 0x6A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0x9B, 0x4D, 0xA7, 0x73, 0x6E, 0xB6, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x47, 0xF6, 0xED, 0x37, 0xEF, 0x71, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0xB5, 0x49, 0x61, 0x5E, 0x45, 0xF6, 0x4A ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x0E, 0xB3, 0x84, 0x3A, 0x63, 0x72, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x53, 0x5C, 0xA7, 0xC6, 0x2E, 0xAB, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0x0F, 0x8F, 0x87, 0x50, 0x28, 0xB4, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0x98, 0x4A, 0x98, 0x31, 0x86, 0xCA, 0x51 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0xC9, 0xE2, 0xFD, 0x5D, 0x1F, 0xE8, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x90, 0x91, 0xC4, 0x84, 0xF0, 0xBA, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x5A, 0xB3, 0x4E, 0xFB, 0xE0, 0x57, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x0B, 0x90, 0xA6, 0xFD, 0x9D, 0x8E, 0x02 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0x41, 0x8F, 0x31, 0xFA, 0x5A, 0xF6, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xE9, 0xE3, 0xF6, 0xE0, 0x4A, 0xE7, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x4E, 0xCD, 0xA2, 0x22, 0x14, 0xD4, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0xED, 0x21, 0xB7, 0x0F, 0x53, 0x10, 0x17 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0x06, 0x24, 0x2C, 0x4E, 0xD1, 0x1E, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD7, 0x3F, 0xC1, 0x9F, 0xAB, 0xF0, 0x37, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x03, 0x5E, 0x12, 0xCE, 0x83, 0x1B, 0x2A, 0x18 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x65, 0xCF, 0xE8, 0x5C, 0xA5, 0xA2, 0x70 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0x86, 0x76, 0x3A, 0x94, 0xF6, 0x1D, 0xC1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0xDA, 0xC9, 0xA6, 0x29, 0x93, 0x15, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x61, 0x6A, 0x7D, 0xC7, 0xA9, 0xF3, 0x76 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4A, 0x03, 0x71, 0xA2, 0x15, 0xCE, 0x50, 0x72 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0xD0, 0xA8, 0x1E, 0x91, 0xC4, 0x4F, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0x4B, 0x7E, 0xD7, 0x71, 0x58, 0x7E, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x45, 0xAF, 0x2A, 0x18, 0x93, 0x95, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0x8F, 0xC7, 0xFA, 0x4C, 0x7A, 0x86, 0x54 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0xAF, 0x68, 0x3A, 0x23, 0xC1, 0x2E, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0x50, 0x11, 0x67, 0x39, 0xB9, 0xAF, 0x48 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x86, 0xAA, 0x1E, 0x88, 0x21, 0x29, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0x28, 0xA4, 0x9D, 0x89, 0xA9, 0x9A, 0x10 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0xBA, 0x04, 0x67, 0xB7, 0x01, 0x40, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0xE9, 0x09, 0xA3, 0xCA, 0xA6, 0x37, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x97, 0xA8, 0xB6, 0x3C, 0xEE, 0x90, 0x3D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDC, 0xED, 0xC4, 0xF7, 0xC3, 0x95, 0xEC, 0x85 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x84, 0xBD, 0xEB, 0xD5, 0x64, 0xBB, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x9B, 0xE2, 0x28, 0x50, 0xC2, 0x72, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x39, 0xF2, 0x74, 0xD1, 0x26, 0xBF, 0x32, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xCB, 0xAF, 0x72, 0xDB, 0x6D, 0x30, 0x98 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x50, 0x85, 0xF4, 0x2B, 0x48, 0xC1, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0x28, 0xBB, 0x11, 0xBA, 0x5B, 0x22, 0x6C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0xA1, 0xE5, 0x5C, 0xC9, 0x1D, 0x44, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0xE8, 0xE6, 0x6F, 0xBB, 0xC1, 0x81, 0x7F ),
+};
+static const mbedtls_ecp_point brainpoolP256r1_T[16] = {
+    ECP_POINT_INIT_XY_Z1(brainpoolP256r1_T_0_X, brainpoolP256r1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_1_X, brainpoolP256r1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_2_X, brainpoolP256r1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_3_X, brainpoolP256r1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_4_X, brainpoolP256r1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_5_X, brainpoolP256r1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_6_X, brainpoolP256r1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_7_X, brainpoolP256r1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_8_X, brainpoolP256r1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_9_X, brainpoolP256r1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_10_X, brainpoolP256r1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_11_X, brainpoolP256r1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_12_X, brainpoolP256r1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_13_X, brainpoolP256r1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_14_X, brainpoolP256r1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_15_X, brainpoolP256r1_T_15_Y),
+};
+#else
+#define brainpoolP256r1_T NULL
+#endif
+
+#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
+
+/*
+ * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
+ */
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
+};
+
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint brainpoolP384r1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0xD8, 0x8A, 0x54, 0x41, 0xD6, 0x6B, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0x3B, 0xF1, 0x22, 0xFD, 0x2D, 0x4B, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x55, 0xE3, 0x33, 0xF0, 0x73, 0x52, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x3F, 0x30, 0x26, 0xCA, 0x7F, 0x52, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD3, 0x6E, 0x17, 0x9B, 0xD5, 0x2A, 0x4A, 0x31 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0xDA, 0x6B, 0xE5, 0x03, 0x07, 0x1D, 0x2E ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x7A, 0xAF, 0x98, 0xE3, 0xA4, 0xF6, 0x19 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x7D, 0xFE, 0x51, 0x40, 0x3B, 0x47, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x88, 0xEC, 0xC4, 0xE2, 0x8F, 0xCB, 0xA4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0xE2, 0x88, 0x2D, 0x4E, 0x50, 0xEB, 0x9A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0x54, 0x94, 0x5E, 0xF4, 0x7F, 0x3A, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0x07, 0x1C, 0xE1, 0xBD, 0x0F, 0xF8, 0x63 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x92, 0x28, 0x2E, 0x32, 0x04, 0xB1, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x25, 0x82, 0x44, 0x43, 0x76, 0x0D, 0x55, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0xE3, 0xFF, 0x89, 0x46, 0xDE, 0x4E, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0x22, 0xBB, 0x67, 0x1A, 0x81, 0xEE, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0x54, 0xE2, 0x7A, 0xAE, 0xDA, 0x2C, 0xD0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x9A, 0x90, 0xAA, 0x6E, 0x8B, 0xCC, 0x5F ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x40, 0xAC, 0xED, 0x7D, 0x37, 0x87, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0xF8, 0xB1, 0x80, 0x4C, 0x8C, 0x04, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x98, 0x2C, 0xAD, 0x30, 0x69, 0x35, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0x2E, 0x00, 0x2F, 0x44, 0x8C, 0xF0, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x58, 0x07, 0xD7, 0xCD, 0x60, 0xA1, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xFB, 0x7B, 0x03, 0x05, 0x5E, 0x79, 0x73 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0x17, 0xCE, 0x38, 0x4B, 0x5E, 0x5B, 0xC8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x60, 0x0E, 0x0A, 0x61, 0x9D, 0x7C, 0x62, 0x08 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x25, 0xF0, 0x98, 0x71, 0x7F, 0x17, 0x26, 0xD7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0xD3, 0xFA, 0x3C, 0xF0, 0x70, 0x07, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x47, 0x5C, 0x09, 0x43, 0xB7, 0x65, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xA9, 0xA7, 0x3E, 0xFA, 0xF3, 0xEC, 0x22 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x78, 0x22, 0x2B, 0x58, 0x71, 0xFA, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x30, 0xCE, 0x6A, 0xB3, 0xB0, 0x4F, 0x83 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCF, 0x95, 0x20, 0xA9, 0x23, 0xC2, 0x65, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0xCF, 0x03, 0x5B, 0x8A, 0x80, 0x44, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xF8, 0x91, 0xF7, 0xD5, 0xED, 0xEA, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x5B, 0x16, 0x10, 0x25, 0xAC, 0x2A, 0x17 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0xEC, 0xDC, 0xC4, 0x7B, 0x8C, 0x6B, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0xBB, 0x1C, 0xD3, 0x5A, 0xEE, 0xD9, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x5D, 0x30, 0x5E, 0xF7, 0xB2, 0x41, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0xCE, 0x0F, 0x1A, 0xC6, 0x41, 0x64, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x18, 0xE1, 0xE3, 0x82, 0x15, 0x66, 0x4B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0xE2, 0x24, 0x04, 0x72, 0x39, 0xA0, 0x7C ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0x51, 0xA2, 0x58, 0x88, 0x62, 0xE1, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0xD2, 0x65, 0x14, 0xE9, 0x4C, 0x82, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDC, 0xE1, 0xAC, 0x87, 0xAE, 0x31, 0x1A, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0x4F, 0x96, 0x1E, 0x85, 0x7A, 0xC3, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0x86, 0xBB, 0xF0, 0xC0, 0x9D, 0x08, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBD, 0x53, 0x03, 0x09, 0x80, 0x91, 0xEF, 0x68 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0xD7, 0xAF, 0x6F, 0x69, 0x7B, 0x88, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0x13, 0xE4, 0x30, 0xA2, 0x47, 0xB5, 0xC1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xD2, 0xC0, 0xDD, 0x8A, 0x1C, 0x3C, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF9, 0x8C, 0xB3, 0x4C, 0xBA, 0x8B, 0x6D, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0xC7, 0xA1, 0xA8, 0x6E, 0x3C, 0x4F, 0xF1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x4A, 0x97, 0xC8, 0x03, 0x6F, 0x01, 0x82 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x18, 0x12, 0xA9, 0x39, 0xD5, 0x22, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0xA7, 0xC0, 0xBD, 0x9D, 0x8D, 0x78, 0x38 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0xB3, 0xD0, 0x7F, 0xDF, 0xD0, 0x30, 0xDE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x25, 0x73, 0x96, 0xEC, 0xA8, 0x1D, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0xD1, 0x65, 0x66, 0xDC, 0xD9, 0xCF, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0xED, 0x7B, 0x37, 0xAD, 0xE2, 0xBE, 0x2D ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x79, 0x42, 0x6A, 0x07, 0x66, 0xB1, 0xBD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x45, 0x53, 0x62, 0x65, 0x92, 0x09, 0x4C, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0xAF, 0xC3, 0x03, 0xF6, 0xF4, 0x2D, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0xCA, 0x41, 0xD9, 0xA2, 0x69, 0x9B, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0xB2, 0xA6, 0x8D, 0xE1, 0xAA, 0x61, 0x76 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0xBA, 0x4D, 0x12, 0xB6, 0xBE, 0xF3, 0x7E ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0xD9, 0x92, 0x22, 0x07, 0xCE, 0xC9, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0xA1, 0x7C, 0x91, 0xDB, 0x32, 0xF7, 0xE5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x49, 0x4B, 0x6D, 0xFB, 0xD9, 0x70, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0xFB, 0x4E, 0x4C, 0x5E, 0x66, 0x81, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0xB3, 0xE1, 0x00, 0xB7, 0xD9, 0xCC, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x36, 0x8B, 0xC4, 0x39, 0x20, 0xFD, 0x30 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x1F, 0x60, 0x03, 0xBB, 0xD7, 0x60, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x3C, 0x62, 0xDD, 0x71, 0x95, 0xE9, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x5B, 0x7A, 0x5F, 0x68, 0x81, 0xC5, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xB5, 0xB9, 0x98, 0x42, 0x28, 0xA5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x29, 0x8E, 0x11, 0x49, 0xB4, 0xD7, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x3E, 0xD2, 0x30, 0xA1, 0xBA, 0xCA, 0x03 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x37, 0x64, 0x44, 0x2F, 0x03, 0xE5, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4A, 0x42, 0xBC, 0xFF, 0xA2, 0x1A, 0x5F, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0x04, 0xAB, 0x04, 0xE0, 0x24, 0xAD, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x45, 0x17, 0x67, 0x1F, 0x3E, 0x53, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0x0F, 0xB3, 0x1B, 0x57, 0x54, 0xC2, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xD3, 0xF8, 0xC4, 0x1B, 0x9B, 0xFA, 0x30 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x90, 0xFD, 0xFB, 0xCA, 0x49, 0x38, 0x4E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0xCF, 0xC6, 0xDD, 0xF0, 0xFF, 0x8C, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD7, 0x69, 0x9D, 0xBD, 0x5F, 0x33, 0xE9, 0xB4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x19, 0x82, 0x3D, 0xAC, 0x1C, 0x40, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xC7, 0x02, 0x46, 0x14, 0x77, 0x00, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x05, 0xF2, 0x77, 0x3A, 0x66, 0x5C, 0x39 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xE6, 0x17, 0xDE, 0xB2, 0xA1, 0xE5, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0x71, 0xEC, 0x9D, 0xD8, 0xF5, 0xD4, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0xC6, 0x42, 0x5E, 0xE7, 0x18, 0xBA, 0xD0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x21, 0x68, 0x5A, 0x26, 0xFB, 0xD7, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x00, 0x5C, 0xBA, 0x8A, 0x34, 0xEC, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0x9C, 0x3C, 0xAF, 0x53, 0xE8, 0x65, 0x35 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0xEF, 0x28, 0xDC, 0x67, 0x05, 0xC8, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0x78, 0xC3, 0x85, 0x49, 0xA0, 0xBC, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x3E, 0x2D, 0xA0, 0xCF, 0xD4, 0x7A, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0x93, 0xFE, 0x60, 0xB3, 0x6E, 0x99, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0xAD, 0x04, 0xE7, 0x49, 0xAF, 0x5E, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x7A, 0xED, 0xA6, 0x9E, 0x18, 0x09, 0x31 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x05, 0x94, 0x44, 0xDC, 0xB8, 0x85, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x14, 0xB7, 0x37, 0xC2, 0x50, 0x75, 0x15, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xC6, 0x0F, 0xB2, 0xA9, 0x91, 0x3E, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x81, 0xAD, 0x25, 0xA1, 0x26, 0x73, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xF1, 0xD1, 0x61, 0x7C, 0x76, 0x8F, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0xDB, 0x4A, 0xFF, 0x14, 0xA7, 0x48, 0x0B ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0x73, 0xC6, 0xC2, 0xCC, 0xF1, 0x57, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0xED, 0x73, 0x27, 0x70, 0x82, 0xB6, 0x5E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0xBA, 0xAC, 0x3A, 0xCF, 0xF4, 0xEA, 0xA6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0xD6, 0xB1, 0x8F, 0x0E, 0x08, 0x2C, 0x5E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xE3, 0x8F, 0x2F, 0x0E, 0xA1, 0xF3, 0x07 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0xF5, 0x7C, 0x9B, 0x29, 0x0A, 0xF6, 0x28 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBD, 0xEE, 0x17, 0x47, 0x34, 0x15, 0xA3, 0xAF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0xBE, 0x88, 0x48, 0xE7, 0xA2, 0xBB, 0xDE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0xAD, 0xDC, 0x65, 0x61, 0x37, 0x0F, 0xC1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x67, 0xAD, 0xA2, 0x3A, 0x1C, 0x91, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0x07, 0x0C, 0x3A, 0x41, 0x6E, 0x13, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0xBD, 0x7E, 0xED, 0xAA, 0x14, 0xDD, 0x61 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC3, 0xDC, 0x20, 0x01, 0x72, 0x11, 0x48, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xC4, 0x7B, 0xF8, 0x62, 0x3D, 0xF0, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0xC2, 0x3D, 0x2E, 0x52, 0xA3, 0x4A, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xE2, 0x53, 0x46, 0x5E, 0x21, 0xF8, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0xC7, 0x8F, 0xA9, 0x26, 0x42, 0x32, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0xA6, 0xA0, 0x8D, 0x4B, 0x9A, 0x19, 0x03 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0xAB, 0x6D, 0x1E, 0xFB, 0xEE, 0x60, 0x0C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x56, 0x3C, 0xC5, 0x5D, 0x10, 0x79, 0x1C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x25, 0xBC, 0x41, 0x9F, 0x71, 0xEF, 0x02, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA2, 0x36, 0xC4, 0xD0, 0x88, 0x9B, 0x32, 0xFC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0xD4, 0x5D, 0x17, 0x39, 0xE6, 0x22, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x26, 0x01, 0xCE, 0xBE, 0x4A, 0x9C, 0x27 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x6D, 0x11, 0xCA, 0x6C, 0x5A, 0x93, 0x0C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0x96, 0x26, 0xAF, 0x2F, 0xE4, 0x30, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0xC1, 0x4C, 0xC6, 0x30, 0x1F, 0x5C, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xB3, 0xE8, 0xFC, 0x35, 0xEB, 0x63, 0x6C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0x1D, 0xCA, 0xFC, 0x50, 0x36, 0x4B, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0x0E, 0x23, 0x5B, 0xAF, 0xEB, 0x2D, 0x31 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0x88, 0xB6, 0xD7, 0x74, 0x4A, 0x23, 0xB6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x66, 0xE2, 0xBB, 0x29, 0xA6, 0x4F, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0x6F, 0x7E, 0x68, 0x6E, 0xA0, 0x14, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0x73, 0xD4, 0xE8, 0xAB, 0x5B, 0xF6, 0x0D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0xE0, 0x3C, 0x24, 0x00, 0x95, 0xE9, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x0D, 0x4F, 0x81, 0xD0, 0xF2, 0x3F, 0x00 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0x1D, 0xCD, 0x78, 0x39, 0xC4, 0x6B, 0xD9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0x45, 0xC7, 0xB8, 0x2F, 0xAA, 0x5D, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0x8C, 0x6E, 0xA3, 0x24, 0xB2, 0xDB, 0x4B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x2D, 0xD9, 0xF1, 0xC7, 0x9B, 0x8A, 0xAF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0xE1, 0x2C, 0xB9, 0x40, 0x37, 0x91, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0x2C, 0xB5, 0x23, 0x03, 0x2B, 0xAF, 0x2F ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0x9D, 0x5A, 0x20, 0x10, 0xA9, 0x84, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x30, 0x89, 0x20, 0x13, 0xE9, 0xB2, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x6E, 0x52, 0xEB, 0x03, 0x18, 0x1F, 0xA6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x9E, 0x1C, 0x35, 0x87, 0x92, 0x69, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0xC9, 0x88, 0xAF, 0xC6, 0x6C, 0x83, 0x72 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0xD5, 0x7A, 0x54, 0x34, 0x99, 0xB6, 0x6F ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0xAD, 0x45, 0x9B, 0x4B, 0x41, 0x4D, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0x5D, 0xAB, 0x7F, 0x35, 0x34, 0xE9, 0x29 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0xBE, 0x78, 0x34, 0x44, 0xF3, 0x4A, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0xDE, 0xE3, 0xC4, 0xEE, 0x0B, 0xF9, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x86, 0x16, 0x48, 0x32, 0xB8, 0x74, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0xEE, 0x7C, 0xBA, 0xBD, 0x81, 0xE3, 0x55 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0x6A, 0xFA, 0x84, 0xDA, 0xB8, 0xD5, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB2, 0x9F, 0x8A, 0xD5, 0x1B, 0x2E, 0x1A, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x0C, 0x61, 0xE2, 0xFF, 0x5B, 0xE6, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0x62, 0xC1, 0x87, 0x53, 0x1B, 0x92, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x90, 0x00, 0xD1, 0x6A, 0x0C, 0x0E, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0x2E, 0xB5, 0x3B, 0x44, 0xB5, 0xA0, 0x78 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0x5D, 0x02, 0x58, 0xB5, 0xBE, 0x45, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0xEF, 0x8E, 0x90, 0x4D, 0x2A, 0x32, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x48, 0x99, 0x75, 0x5C, 0x0A, 0x33, 0x8F, 0x36 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0x6C, 0x95, 0xD4, 0x1F, 0xF3, 0xEB, 0xDA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0xE4, 0x4C, 0x91, 0x20, 0xF3, 0x25, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x95, 0xEB, 0x29, 0x6F, 0x20, 0x34, 0x81 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0x15, 0xE5, 0x13, 0x7E, 0x64, 0x8B, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0xBC, 0x0D, 0x18, 0x7E, 0x37, 0x9E, 0xFA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x82, 0x20, 0xF7, 0x2D, 0x7A, 0x77, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x29, 0xA2, 0xDB, 0x7A, 0xE6, 0x6F, 0xA5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xC6, 0x50, 0x5C, 0xBC, 0xE6, 0x4F, 0xBD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0x9F, 0xD5, 0xE8, 0xC5, 0x3D, 0xB7, 0x30 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_16_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x45, 0x03, 0x55, 0x10, 0xDB, 0xA6, 0x8B, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4E, 0x17, 0xAE, 0x78, 0xC9, 0x1D, 0x43, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4E, 0x35, 0x49, 0xD4, 0x47, 0x84, 0x8D, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x95, 0x2F, 0xEA, 0xBC, 0xB4, 0x18, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x48, 0xAE, 0x89, 0xF5, 0x65, 0x3D, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0xF2, 0x2B, 0x20, 0xD1, 0x75, 0x50, 0x63 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_16_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0xE6, 0x5C, 0x2C, 0xE0, 0x7D, 0xDF, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0x07, 0x3E, 0xCE, 0x9F, 0x18, 0xB6, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0xF8, 0xF0, 0xD5, 0xFA, 0x42, 0x1D, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x6C, 0x1D, 0x03, 0xC9, 0x0E, 0x2B, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0x18, 0x52, 0xA5, 0xB4, 0x63, 0xE1, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0xD9, 0xC4, 0xFD, 0x16, 0x60, 0x54 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_17_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0x7D, 0xDE, 0xDF, 0x4B, 0x4A, 0xB0, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x4E, 0x8C, 0x94, 0xC1, 0xE2, 0x85, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4F, 0xF0, 0xEA, 0xB5, 0x9B, 0x70, 0xEF, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0xC2, 0x39, 0x5D, 0xF3, 0x2C, 0xD9, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0D, 0x1C, 0x2E, 0xCC, 0x2F, 0x54, 0x87, 0x80 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB0, 0x72, 0xC7, 0xB5, 0x50, 0xA3, 0x84, 0x77 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_17_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xD1, 0xAF, 0xA9, 0xB4, 0x8B, 0x5D, 0xFA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0xF6, 0x52, 0x8A, 0xC3, 0x56, 0xA5, 0x5E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0x52, 0xFF, 0xEA, 0x05, 0x42, 0x77, 0x83 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x08, 0x90, 0x72, 0x86, 0xC4, 0xC3, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0x15, 0xF8, 0xF1, 0x16, 0x67, 0xC6, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0x87, 0xAC, 0x8F, 0x71, 0xEC, 0x83, 0x81 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_18_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0xE1, 0xE6, 0x2D, 0x0E, 0x11, 0xA1, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xE2, 0xA8, 0x32, 0xE6, 0xE3, 0x83, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x56, 0xE5, 0xCD, 0xB7, 0x2B, 0x67, 0x6F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0xED, 0xC9, 0x65, 0x6D, 0x87, 0xE1, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x8E, 0xFD, 0x9A, 0x53, 0x0E, 0xFA, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0x4C, 0x4A, 0xE2, 0x23, 0x84, 0xFA, 0x01 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_18_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xFE, 0x49, 0x81, 0xD1, 0x3E, 0xF4, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x45, 0x72, 0xE0, 0xEF, 0x0D, 0xB8, 0x3E, 0x6F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0x00, 0x0F, 0x5F, 0xCE, 0x60, 0x72, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xCC, 0xD8, 0x03, 0x07, 0x6E, 0x5A, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0x3A, 0x35, 0x50, 0x4E, 0x1F, 0xCA, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0xEA, 0x88, 0x55, 0xBD, 0x6E, 0x05, 0x7F ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_19_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0x6D, 0xF1, 0x97, 0xA6, 0x69, 0x39, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0x41, 0x99, 0xFF, 0x3B, 0xA1, 0x26, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0x2F, 0x95, 0x80, 0x12, 0x4A, 0x1B, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0xBF, 0x51, 0xAA, 0xAE, 0x2D, 0xDA, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x1C, 0xB3, 0x52, 0x36, 0x49, 0xD4, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0xC1, 0x1F, 0x3A, 0xD3, 0x3E, 0x5C, 0x1A ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_19_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x51, 0xF7, 0x2B, 0xC8, 0xA9, 0xA7, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x4E, 0x7F, 0x98, 0x41, 0x66, 0xB0, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0x1D, 0xC0, 0x42, 0xCD, 0xF8, 0xC3, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0x41, 0x91, 0x7D, 0xCC, 0x8B, 0xCC, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0xAE, 0x76, 0xED, 0x56, 0x18, 0xC5, 0xAB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0x6A, 0x06, 0xA3, 0x7F, 0x65, 0x10, 0x1F ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_20_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0xEC, 0x3C, 0x05, 0x05, 0xCA, 0xF6, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x48, 0xCD, 0x02, 0x51, 0x12, 0x16, 0x3C, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0xEB, 0xB3, 0x43, 0x7B, 0xDD, 0xB2, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x59, 0x90, 0x41, 0xDB, 0xE4, 0xF5, 0x91 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x0E, 0x18, 0x2A, 0x5A, 0x83, 0x7C, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x37, 0xA1, 0x0D, 0xF1, 0x2F, 0x63, 0x79 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_20_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xC0, 0xFA, 0x6F, 0x1F, 0x67, 0xCF, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x34, 0x45, 0xBB, 0xF4, 0xF9, 0x9B, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x69, 0xFE, 0x67, 0x1D, 0x64, 0x8F, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x39, 0xBF, 0xD8, 0xB3, 0xC7, 0xAD, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0x93, 0xFF, 0xF3, 0x28, 0xFA, 0x39, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xF9, 0xC3, 0x85, 0x26, 0x7A, 0x88, 0x89 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_21_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xD5, 0x79, 0xD8, 0x11, 0xDE, 0xEB, 0x4E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x46, 0xA4, 0x6A, 0xDA, 0x74, 0x34, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xBD, 0xD3, 0xF5, 0x14, 0xEE, 0xFE, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x4C, 0xA3, 0x71, 0x43, 0x65, 0xF8, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x6C, 0x35, 0xFA, 0x90, 0x25, 0xD8, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x34, 0x84, 0x96, 0xA1, 0x43, 0x03, 0x4D ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_21_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x3B, 0x3B, 0x2F, 0xCA, 0x59, 0xF2, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0x48, 0x24, 0x74, 0xD8, 0x72, 0x90, 0xA3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x42, 0x74, 0x8C, 0x6F, 0x52, 0x19, 0x3D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x9E, 0x41, 0x63, 0x68, 0x78, 0x4C, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0x94, 0xB6, 0x6B, 0x38, 0x52, 0xA8, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0x30, 0x25, 0x93, 0xA1, 0x6F, 0x6E, 0x68 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_22_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x2F, 0x4B, 0x64, 0x79, 0x50, 0xFF, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0x36, 0xED, 0x57, 0x39, 0x3B, 0xE7, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x85, 0xEA, 0x35, 0xD6, 0xC0, 0xA0, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x89, 0x3A, 0xCC, 0x22, 0x1C, 0x46, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x7A, 0xB0, 0xA1, 0x1B, 0x69, 0x62, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0xB8, 0x8A, 0x6C, 0x18, 0x85, 0x0D, 0x88 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_22_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xB6, 0x50, 0xE9, 0x4E, 0x7F, 0xE8, 0x07 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x5B, 0x5C, 0xD1, 0x4B, 0x11, 0x9A, 0xD8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0x25, 0x56, 0x74, 0x51, 0x9C, 0xEC, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0x7F, 0xB6, 0x8A, 0xCB, 0x3A, 0x10, 0x6A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x60, 0x33, 0x07, 0x01, 0xE9, 0x49, 0x59, 0xE6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0xA5, 0x2E, 0xF2, 0xBA, 0x32, 0x63, 0x44 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_23_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0x06, 0x0B, 0xA5, 0x44, 0x27, 0x7F, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x74, 0xAC, 0x0F, 0xCC, 0x4F, 0x13, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xB1, 0xBF, 0x97, 0x49, 0xA5, 0x1C, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0x64, 0x68, 0x7B, 0x0F, 0xCC, 0x77, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x39, 0xF9, 0x4E, 0x84, 0x9C, 0xF6, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xCF, 0x6D, 0xE2, 0xA1, 0x2D, 0xF9, 0x2B ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_23_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0xC4, 0x90, 0x57, 0x31, 0x01, 0x05, 0x5E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0x1E, 0xBB, 0xBF, 0x98, 0xA4, 0x7C, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0xE3, 0xA0, 0xB2, 0xCD, 0x39, 0x9A, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x34, 0x60, 0x7A, 0x89, 0x98, 0xB5, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0x20, 0x3D, 0x3A, 0x04, 0x8F, 0x5A, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0x26, 0xB6, 0x49, 0x09, 0x9C, 0x0F, 0x59 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_24_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x66, 0xD2, 0x38, 0x2A, 0x62, 0x81, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0xC8, 0x20, 0x5E, 0x28, 0xA3, 0x81, 0xA7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x20, 0x31, 0xA4, 0xF1, 0xEA, 0x7D, 0x87, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8F, 0x2C, 0x99, 0x09, 0x6F, 0x63, 0xEB, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x76, 0xDA, 0x1A, 0x06, 0xBE, 0xDE, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x09, 0x2E, 0x75, 0x39, 0x30, 0x2D, 0x42 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_24_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x9B, 0xC1, 0x5A, 0x17, 0xC3, 0x8C, 0x31 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x58, 0x8D, 0x94, 0x4D, 0x3D, 0xAB, 0x60, 0xD4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFD, 0x1E, 0x0F, 0x43, 0xAE, 0x9D, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0xF2, 0xF3, 0x20, 0x1B, 0xAA, 0xB7, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x5B, 0xA4, 0xF4, 0x90, 0x3B, 0xE3, 0x71 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0x78, 0x72, 0xBD, 0x65, 0x09, 0x0B, 0x01 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_25_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x37, 0x2A, 0x6C, 0x16, 0x4F, 0x64, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0xCE, 0xA3, 0x90, 0xB4, 0x9A, 0xBC, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0x38, 0x55, 0x63, 0x1D, 0x3A, 0x6E, 0x18 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xB4, 0xAA, 0x99, 0x22, 0x45, 0x89, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x7C, 0x8C, 0xA6, 0x3D, 0xA7, 0x3E, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x06, 0x42, 0xDC, 0xA6, 0xE3, 0xC6, 0x12 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_25_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0x8C, 0x3D, 0x5D, 0x47, 0x31, 0x7C, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0x85, 0xEE, 0x46, 0x7E, 0x13, 0x04, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9E, 0x3C, 0x8B, 0x43, 0x2E, 0x74, 0xF5, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x88, 0x8E, 0x07, 0x29, 0x08, 0x03, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0x9B, 0x89, 0xEB, 0x08, 0xE8, 0x43, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0x07, 0x67, 0xFD, 0xD9, 0x73, 0x6F, 0x18 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_26_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xEB, 0x21, 0x8D, 0x98, 0x43, 0x74, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x88, 0xCC, 0x14, 0xD8, 0x08, 0xBB, 0xA6, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC4, 0x98, 0xF2, 0x6A, 0x18, 0xC3, 0xDD, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0x38, 0x91, 0xA0, 0x03, 0xF2, 0x04, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xAF, 0xE8, 0xFD, 0xFB, 0x13, 0x70, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x93, 0x87, 0x98, 0x4A, 0xE0, 0x00, 0x12 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_26_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x2E, 0x69, 0x9C, 0xA2, 0x2D, 0x03, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0xFE, 0xF3, 0xB9, 0xC1, 0x85, 0x2A, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xFD, 0x86, 0xB1, 0xCD, 0xBF, 0x41, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xD8, 0x9A, 0x21, 0xF3, 0xFE, 0xCB, 0xF1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0x78, 0x04, 0x60, 0xB7, 0xA9, 0xA2, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x1E, 0x66, 0x2A, 0x54, 0x51, 0xBD, 0x8B ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_27_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x16, 0x36, 0xEF, 0x61, 0x2D, 0xEE, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x45, 0x5F, 0x88, 0xA0, 0x13, 0x12, 0xF7, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0xC6, 0xAD, 0x4A, 0x4A, 0x07, 0x01, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0x74, 0xB1, 0x4F, 0xEB, 0xBD, 0xD5, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0xF9, 0x71, 0xA2, 0x06, 0x4F, 0xD7, 0xBC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x8B, 0x4D, 0x48, 0xE0, 0x98, 0xFB, 0x6A ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_27_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC4, 0xBA, 0x10, 0xA3, 0x0D, 0x52, 0xAC, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0xD0, 0xE0, 0x36, 0xE6, 0x07, 0x3A, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x80, 0xF0, 0xAA, 0x49, 0x22, 0x4B, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xC7, 0xAB, 0x1C, 0x89, 0xCD, 0x24, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x82, 0x2A, 0xFC, 0xB3, 0x6D, 0x45, 0x96, 0x49 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0xE4, 0xDB, 0x52, 0x3F, 0xC4, 0xB4, 0x19 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_28_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5B, 0xCC, 0xC8, 0x7F, 0xBB, 0x6B, 0x87, 0x47 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0x21, 0x3C, 0x69, 0x7D, 0x38, 0x57, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0x4C, 0x18, 0x3C, 0x53, 0xA5, 0x48, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xC3, 0x64, 0x45, 0xDB, 0xC4, 0x6D, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0xCC, 0xD1, 0xBB, 0x17, 0xB8, 0x34, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x69, 0x71, 0xFA, 0xA0, 0x28, 0x4A, 0x3D ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_28_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0xE8, 0x9E, 0x39, 0xEA, 0x8D, 0x38, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0x9C, 0xBB, 0xCD, 0x80, 0x1A, 0xEE, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA0, 0x45, 0xBF, 0xD9, 0x22, 0x11, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x7C, 0x5C, 0xD9, 0xC0, 0x9F, 0x69, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x8A, 0xA6, 0x79, 0x4E, 0x35, 0xB9, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCC, 0x8B, 0x9A, 0x3E, 0xA1, 0xB8, 0x28, 0x10 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_29_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0x2F, 0xEF, 0xBB, 0xA9, 0x72, 0x7F, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0x34, 0xB7, 0x12, 0xB9, 0xE7, 0xC3, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0x1D, 0xD9, 0x42, 0x77, 0x0C, 0x71, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x01, 0x59, 0xA7, 0x56, 0x03, 0x91, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x91, 0x99, 0x33, 0x30, 0x3E, 0xEF, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0xC9, 0x5A, 0x9A, 0x54, 0x66, 0xF1, 0x70 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_29_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x2C, 0xB7, 0x6E, 0x71, 0x7D, 0x35, 0x30 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x0D, 0xEF, 0xD1, 0x2D, 0x99, 0x63, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0x31, 0xAF, 0x2D, 0xC9, 0xC6, 0xC2, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0xC0, 0xDF, 0x80, 0x54, 0xC4, 0xAC, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x6B, 0xA0, 0x84, 0x96, 0xF7, 0x31, 0xC8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0xE2, 0x7C, 0x7A, 0x41, 0x45, 0x75, 0x6A ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_30_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xEE, 0x58, 0x31, 0xE8, 0x68, 0xD6, 0x76 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD2, 0x2E, 0x48, 0xB7, 0x09, 0x9F, 0xD4, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xA9, 0x5C, 0xE7, 0x64, 0x43, 0x5D, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9E, 0x58, 0x9F, 0x50, 0xAB, 0x68, 0xFF, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x88, 0x2D, 0xBA, 0x12, 0xBF, 0x8D, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0xDF, 0x6F, 0xB3, 0x75, 0xA4, 0x55, 0x73 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_30_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x17, 0x92, 0x39, 0xB7, 0x13, 0x37, 0x6F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x43, 0x71, 0xA7, 0xCA, 0x17, 0x1B, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xB9, 0xB0, 0x78, 0xEF, 0xA0, 0xDA, 0x83 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0x84, 0xF2, 0x0F, 0x85, 0xA2, 0xB6, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x65, 0x2E, 0x6E, 0x45, 0xB9, 0x4C, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0x6A, 0x8C, 0x2B, 0x77, 0x96, 0x36, 0x22 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_31_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x7A, 0x13, 0x4A, 0x97, 0x63, 0x02, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x1E, 0x06, 0x03, 0x8F, 0xB9, 0xEE, 0x64 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0xEE, 0x8B, 0x89, 0xA9, 0x70, 0xDB, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x7B, 0x81, 0xC9, 0x70, 0x8D, 0x62, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0xDA, 0x46, 0xF8, 0xF9, 0x3A, 0xBE, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9F, 0x9C, 0x7A, 0x97, 0x62, 0xEB, 0xFA, 0x0F ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_T_31_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB2, 0x03, 0x3D, 0x3C, 0x46, 0x27, 0x9E, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x08, 0x1C, 0xD5, 0x25, 0xAF, 0xE9, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0x69, 0xDC, 0x59, 0xF4, 0x8A, 0x7C, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x9A, 0x7A, 0x99, 0x21, 0x0C, 0x4E, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xCE, 0x85, 0x5F, 0xAC, 0xAA, 0x82, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x83, 0x57, 0x69, 0x90, 0x76, 0xF3, 0x53, 0x3F ),
+};
+static const mbedtls_ecp_point brainpoolP384r1_T[32] = {
+    ECP_POINT_INIT_XY_Z1(brainpoolP384r1_T_0_X, brainpoolP384r1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_1_X, brainpoolP384r1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_2_X, brainpoolP384r1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_3_X, brainpoolP384r1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_4_X, brainpoolP384r1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_5_X, brainpoolP384r1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_6_X, brainpoolP384r1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_7_X, brainpoolP384r1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_8_X, brainpoolP384r1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_9_X, brainpoolP384r1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_10_X, brainpoolP384r1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_11_X, brainpoolP384r1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_12_X, brainpoolP384r1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_13_X, brainpoolP384r1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_14_X, brainpoolP384r1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_15_X, brainpoolP384r1_T_15_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_16_X, brainpoolP384r1_T_16_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_17_X, brainpoolP384r1_T_17_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_18_X, brainpoolP384r1_T_18_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_19_X, brainpoolP384r1_T_19_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_20_X, brainpoolP384r1_T_20_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_21_X, brainpoolP384r1_T_21_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_22_X, brainpoolP384r1_T_22_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_23_X, brainpoolP384r1_T_23_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_24_X, brainpoolP384r1_T_24_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_25_X, brainpoolP384r1_T_25_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_26_X, brainpoolP384r1_T_26_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_27_X, brainpoolP384r1_T_27_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_28_X, brainpoolP384r1_T_28_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_29_X, brainpoolP384r1_T_29_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_30_X, brainpoolP384r1_T_30_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_31_X, brainpoolP384r1_T_31_Y),
+};
+#else
+#define brainpoolP384r1_T NULL
+#endif
+
+#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
+
+/*
+ * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
+ */
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
+};
+
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+static const mbedtls_mpi_uint brainpoolP512r1_T_0_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_0_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_1_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0xE9, 0x6B, 0x8C, 0x6F, 0x9D, 0x88, 0x43 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x4F, 0x86, 0x96, 0xA7, 0x56, 0xD1, 0x37 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xAB, 0xFA, 0xEE, 0xA7, 0xF5, 0x0E, 0xA6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x40, 0xEF, 0x9E, 0x6D, 0xD6, 0x32, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0xED, 0x56, 0x14, 0x57, 0x1A, 0x8D, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xED, 0x4D, 0x3A, 0xFA, 0x71, 0x75, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xC5, 0x76, 0x1C, 0x14, 0xBE, 0xB5, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x5A, 0xCB, 0xE7, 0x36, 0x1D, 0x52, 0x1C ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_1_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x8D, 0x7A, 0xEB, 0xA3, 0x8B, 0xD5, 0xB0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0xA3, 0x41, 0xF8, 0xAC, 0x9E, 0xAB, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0xE3, 0x65, 0x0D, 0x1C, 0xFE, 0x09, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0xCA, 0x13, 0x3F, 0xC5, 0xF9, 0x7E, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x5D, 0x63, 0x28, 0xA6, 0x89, 0xD3, 0x91 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x95, 0x3F, 0x7A, 0x82, 0xD4, 0x77, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xBB, 0x92, 0x32, 0x00, 0xF4, 0x66, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x58, 0x31, 0xD1, 0x17, 0x9F, 0x2A, 0x22 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_2_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0x36, 0xA9, 0xCD, 0x80, 0xA5, 0x2D, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x91, 0x44, 0xAB, 0xCE, 0x71, 0xFF, 0x0C, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0x24, 0x58, 0x35, 0x5A, 0x21, 0x32, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1B, 0xA6, 0x28, 0xF8, 0x7A, 0x97, 0xAE, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0xE7, 0x08, 0xFA, 0x47, 0xC9, 0x55, 0x09 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xAC, 0x2E, 0x84, 0xA4, 0xF5, 0x52, 0xC4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x58, 0x05, 0x9D, 0xA7, 0xC8, 0x71, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x92, 0xB4, 0x92, 0xC1, 0x92, 0xEC, 0x6B ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_2_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4A, 0x48, 0x2D, 0x79, 0x5E, 0x58, 0xE5, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x85, 0x26, 0xEC, 0xE9, 0x6E, 0xD4, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x68, 0x26, 0x87, 0x38, 0xA2, 0xD2, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0x17, 0x60, 0xCE, 0x75, 0xF8, 0xA5, 0x6F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x20, 0x51, 0xDB, 0xA9, 0xAE, 0x87, 0xF1, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x49, 0x92, 0x3B, 0x19, 0x96, 0xF5, 0xB0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC4, 0xD5, 0x52, 0x52, 0x8C, 0xCE, 0xFD, 0xFA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0x18, 0x0A, 0xE6, 0xF6, 0xAE, 0x08, 0x41 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_3_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x2B, 0xD8, 0x54, 0xCE, 0xB0, 0x57, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0xB0, 0xF8, 0x9E, 0x03, 0x03, 0x3C, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x0E, 0x29, 0x29, 0x00, 0xF3, 0x70, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x33, 0x99, 0x0E, 0x00, 0x5D, 0xFE, 0x4B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0x2D, 0xF2, 0x59, 0x32, 0xCF, 0x03, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0xC9, 0x72, 0xAE, 0x0C, 0xEF, 0xD1, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x5A, 0x27, 0xBF, 0x2F, 0x45, 0xF9, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD4, 0xBE, 0xE5, 0x2C, 0xFF, 0x5B, 0x1E, 0x88 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_3_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0xAC, 0xBB, 0xD8, 0x83, 0xC2, 0x46, 0xF6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCF, 0xDC, 0xCE, 0x15, 0xB4, 0xEF, 0xCF, 0x46 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0xDB, 0x5E, 0x94, 0x31, 0x0B, 0xB2, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0xB9, 0xE3, 0xE3, 0x11, 0x71, 0x41, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xE3, 0x01, 0xB7, 0x7D, 0xBC, 0x65, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x07, 0x65, 0x87, 0xA7, 0xE8, 0x48, 0xE3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0x48, 0x8F, 0xD4, 0x30, 0x8E, 0xB4, 0x6C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0xE0, 0x73, 0xBE, 0x1E, 0xBF, 0x56, 0x36 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_4_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0x0E, 0x5E, 0x87, 0xC5, 0xAB, 0x0E, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xF9, 0x5F, 0x80, 0x24, 0x4C, 0x2A, 0xF1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0x15, 0x21, 0x54, 0x92, 0x84, 0x8D, 0x6A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x8A, 0x47, 0x74, 0xDC, 0x42, 0xB1, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0xF7, 0x30, 0xFD, 0xC1, 0x9B, 0x0C, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4E, 0x6C, 0xCC, 0xDF, 0xC5, 0xE3, 0xA9, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x67, 0x59, 0x10, 0x5C, 0x51, 0x54, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x37, 0xFB, 0x6E, 0xB0, 0x78, 0x63, 0x8E ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_4_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0xEF, 0xC4, 0x39, 0x20, 0xF1, 0x46, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0x62, 0xAE, 0xFF, 0x10, 0xE4, 0xE2, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x5C, 0xF5, 0x2E, 0x22, 0x89, 0xE5, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0x0C, 0x29, 0xA8, 0x62, 0xAE, 0xDB, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD7, 0x9E, 0x0F, 0xCA, 0x87, 0x2A, 0x6F, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xDC, 0x9B, 0x9F, 0x65, 0xD4, 0xAD, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0xC3, 0x08, 0x0F, 0xCF, 0x67, 0xE9, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x5C, 0xD7, 0xFF, 0x41, 0x9C, 0xCB, 0x26 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_5_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x25, 0x05, 0x12, 0xAD, 0x73, 0x63, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0x99, 0x07, 0x86, 0x57, 0xE7, 0x94, 0xB1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x4B, 0xA5, 0xBF, 0x18, 0xA9, 0xEF, 0x6A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0x4C, 0xC4, 0x09, 0xF2, 0x2F, 0x0C, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0x3A, 0x04, 0xEA, 0x89, 0x6C, 0x91, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0x3A, 0xE7, 0xA3, 0xEC, 0x24, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0xA1, 0x26, 0x21, 0x04, 0xE3, 0xB9, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0x71, 0x4B, 0x7B, 0xC2, 0x89, 0xCD, 0xA2 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_5_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0xB9, 0xA8, 0x9D, 0xFD, 0x00, 0x3A, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0x41, 0x6C, 0xBB, 0x5A, 0xCA, 0x1F, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0xD7, 0xE2, 0x6C, 0x6B, 0xA7, 0x48, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0x19, 0xAD, 0xA7, 0xC1, 0x7E, 0x4F, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0xF7, 0x19, 0x3C, 0x06, 0x74, 0x2C, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x23, 0x4F, 0x0C, 0x09, 0xB0, 0x80, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4E, 0x74, 0x34, 0x08, 0x44, 0x7E, 0xA3, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0xCC, 0x8D, 0x12, 0x6E, 0xE1, 0x3D, 0x0B ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_6_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x18, 0xB1, 0x71, 0x02, 0x93, 0xC2, 0xA4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x89, 0x40, 0xE2, 0x1F, 0xE7, 0x5E, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x8E, 0xAE, 0x89, 0x01, 0xD4, 0x0C, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xDA, 0x58, 0x70, 0x24, 0xF2, 0xE4, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0xC7, 0x1D, 0xD6, 0x4A, 0x6F, 0x66, 0x4F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x1D, 0x7E, 0x4A, 0x2C, 0xCA, 0xEC, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x06, 0x7F, 0xA8, 0x99, 0xE4, 0xD3, 0x4E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0x1D, 0x5A, 0xDF, 0x5E, 0x58, 0x36, 0x49 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_6_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0xB9, 0x32, 0x69, 0x1F, 0x72, 0x2A, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0x73, 0xE2, 0x03, 0x39, 0x35, 0xAA, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0x5E, 0x5D, 0x48, 0xEF, 0xAE, 0x30, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x7F, 0x60, 0x19, 0xAF, 0xEC, 0x9D, 0xFC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0xD9, 0x19, 0xE4, 0x1B, 0x56, 0x15, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xD7, 0x33, 0x59, 0x1F, 0x43, 0x59, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0xCE, 0xEE, 0xCA, 0xA4, 0x7F, 0x63, 0xD4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBD, 0x40, 0xC0, 0xF6, 0x19, 0x89, 0x43, 0x20 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_7_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0x92, 0xEA, 0x07, 0x65, 0x79, 0x86, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xB7, 0x13, 0x75, 0xD3, 0xC5, 0x0A, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x9E, 0xFA, 0xE1, 0x1F, 0x0C, 0xF9, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x8C, 0xED, 0x5C, 0x21, 0xE9, 0x09, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0x4D, 0xD8, 0x18, 0xC4, 0xF6, 0x36, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0xC9, 0xAC, 0x5C, 0xFA, 0x69, 0xA4, 0xA0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x8C, 0x94, 0x1C, 0x7B, 0x71, 0x36, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0xBD, 0x46, 0xCE, 0xB7, 0x1D, 0x9C, 0x5E ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_7_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0xD6, 0x96, 0x4B, 0xA6, 0x47, 0xEB, 0xE5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0xF1, 0x5F, 0x15, 0xDE, 0x99, 0x6F, 0x66 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xBD, 0xE5, 0x04, 0xB8, 0xE6, 0xC0, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0xD3, 0xF0, 0x04, 0x00, 0xE4, 0x05, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xF3, 0x06, 0xA3, 0x1A, 0xFF, 0xEA, 0x73 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x32, 0xAA, 0x99, 0x33, 0x09, 0xB6, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6E, 0xEF, 0xFC, 0x61, 0x10, 0x42, 0x31, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xF1, 0xF4, 0x33, 0xCF, 0x28, 0x90, 0x9C ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_8_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xDE, 0xF9, 0x88, 0x87, 0x7B, 0xEB, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xB8, 0xDA, 0xFA, 0xDA, 0x3D, 0xA6, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xF0, 0x62, 0x82, 0x53, 0x32, 0x55, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xA5, 0x32, 0x4A, 0x19, 0x11, 0x9C, 0x10 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0xB3, 0x27, 0xE9, 0x75, 0x90, 0x05, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0x1C, 0x90, 0x48, 0x77, 0x01, 0x85, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0xD6, 0x9B, 0x84, 0xA8, 0xD7, 0xC5, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x7A, 0xCB, 0xB3, 0x11, 0x46, 0xD7, 0x99 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_8_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0x23, 0xBF, 0x75, 0x75, 0xA1, 0x95, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x66, 0x5D, 0x34, 0x13, 0xA9, 0x03, 0xBE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x80, 0x9D, 0x5F, 0xD2, 0x44, 0xE1, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0x5D, 0xBD, 0xA8, 0xBF, 0xB4, 0x25, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0x99, 0x1F, 0x53, 0xF1, 0x57, 0xDB, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x7C, 0xE5, 0xC5, 0x51, 0x0B, 0x4C, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0xB0, 0x1A, 0x9C, 0x16, 0xB0, 0x32, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0xE3, 0xCF, 0xDD, 0x48, 0xB4, 0x7B, 0x33 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_9_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xDD, 0x9E, 0x3C, 0x98, 0x0E, 0x77, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0xAB, 0x01, 0xD3, 0x87, 0x74, 0x25, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0xA3, 0xE3, 0x76, 0x43, 0x87, 0x12, 0xBD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0xB1, 0x3B, 0x60, 0x66, 0xEB, 0x98, 0x54 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD2, 0x78, 0xC8, 0xD7, 0x4E, 0x75, 0xCA, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xDF, 0x71, 0x19, 0xE7, 0x07, 0x36, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xC9, 0xA8, 0x5F, 0x91, 0xBF, 0x47, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0x96, 0x58, 0x96, 0x18, 0xB6, 0xFA, 0x01 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_9_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x2D, 0xA9, 0x9B, 0x86, 0xDB, 0x0C, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0x0B, 0x2D, 0x56, 0x4A, 0xD3, 0x93, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0x15, 0xE2, 0x65, 0x12, 0x86, 0x0E, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x41, 0x4D, 0xC1, 0xCB, 0xE4, 0xC3, 0xD7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0x53, 0x10, 0xCA, 0xA3, 0xAC, 0x83, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0x01, 0x22, 0x96, 0x10, 0xAD, 0x69, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x46, 0x4E, 0xD8, 0xEA, 0xD6, 0x9D, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0x2F, 0x7F, 0x62, 0x62, 0x80, 0xD0, 0x14 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_10_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB2, 0xDA, 0x00, 0x63, 0x09, 0xBD, 0x6A, 0x83 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xD4, 0x6E, 0x48, 0x05, 0xB7, 0xF7, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x14, 0x4D, 0xD7, 0x00, 0x4A, 0x15, 0x27, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0x15, 0xAA, 0x37, 0x27, 0x34, 0x18, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0x20, 0x2C, 0x84, 0x1B, 0x88, 0xBA, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x09, 0xD6, 0x04, 0xA2, 0x60, 0x84, 0x72 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0x04, 0x94, 0x08, 0xD4, 0xED, 0x47, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xF3, 0xE4, 0x3E, 0xB9, 0x5B, 0x35, 0x42 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_10_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0xD8, 0xB6, 0x80, 0xD6, 0xF1, 0x30, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x14, 0xA6, 0x85, 0xEE, 0xA7, 0xD8, 0x61 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0x49, 0x2A, 0x1E, 0x7C, 0xE9, 0x2D, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3A, 0x87, 0x56, 0x91, 0x03, 0x77, 0x4D, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0x52, 0xD4, 0xAA, 0xF7, 0xFA, 0xB0, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x5D, 0x11, 0x39, 0xB1, 0xE7, 0x76, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x13, 0xBC, 0x37, 0x5D, 0x74, 0xCD, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x48, 0x14, 0x23, 0x30, 0xF8, 0x46, 0x37 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_11_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x27, 0xB0, 0xD9, 0xB2, 0x74, 0xB4, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEA, 0xA6, 0xB9, 0x6F, 0x9F, 0x64, 0x36, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2E, 0x2B, 0x78, 0x40, 0x05, 0x2B, 0x7B, 0xA9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x68, 0x3A, 0xB6, 0x4A, 0xE2, 0xDB, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0x33, 0xD7, 0x34, 0x8B, 0x25, 0x45, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0xCE, 0xA8, 0xC9, 0x01, 0xFB, 0x0E, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0xF9, 0x51, 0x4C, 0x12, 0x9F, 0x60, 0xE4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x85, 0xBD, 0x30, 0x37, 0x84, 0x39, 0x44 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_11_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x33, 0xAF, 0x2E, 0xB8, 0x2E, 0xCC, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xB1, 0x73, 0x59, 0x4E, 0x0C, 0x09, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0x24, 0x89, 0x81, 0x12, 0xFF, 0xBB, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x37, 0x1A, 0x66, 0xEE, 0xED, 0xB6, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0xBD, 0x04, 0x20, 0x5D, 0xFB, 0xBF, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xF8, 0x34, 0xA3, 0xFF, 0x45, 0xDE, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x18, 0x73, 0xF1, 0x32, 0x25, 0x58, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0xC1, 0x14, 0xE3, 0x9E, 0x40, 0x0F, 0x12 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_12_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x07, 0x9D, 0x9C, 0x00, 0xF7, 0x56, 0x19 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0xBA, 0x87, 0xF9, 0x15, 0x0C, 0x66, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0x1F, 0xC1, 0x28, 0xB0, 0x47, 0x0D, 0xF5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xCA, 0x27, 0xEE, 0x4B, 0x23, 0x2B, 0x89 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7E, 0xB5, 0x68, 0xC8, 0x17, 0x5D, 0xC3, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0x02, 0x08, 0xEE, 0x20, 0x9D, 0xEA, 0x64 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x14, 0x50, 0xD4, 0x7D, 0x5F, 0xCF, 0xA0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xFA, 0xF8, 0xA7, 0xC6, 0xDC, 0x14, 0x8C ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_12_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x76, 0xBD, 0x0A, 0x1A, 0x18, 0x98, 0xDC, 0xB0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x63, 0x63, 0x02, 0xB7, 0xD5, 0x5B, 0x5A, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0xB1, 0xD7, 0x4B, 0x15, 0x39, 0x61, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0x32, 0xE1, 0x9E, 0x70, 0x1B, 0xCE, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0xD8, 0x18, 0x83, 0x52, 0x9B, 0x6D, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x55, 0x56, 0x19, 0x34, 0xA4, 0xEA, 0xFC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0xA9, 0x55, 0x80, 0xE3, 0x15, 0x36, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0x06, 0xC8, 0x1D, 0x17, 0x0D, 0xAD, 0x16 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_13_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x20, 0xD6, 0xF0, 0xCC, 0xF3, 0x63, 0x53, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0x5A, 0xDC, 0x46, 0xBD, 0x0D, 0xAD, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x2F, 0x11, 0x60, 0x15, 0x51, 0x4A, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0xE3, 0x93, 0x38, 0xD5, 0x83, 0xAA, 0x0D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x90, 0xA6, 0xCC, 0xB1, 0xFD, 0xBB, 0x1A, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0x54, 0xC8, 0x54, 0x6F, 0x79, 0x1A, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x4A, 0xDA, 0x28, 0x92, 0x97, 0x9D, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0x4B, 0xDB, 0xC7, 0x52, 0xC5, 0x66, 0x34 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_13_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0x7E, 0x92, 0x53, 0x30, 0x93, 0xFD, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x16, 0x6A, 0xB1, 0x91, 0x0A, 0xB4, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0x9D, 0x40, 0x3F, 0xE3, 0xF1, 0x01, 0x46 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0x0E, 0xD8, 0xED, 0x11, 0x8E, 0x4C, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x4A, 0x1B, 0x88, 0xDF, 0x8D, 0x29, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x23, 0x21, 0x11, 0xAB, 0x77, 0x81, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0B, 0xAF, 0x11, 0xFA, 0xBA, 0x40, 0x63, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0x6F, 0x8D, 0x80, 0xDF, 0x67, 0xF5, 0x44 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_14_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB2, 0x8B, 0xB7, 0x08, 0xF4, 0xD7, 0x2D, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0x2B, 0x30, 0x02, 0x45, 0x71, 0x08, 0x49 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x3A, 0xCA, 0x50, 0xF6, 0xC2, 0x19, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xB9, 0x9B, 0x3E, 0x73, 0x95, 0x1D, 0x49 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x60, 0x59, 0x48, 0xCB, 0xD8, 0xD6, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0xB9, 0x6C, 0x89, 0xAB, 0x99, 0xA8, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0xA1, 0x8B, 0x4E, 0x06, 0x19, 0xEC, 0x99 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x95, 0x04, 0xCF, 0xD5, 0x94, 0xB3, 0x02 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_14_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0x35, 0x93, 0x7C, 0xB3, 0xB8, 0x9E, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC4, 0x45, 0x5C, 0x7E, 0xBF, 0x75, 0x81, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDC, 0xE8, 0x24, 0xDF, 0xEC, 0x2F, 0x7D, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x8B, 0xD5, 0x6A, 0x9B, 0xA0, 0xE0, 0x4F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0xE3, 0x27, 0x82, 0xDE, 0xDD, 0xCA, 0x4B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x57, 0x56, 0x46, 0x05, 0x06, 0x01, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0x35, 0xA7, 0x47, 0xE2, 0x6B, 0x2C, 0x4F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x9D, 0x4C, 0xEC, 0x1F, 0x11, 0x75, 0x2B ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_15_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xAA, 0x41, 0xC1, 0xE9, 0x0E, 0xE9, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0xCF, 0x9C, 0x4B, 0xE8, 0xED, 0x0A, 0x49 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x73, 0xCA, 0x0C, 0x46, 0x0A, 0x9C, 0xE4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0xE1, 0x9E, 0xBC, 0xFE, 0x44, 0x63, 0x6D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x43, 0x71, 0xEE, 0xF8, 0xC1, 0x8C, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6A, 0x4B, 0xF0, 0x69, 0x25, 0xBD, 0x71, 0x1A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x9A, 0xFE, 0x82, 0xE7, 0xC1, 0xC1, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFC, 0x5A, 0x6E, 0x5E, 0x97, 0x6A, 0x35, 0x8D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_15_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA2, 0x18, 0x6C, 0x7E, 0xB8, 0x9E, 0x57, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x35, 0xB9, 0xC1, 0xD0, 0xFE, 0x78, 0xFB, 0x32 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x08, 0xAE, 0x46, 0x34, 0xEA, 0x7A, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x1C, 0x56, 0xA9, 0x18, 0x37, 0xD4, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x63, 0xE9, 0x0A, 0xB6, 0x38, 0x3C, 0xC1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0x4F, 0xA4, 0x6E, 0x85, 0x31, 0x23, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0D, 0xAD, 0xC4, 0xC3, 0xB1, 0x4B, 0x1C, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x56, 0x4A, 0x38, 0xB3, 0x6B, 0x6F, 0x2C ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_16_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0xC7, 0x19, 0xDE, 0x21, 0xED, 0x89, 0xD0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xBE, 0xA6, 0xAE, 0xEB, 0x9D, 0xA7, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x0E, 0x13, 0x1E, 0x86, 0x57, 0xC3, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x4B, 0x30, 0x46, 0x52, 0xC1, 0xEC, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6E, 0xD5, 0x44, 0x31, 0x96, 0x3B, 0x26, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x68, 0xA8, 0x67, 0x78, 0x39, 0xE8, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x78, 0xB7, 0xDD, 0xF2, 0x58, 0xB6, 0x3D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x81, 0x3C, 0xB3, 0x26, 0xC4, 0x2C, 0x8C, 0xA5 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_16_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x24, 0xE5, 0x73, 0xEE, 0x9A, 0x02, 0xA9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x6A, 0x65, 0x60, 0xF3, 0x62, 0xE3, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFB, 0x07, 0x84, 0xE6, 0x3B, 0x46, 0x65, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x8F, 0x0C, 0xB0, 0xE1, 0x04, 0x82, 0x9D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0x13, 0xBF, 0x3D, 0xA0, 0x48, 0xA2, 0x74 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0x26, 0x76, 0x74, 0xAB, 0x0B, 0x29, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x30, 0x6E, 0x5F, 0x03, 0x34, 0x7C, 0x38, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0x72, 0xF9, 0x3B, 0x3C, 0xA4, 0xBC, 0x7C ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_17_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xCE, 0x18, 0x80, 0xB8, 0x24, 0x45, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x09, 0x03, 0xB8, 0x06, 0x64, 0xF7, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x26, 0xB1, 0x10, 0x6D, 0x71, 0x12, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x12, 0xC6, 0x6E, 0x1E, 0x6A, 0xC3, 0x80 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE5, 0xD3, 0x0A, 0xDE, 0xD8, 0x6B, 0x04, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0x87, 0x5B, 0xAE, 0xDB, 0x3C, 0xC0, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0xF5, 0xF9, 0xC1, 0x9A, 0x89, 0xBB, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xED, 0x69, 0x72, 0x8B, 0xAE, 0x32, 0x13, 0x11 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_17_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF9, 0x16, 0x07, 0x50, 0xFA, 0x4C, 0xCF, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0x50, 0x21, 0xE9, 0xDE, 0xEC, 0x7E, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x2F, 0xE8, 0x83, 0x30, 0x0B, 0x65, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x0B, 0x99, 0xAC, 0xC9, 0xBA, 0x6C, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x59, 0x5A, 0x0D, 0x7B, 0x9E, 0x08, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x91, 0xB2, 0xDC, 0x90, 0xCE, 0x67, 0xED ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x93, 0x60, 0x0C, 0xD7, 0x1F, 0x2F, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x7F, 0x9D, 0x40, 0xF8, 0x78, 0x7A, 0x54 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_18_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x13, 0x22, 0x95, 0xE8, 0xEF, 0x31, 0x57, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0x88, 0x53, 0xFE, 0xAF, 0x7C, 0x47, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xCE, 0xCC, 0x79, 0xE8, 0x9F, 0x8C, 0xC4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDB, 0x16, 0xDD, 0x77, 0x6E, 0x8A, 0x73, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0x07, 0x97, 0x21, 0x3B, 0xF8, 0x5F, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC6, 0xB5, 0xD2, 0x81, 0x84, 0xF0, 0xE7, 0x9F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x8F, 0x75, 0x09, 0x6A, 0x0E, 0x53, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x4F, 0x70, 0x97, 0xC7, 0xAC, 0x7D, 0x3F ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_18_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF9, 0x3C, 0x6A, 0xB4, 0x10, 0xA9, 0xC8, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0xC5, 0xD6, 0x69, 0x16, 0xB8, 0xAC, 0x25 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x44, 0xDC, 0xEB, 0x48, 0x54, 0x5D, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x48, 0x9B, 0xD7, 0x72, 0x69, 0xA4, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x0D, 0x36, 0x9A, 0x66, 0x0B, 0xEC, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0xC6, 0xD4, 0xB6, 0x60, 0xE5, 0xC3, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x29, 0x42, 0xE0, 0x9D, 0xFD, 0x7C, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0x10, 0xBA, 0x55, 0xBC, 0x3B, 0x38, 0x5D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_19_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x25, 0x66, 0xFA, 0x05, 0x73, 0x03, 0x1B, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0xA4, 0x66, 0x12, 0x96, 0x7B, 0x02, 0x4C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0xB5, 0xDE, 0x6D, 0x98, 0xD1, 0xD5, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE2, 0xF5, 0x44, 0xB8, 0x8E, 0xF6, 0x8C, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x15, 0x2B, 0x72, 0xBC, 0x49, 0xE5, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x44, 0xD7, 0xDF, 0x8F, 0xEB, 0x8D, 0x80 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0x64, 0x88, 0xAA, 0xB7, 0xE4, 0x70, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9C, 0x14, 0xBB, 0xE9, 0x9B, 0xB9, 0x65, 0x5D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_19_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0x8E, 0x88, 0xF5, 0xF1, 0xC1, 0x89, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x30, 0x53, 0xE6, 0xFB, 0x2D, 0x82, 0xB4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0xE4, 0xFF, 0xBA, 0x31, 0x79, 0xAB, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x45, 0x09, 0xF7, 0xB7, 0x09, 0x78, 0x4C, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xAE, 0xC2, 0x44, 0xDC, 0x17, 0x78, 0x47 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0xD4, 0x17, 0x43, 0x19, 0x74, 0x9E, 0x23 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x64, 0x3B, 0x73, 0xA2, 0x99, 0x27, 0x76 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0x74, 0x36, 0x5F, 0xD3, 0x14, 0xB1, 0x31 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_20_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0x07, 0xAB, 0xFD, 0x9B, 0x03, 0xC5, 0xD5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0xBE, 0xB0, 0x1D, 0xF2, 0x0C, 0x73, 0x73 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0xE7, 0x7B, 0x87, 0xD3, 0x34, 0xFD, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9A, 0x25, 0x3D, 0xC7, 0x36, 0x83, 0x53, 0xDC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x7C, 0xCF, 0x63, 0x55, 0x12, 0x11, 0xB0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0x34, 0x4D, 0x27, 0x92, 0xAC, 0x18, 0x16 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x42, 0x61, 0x9D, 0x2E, 0xFF, 0x13, 0x16 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF4, 0xDE, 0x92, 0x65, 0x57, 0x0D, 0xBC, 0x0A ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_20_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x7B, 0x6E, 0xC6, 0x2A, 0x21, 0x74, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xA7, 0x53, 0x4D, 0x29, 0x36, 0xEF, 0xE5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0xD6, 0x41, 0xC7, 0x99, 0xAD, 0x50, 0x53 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x99, 0xAC, 0x41, 0x9F, 0xFB, 0x4C, 0x86, 0xF1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xBB, 0xE6, 0x25, 0x28, 0xAA, 0xEB, 0x1E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x04, 0xA2, 0xC3, 0xAA, 0x08, 0x8A, 0xCC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x2B, 0x5B, 0xE2, 0x8D, 0x76, 0xEA, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x33, 0xD2, 0x21, 0x4D, 0x62, 0xE3, 0x8E ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_21_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x06, 0x8B, 0x2B, 0xC2, 0xC4, 0xB1, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xF5, 0xA1, 0xC0, 0x03, 0x6A, 0x29, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0xA9, 0xEF, 0x55, 0xB6, 0x1A, 0x9F, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x54, 0x32, 0xBE, 0x06, 0x43, 0xB5, 0xFD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xD6, 0xD9, 0x20, 0x89, 0xBE, 0xD4, 0x1B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x26, 0x95, 0x10, 0xCE, 0xB4, 0x88, 0x79 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xA6, 0x27, 0xAC, 0x32, 0xBA, 0xBD, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0xA6, 0xAE, 0x9C, 0x7B, 0xBE, 0xA1, 0x63 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_21_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xCD, 0x4D, 0x3D, 0xDF, 0x96, 0xBB, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0xA7, 0x11, 0x06, 0xCC, 0x0E, 0x31, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x20, 0xE4, 0xF4, 0xAD, 0x7B, 0x5F, 0xF1, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0x54, 0xBE, 0xF4, 0x8A, 0x03, 0x47, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x53, 0x00, 0x7F, 0xB0, 0x8A, 0x68, 0xA6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x16, 0xB1, 0x73, 0x6F, 0x5B, 0x0E, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0x32, 0xE3, 0x43, 0x64, 0x75, 0xFB, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x18, 0x55, 0x8A, 0x4E, 0x6E, 0x35, 0x54 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_22_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x80, 0x97, 0x15, 0x1E, 0xCB, 0xF2, 0x9C, 0xA5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0xD1, 0xBB, 0xF3, 0x70, 0xAD, 0x13, 0xAD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0x96, 0xA4, 0xC5, 0x5E, 0xDA, 0xD5, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x81, 0xE9, 0x65, 0x66, 0x76, 0x47, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x35, 0x87, 0x06, 0x73, 0xCF, 0x34, 0xD2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x81, 0x15, 0x42, 0xA2, 0x79, 0x5B, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x08, 0xA2, 0x7D, 0x09, 0x14, 0x64, 0xC6, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x6D, 0xC4, 0xED, 0xF1, 0xD6, 0xE9, 0x24 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_22_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xD5, 0xBB, 0x25, 0xA3, 0xDD, 0xA3, 0x88 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0xF2, 0x68, 0x67, 0x39, 0x8F, 0x73, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0x76, 0x28, 0x89, 0xAD, 0x32, 0xE0, 0xDF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0x90, 0xCC, 0x57, 0x58, 0xAA, 0xC9, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0xD7, 0x43, 0xD2, 0xCE, 0x5E, 0xA0, 0x08 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x33, 0xB0, 0xB8, 0xA4, 0x9E, 0x96, 0x26, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0x61, 0x1D, 0xF3, 0x65, 0x5E, 0x60, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC7, 0x1E, 0x65, 0xED, 0xCF, 0x07, 0x60, 0x20 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_23_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x30, 0x17, 0x8A, 0x91, 0x88, 0x0A, 0xA4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x05, 0x7D, 0x18, 0xA4, 0xAC, 0x59, 0xFC, 0x5F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x31, 0x8B, 0x25, 0x65, 0x39, 0x9A, 0xDC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x16, 0x4B, 0x68, 0xBA, 0x59, 0x13, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xD3, 0xC5, 0x56, 0xC9, 0x8C, 0x5E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xC6, 0x9F, 0xF4, 0xE6, 0xF7, 0xB4, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2D, 0x7C, 0x03, 0x00, 0x26, 0x9F, 0xD8, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0x1D, 0x6E, 0x00, 0xB9, 0x00, 0x6E, 0x93 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_23_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0x63, 0xDA, 0x03, 0x2B, 0xD5, 0x0B, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x46, 0xFC, 0xE2, 0xC8, 0x47, 0xF0, 0xAE, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x4C, 0xF7, 0x50, 0x0C, 0x48, 0x06, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x2B, 0x32, 0x98, 0x0E, 0x7E, 0x61, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x02, 0x27, 0xFE, 0x75, 0x86, 0xDF, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2B, 0x30, 0xB1, 0x22, 0x32, 0x1B, 0xFE, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x27, 0xF7, 0x78, 0x6F, 0xD7, 0xFD, 0xE4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x78, 0xCC, 0xEA, 0xC0, 0x50, 0x24, 0x44 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_24_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x2B, 0x4F, 0x7F, 0x58, 0xE6, 0xC2, 0x70 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x43, 0xD5, 0xA7, 0x35, 0x3C, 0x80, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x6D, 0x4B, 0x12, 0x00, 0x7B, 0xE6, 0xA6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x15, 0xBD, 0xD0, 0x9B, 0xCA, 0xAA, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCF, 0xCE, 0x9C, 0xE3, 0x8B, 0x60, 0x7A, 0x53 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0xDA, 0x4B, 0x03, 0xA7, 0x8D, 0x43, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0xAF, 0x00, 0x2B, 0x32, 0xF0, 0x22, 0x68 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDC, 0xD9, 0x99, 0x99, 0xBE, 0x43, 0x99, 0x3E ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_24_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x71, 0x41, 0xF4, 0xB5, 0xFD, 0xDD, 0x36 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xE2, 0x20, 0x4C, 0xD1, 0x2E, 0x1F, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0x43, 0x48, 0x76, 0x8A, 0x49, 0xAC, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x1A, 0x55, 0xA8, 0xA3, 0xD4, 0x57, 0x75 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0xA6, 0x84, 0x39, 0xC9, 0x13, 0xBB, 0x60 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0xFA, 0xA9, 0x70, 0xDE, 0x83, 0xDD, 0xC9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0xC9, 0xD9, 0x3E, 0x44, 0x91, 0x68, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x9F, 0x85, 0x6D, 0xF7, 0x54, 0x36, 0x82 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_25_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x6B, 0xA6, 0xA3, 0xE5, 0xD4, 0x46, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x3E, 0xDC, 0x84, 0x7C, 0x7B, 0x24, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x14, 0xED, 0x7F, 0x86, 0x07, 0x6C, 0x57, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x95, 0x06, 0xFE, 0x52, 0x12, 0x79, 0x69, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0xD1, 0x44, 0x5F, 0x21, 0x3A, 0xC3, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0xD9, 0x4A, 0xC0, 0x75, 0xAB, 0x17, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x81, 0x94, 0xB6, 0x80, 0x6B, 0x6F, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xBE, 0x8E, 0xA5, 0xAA, 0xBC, 0x1E, 0x3E ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_25_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0xC7, 0x85, 0xA6, 0x59, 0x9B, 0xB1, 0x52 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0xCE, 0x40, 0xD1, 0xFB, 0xDF, 0x94, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x18, 0xB8, 0x5E, 0xBF, 0x45, 0xA8, 0x2D, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x9C, 0x06, 0x1B, 0xA9, 0x57, 0xB9, 0x79 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xE9, 0xCE, 0xA2, 0xD3, 0x74, 0xA1, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x5F, 0x34, 0x78, 0xDB, 0xAE, 0x3A, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x32, 0x84, 0x3E, 0x68, 0x6A, 0x43, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0xBC, 0x39, 0x36, 0xA4, 0xC5, 0xBB, 0x11 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_26_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8C, 0x07, 0xA2, 0xB5, 0xC9, 0x0F, 0x4D, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x1D, 0x67, 0xE6, 0xF1, 0x46, 0xEB, 0x71 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD7, 0x41, 0x23, 0x95, 0xE7, 0xE0, 0x10, 0xDD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0x69, 0xFE, 0x68, 0x8C, 0xC6, 0x5F, 0xB6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0xB9, 0x2B, 0x3D, 0xD2, 0x4F, 0xD8, 0x1A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA3, 0x09, 0xF5, 0x5F, 0xCF, 0xF6, 0x91, 0x57 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x15, 0x42, 0x6B, 0x6D, 0xB5, 0xF3, 0xB6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x56, 0x9D, 0xC5, 0xFF, 0xCA, 0x13, 0x9B ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_26_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0x38, 0xE6, 0x23, 0x63, 0x48, 0x3C, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD2, 0x68, 0x3C, 0xD1, 0x3B, 0xE9, 0x3B, 0x82 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0x08, 0x54, 0x49, 0xD1, 0x46, 0x45, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x70, 0x52, 0x6E, 0x79, 0xC4, 0x5E, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xDF, 0xE8, 0x5A, 0x32, 0x81, 0xDA, 0xD3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3C, 0x2D, 0x94, 0x5B, 0xB5, 0x35, 0x9F, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2A, 0x12, 0x8D, 0xC3, 0x36, 0x36, 0xB2, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x39, 0x2F, 0x22, 0x38, 0x5B, 0x18, 0x4C, 0x35 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_27_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xC1, 0x22, 0x0E, 0xF0, 0x73, 0x11, 0x05 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB2, 0xAE, 0xA4, 0x56, 0x18, 0x61, 0x66, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x79, 0xFB, 0x72, 0x08, 0x84, 0x38, 0x51, 0xB0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDA, 0x86, 0xA8, 0xB9, 0x31, 0x99, 0x29, 0xC3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8A, 0xFB, 0xC3, 0x42, 0xB3, 0xC7, 0x6F, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD8, 0xF8, 0xE1, 0x09, 0xBE, 0x75, 0xB0, 0x22 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x7D, 0xFF, 0xF4, 0x99, 0xFC, 0x13, 0xAB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x1B, 0x84, 0x81, 0x42, 0x22, 0xC6, 0x3D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_27_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xE0, 0x37, 0xA4, 0xA0, 0x2F, 0x38, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x3D, 0xB7, 0x40, 0x2F, 0x39, 0x3C, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0x3B, 0x8A, 0x51, 0xAE, 0x40, 0x49, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0x20, 0x9F, 0xDD, 0xA9, 0xD0, 0x77, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0x1D, 0x64, 0xDA, 0xA0, 0x53, 0xC7, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x7B, 0x66, 0x55, 0x94, 0xD1, 0x51, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xA9, 0xB5, 0x5B, 0x38, 0x35, 0x40, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC8, 0xC9, 0x0F, 0xF0, 0x73, 0x79, 0x43, 0x61 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_28_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x47, 0x45, 0x69, 0x80, 0x72, 0x72, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x11, 0x99, 0x59, 0xDB, 0x48, 0x80, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x75, 0x6E, 0x3D, 0xFC, 0x37, 0x15, 0xF4, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xBB, 0x5B, 0xA6, 0x35, 0x8D, 0x28, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0x1A, 0x3B, 0x2C, 0x8F, 0xD3, 0xAA, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x55, 0x1C, 0x1A, 0xF8, 0x02, 0xD9, 0x7B, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0x69, 0xAC, 0xF8, 0x54, 0x31, 0x14, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x8A, 0xE6, 0xDE, 0x58, 0xB9, 0xC4, 0x7A ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_28_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x83, 0x52, 0xFE, 0xF9, 0x7B, 0xE9, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xA2, 0x55, 0x46, 0x15, 0x49, 0xC1, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0xBC, 0x5C, 0x91, 0xBD, 0xB9, 0x9C, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBB, 0xFD, 0xB1, 0x4E, 0x5F, 0x74, 0xEE, 0x53 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0x8B, 0xD8, 0x8B, 0x17, 0x73, 0x1B, 0x96 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x92, 0xD7, 0x67, 0x06, 0xAD, 0x25, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x0F, 0x80, 0x24, 0xE2, 0x27, 0x5F, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x1C, 0xCE, 0xD0, 0x67, 0xCA, 0xD4, 0x0B ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_29_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0xF1, 0xDD, 0x33, 0x66, 0xF9, 0x05, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1D, 0xE5, 0x6B, 0x79, 0xBD, 0x48, 0x42, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x14, 0x52, 0xE3, 0x53, 0xB4, 0x50, 0xD4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x32, 0x84, 0x6C, 0xCF, 0xDA, 0xB2, 0x20, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0xD6, 0x1A, 0xE5, 0xE2, 0x29, 0x70, 0xCE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x61, 0xFE, 0xBB, 0x21, 0x82, 0xD1, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0xF0, 0x9C, 0x8B, 0x1A, 0x42, 0x30, 0x06 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0xD6, 0x49, 0x81, 0x92, 0xF1, 0xD0, 0x90 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_29_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x91, 0x93, 0x6A, 0xA6, 0x22, 0xE9, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0xDC, 0xC3, 0x69, 0x11, 0x95, 0x7D, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1C, 0xA3, 0x9D, 0x87, 0x5E, 0x64, 0x41, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBE, 0x87, 0x5A, 0x15, 0xBD, 0x6E, 0x3C, 0x8D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0x8D, 0x50, 0xCC, 0xCF, 0xB7, 0x8F, 0x0B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x65, 0xCD, 0x31, 0x30, 0xF1, 0x68, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x5C, 0x66, 0x67, 0x92, 0x30, 0x57, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x9B, 0x01, 0x3D, 0x20, 0x8B, 0xD1, 0x0D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_30_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAB, 0xC0, 0xE6, 0x4F, 0xDE, 0x62, 0xAB, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0x48, 0xB3, 0x1C, 0x0F, 0x16, 0x93, 0x45 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x63, 0xBD, 0x1F, 0x16, 0x50, 0x56, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5D, 0x06, 0xBC, 0xE9, 0x27, 0x1C, 0x9A, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF8, 0xFE, 0x21, 0xC5, 0x39, 0x55, 0xE1, 0xFD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xA8, 0xD0, 0x96, 0x0E, 0xB5, 0xB2, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0xE7, 0x4B, 0xF3, 0x11, 0x0C, 0xC9, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x43, 0x3A, 0xC4, 0x87, 0x71, 0xEE, 0xFA, 0x18 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_30_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x77, 0xEE, 0x81, 0x5E, 0x96, 0xEA, 0x4B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0xDF, 0xA9, 0xF4, 0x4F, 0x7C, 0xB2, 0x43 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9F, 0xD4, 0xDF, 0x35, 0x63, 0x47, 0x25, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x3D, 0xFF, 0xA4, 0x02, 0xC3, 0x95, 0x11 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x10, 0x78, 0xD1, 0x2B, 0xB7, 0xBE, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0A, 0xE9, 0x57, 0xF9, 0xE0, 0xD8, 0xFC, 0xBC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0xC4, 0x01, 0xD6, 0xB4, 0xE7, 0x78, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x02, 0x6C, 0xB9, 0x13, 0xA4, 0xE8, 0x6D, 0x6F ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_31_X[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0xB0, 0xC9, 0xCD, 0xBF, 0xA2, 0x1E, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0x4F, 0x86, 0x22, 0x9B, 0xEA, 0xE8, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x46, 0xDF, 0x43, 0xB9, 0x82, 0x2D, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x32, 0xF1, 0x4E, 0x95, 0x41, 0xAE, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0x93, 0x26, 0xFC, 0xD3, 0x90, 0xDC, 0xEB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x05, 0x45, 0xCA, 0xF9, 0x5A, 0x89, 0x93 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x82, 0x63, 0x4E, 0x55, 0x1D, 0x3A, 0x08 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x69, 0x52, 0x49, 0xE9, 0xED, 0x57, 0x34 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_T_31_Y[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x64, 0xE9, 0xAC, 0x4C, 0x4A, 0xEA, 0x25 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE9, 0xE9, 0x0B, 0x99, 0xE7, 0xF9, 0xA9, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x24, 0x0C, 0xC1, 0xF4, 0x8D, 0x07, 0xB6, 0xB1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAD, 0x68, 0xFA, 0x35, 0xE4, 0x9E, 0xAE, 0xD9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF0, 0x2D, 0x1A, 0x13, 0x8E, 0x02, 0xE2, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x27, 0x38, 0x28, 0x86, 0x46, 0x7B, 0x3A, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3F, 0x4C, 0x64, 0x59, 0x0A, 0xF9, 0x02, 0xC4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x4F, 0x23, 0xA2, 0xC3, 0xD5, 0xEF, 0x42 ),
+};
+static const mbedtls_ecp_point brainpoolP512r1_T[32] = {
+    ECP_POINT_INIT_XY_Z1(brainpoolP512r1_T_0_X, brainpoolP512r1_T_0_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_1_X, brainpoolP512r1_T_1_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_2_X, brainpoolP512r1_T_2_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_3_X, brainpoolP512r1_T_3_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_4_X, brainpoolP512r1_T_4_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_5_X, brainpoolP512r1_T_5_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_6_X, brainpoolP512r1_T_6_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_7_X, brainpoolP512r1_T_7_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_8_X, brainpoolP512r1_T_8_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_9_X, brainpoolP512r1_T_9_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_10_X, brainpoolP512r1_T_10_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_11_X, brainpoolP512r1_T_11_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_12_X, brainpoolP512r1_T_12_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_13_X, brainpoolP512r1_T_13_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_14_X, brainpoolP512r1_T_14_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_15_X, brainpoolP512r1_T_15_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_16_X, brainpoolP512r1_T_16_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_17_X, brainpoolP512r1_T_17_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_18_X, brainpoolP512r1_T_18_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_19_X, brainpoolP512r1_T_19_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_20_X, brainpoolP512r1_T_20_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_21_X, brainpoolP512r1_T_21_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_22_X, brainpoolP512r1_T_22_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_23_X, brainpoolP512r1_T_23_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_24_X, brainpoolP512r1_T_24_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_25_X, brainpoolP512r1_T_25_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_26_X, brainpoolP512r1_T_26_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_27_X, brainpoolP512r1_T_27_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_28_X, brainpoolP512r1_T_28_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_29_X, brainpoolP512r1_T_29_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_30_X, brainpoolP512r1_T_30_Y),
+    ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_31_X, brainpoolP512r1_T_31_Y),
+};
+#else
+#define brainpoolP512r1_T NULL
+#endif
+#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+
 #if defined(ECP_LOAD_GROUP)
 /*
  * Create an MPI from embedded constants
@@ -585,10 +4523,9 @@
  */
 static inline void ecp_mpi_set1( mbedtls_mpi *X )
 {
-    static mbedtls_mpi_uint one[] = { 1 };
     X->s = 1;
     X->n = 1;
-    X->p = one;
+    X->p = mpi_one;
 }
 
 /*
@@ -600,7 +4537,8 @@
                            const mbedtls_mpi_uint *b,  size_t blen,
                            const mbedtls_mpi_uint *gx, size_t gxlen,
                            const mbedtls_mpi_uint *gy, size_t gylen,
-                           const mbedtls_mpi_uint *n,  size_t nlen)
+                           const mbedtls_mpi_uint *n,  size_t nlen,
+                           const mbedtls_ecp_point *T)
 {
     ecp_mpi_load( &grp->P, p, plen );
     if( a != NULL )
@@ -617,6 +4555,12 @@
 
     grp->h = 1;
 
+    grp->T = (mbedtls_ecp_point *) T;
+    /*
+     * Set T_size to 0 to prevent T free by mbedtls_ecp_group_free.
+     */
+    grp->T_size = 0;
+
     return( 0 );
 }
 #endif /* ECP_LOAD_GROUP */
@@ -668,7 +4612,9 @@
                             G ## _b,  sizeof( G ## _b  ),   \
                             G ## _gx, sizeof( G ## _gx ),   \
                             G ## _gy, sizeof( G ## _gy ),   \
-                            G ## _n,  sizeof( G ## _n  ) )
+                            G ## _n,  sizeof( G ## _n  ),   \
+                            G ## _T                         \
+                            )
 
 #define LOAD_GROUP( G )     ecp_group_load( grp,            \
                             G ## _p,  sizeof( G ## _p  ),   \
@@ -676,10 +4622,19 @@
                             G ## _b,  sizeof( G ## _b  ),   \
                             G ## _gx, sizeof( G ## _gx ),   \
                             G ## _gy, sizeof( G ## _gy ),   \
-                            G ## _n,  sizeof( G ## _n  ) )
+                            G ## _n,  sizeof( G ## _n  ),   \
+                            G ## _T                         \
+                            )
 #endif /* ECP_LOAD_GROUP */
 
 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+/* Constants used by ecp_use_curve25519() */
+static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
+static const unsigned char curve25519_part_of_n[] = {
+    0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
+    0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
+};
+
 /*
  * Specialized function for creating the Curve25519 group
  */
@@ -688,7 +4643,7 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
     /* Actually ( A + 2 ) / 4 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve25519_a24 ) );
 
     /* P = 2^255 - 19 */
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
@@ -697,8 +4652,8 @@
     grp->pbits = mbedtls_mpi_bitlen( &grp->P );
 
     /* N = 2^252 + 27742317777372353535851937790883648493 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->N, 16,
-                                              "14DEF9DEA2F79CD65812631A5CF5D3ED" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N,
+                     curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
 
     /* Y intentionally not set, since we use x/z coordinates.
@@ -719,6 +4674,15 @@
 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
 
 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+/* Constants used by ecp_use_curve448() */
+static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
+static const unsigned char curve448_part_of_n[] = {
+    0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
+    0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
+    0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
+    0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
+};
+
 /*
  * Specialized function for creating the Curve448 group
  */
@@ -730,7 +4694,7 @@
     mbedtls_mpi_init( &Ns );
 
     /* Actually ( A + 2 ) / 4 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "98AA" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve448_a24 ) );
 
     /* P = 2^448 - 2^224 - 1 */
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
@@ -748,8 +4712,8 @@
 
     /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
     MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &Ns, 16,
-                                              "8335DC163BB124B65129C96FDE933D8D723A70AADC873D6D54A7BB0D" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
+                        curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
 
     /* Actually, the required msb for private keys */
@@ -1446,9 +5410,11 @@
 static int ecp_mod_p192k1( mbedtls_mpi *N )
 {
     static mbedtls_mpi_uint Rp[] = {
-        BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+        MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
+                                   0x00 ) };
 
-    return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+    return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
+                             0 ) );
 }
 #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
 
@@ -1460,12 +5426,14 @@
 static int ecp_mod_p224k1( mbedtls_mpi *N )
 {
     static mbedtls_mpi_uint Rp[] = {
-        BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+        MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
+                                   0x00 ) };
 
 #if defined(MBEDTLS_HAVE_INT64)
     return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
 #else
-    return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+    return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
+                             0 ) );
 #endif
 }
 
@@ -1479,8 +5447,10 @@
 static int ecp_mod_p256k1( mbedtls_mpi *N )
 {
     static mbedtls_mpi_uint Rp[] = {
-        BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
-    return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+        MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
+                                   0x00 ) };
+    return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
+                             0 ) );
 }
 #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
 
diff --git a/library/ecp_alt.h b/library/ecp_internal_alt.h
similarity index 98%
rename from library/ecp_alt.h
rename to library/ecp_internal_alt.h
index 6b1b29f..a7544aa 100644
--- a/library/ecp_alt.h
+++ b/library/ecp_internal_alt.h
@@ -1,5 +1,5 @@
 /**
- * \file ecp_alt.h
+ * \file ecp_internal_alt.h
  *
  * \brief Function declarations for alternative implementation of elliptic curve
  * point arithmetic.
@@ -59,11 +59,7 @@
 #ifndef MBEDTLS_ECP_INTERNAL_H
 #define MBEDTLS_ECP_INTERNAL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
 
@@ -293,5 +289,5 @@
 
 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
 
-#endif /* ecp_alt.h */
+#endif /* ecp_internal_alt.h */
 
diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h
index b523967..71c7702 100644
--- a/library/ecp_invasive.h
+++ b/library/ecp_invasive.h
@@ -27,6 +27,7 @@
 #define MBEDTLS_ECP_INVASIVE_H
 
 #include "common.h"
+#include "mbedtls/bignum.h"
 #include "mbedtls/ecp.h"
 
 #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_C)
@@ -46,6 +47,35 @@
 void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits );
 #endif
 
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+/** Generate a private key on a Montgomery curve (Curve25519 or Curve448).
+ *
+ * This function implements key generation for the set of secret keys
+ * specified in [Curve25519] p. 5 and in [Curve448]. The resulting value
+ * has the lower bits masked but is not necessarily canonical.
+ *
+ * \note            - [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
+ *                  - [RFC7748] https://tools.ietf.org/html/rfc7748
+ *
+ * \p high_bit      The position of the high-order bit of the key to generate.
+ *                  This is the bit-size of the key minus 1:
+ *                  254 for Curve25519 or 447 for Curve448.
+ * \param d         The randomly generated key. This is a number of size
+ *                  exactly \p n_bits + 1 bits, with the least significant bits
+ *                  masked as specified in [Curve25519] and in [RFC7748] §5.
+ * \param f_rng     The RNG function.
+ * \param p_rng     The RNG context to be passed to \p f_rng.
+ *
+ * \return          \c 0 on success.
+ * \return          \c MBEDTLS_ERR_ECP_xxx or MBEDTLS_ERR_MPI_xxx on failure.
+ */
+int mbedtls_ecp_gen_privkey_mx( size_t n_bits,
+                                mbedtls_mpi *d,
+                                int (*f_rng)(void *, unsigned char *, size_t),
+                                void *p_rng );
+
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
+
 #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */
 
 #endif /* MBEDTLS_ECP_INVASIVE_H */
diff --git a/library/entropy.c b/library/entropy.c
index cc68628..9e31f84 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -73,11 +73,6 @@
                                 MBEDTLS_ENTROPY_MIN_PLATFORM,
                                 MBEDTLS_ENTROPY_SOURCE_STRONG );
 #endif
-#if defined(MBEDTLS_TIMING_C)
-    mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
-                                MBEDTLS_ENTROPY_MIN_HARDCLOCK,
-                                MBEDTLS_ENTROPY_SOURCE_WEAK );
-#endif
 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
     mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
                                 MBEDTLS_ENTROPY_MIN_HARDWARE,
@@ -164,10 +159,10 @@
     if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
     {
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
-        if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 )
+        if( ( ret = mbedtls_sha512( data, len, tmp, 0 ) ) != 0 )
             goto cleanup;
 #else
-        if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 )
+        if( ( ret = mbedtls_sha256( data, len, tmp, 0 ) ) != 0 )
             goto cleanup;
 #endif
         p = tmp;
@@ -184,22 +179,22 @@
      */
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
     if( ctx->accumulator_started == 0 &&
-        ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        ( ret = mbedtls_sha512_starts( &ctx->accumulator, 0 ) ) != 0 )
         goto cleanup;
     else
         ctx->accumulator_started = 1;
-    if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
+    if( ( ret = mbedtls_sha512_update( &ctx->accumulator, header, 2 ) ) != 0 )
         goto cleanup;
-    ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len );
+    ret = mbedtls_sha512_update( &ctx->accumulator, p, use_len );
 #else
     if( ctx->accumulator_started == 0 &&
-        ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        ( ret = mbedtls_sha256_starts( &ctx->accumulator, 0 ) ) != 0 )
         goto cleanup;
     else
         ctx->accumulator_started = 1;
-    if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
+    if( ( ret = mbedtls_sha256_update( &ctx->accumulator, header, 2 ) ) != 0 )
         goto cleanup;
-    ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len );
+    ret = mbedtls_sha256_update( &ctx->accumulator, p, use_len );
 #endif
 
 cleanup:
@@ -361,7 +356,7 @@
      * in a previous call to entropy_update(). If this is not guaranteed, the
      * code below will fail.
      */
-    if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 )
+    if( ( ret = mbedtls_sha512_finish( &ctx->accumulator, buf ) ) != 0 )
         goto exit;
 
     /*
@@ -369,20 +364,20 @@
      */
     mbedtls_sha512_free( &ctx->accumulator );
     mbedtls_sha512_init( &ctx->accumulator );
-    if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+    if( ( ret = mbedtls_sha512_starts( &ctx->accumulator, 0 ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf,
+    if( ( ret = mbedtls_sha512_update( &ctx->accumulator, buf,
                                            MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
         goto exit;
 
     /*
      * Perform second SHA-512 on entropy
      */
-    if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
+    if( ( ret = mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
                                     buf, 0 ) ) != 0 )
         goto exit;
 #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
-    if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 )
+    if( ( ret = mbedtls_sha256_finish( &ctx->accumulator, buf ) ) != 0 )
         goto exit;
 
     /*
@@ -390,16 +385,16 @@
      */
     mbedtls_sha256_free( &ctx->accumulator );
     mbedtls_sha256_init( &ctx->accumulator );
-    if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+    if( ( ret = mbedtls_sha256_starts( &ctx->accumulator, 0 ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf,
+    if( ( ret = mbedtls_sha256_update( &ctx->accumulator, buf,
                                            MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
         goto exit;
 
     /*
      * Perform second SHA-256 on entropy
      */
-    if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
+    if( ( ret = mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
                                     buf, 0 ) ) != 0 )
         goto exit;
 #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index e5d75c5..058c307 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -44,7 +44,7 @@
 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
     !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
     !defined(__HAIKU__) && !defined(__midipix__)
-#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
+#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in mbedtls_config.h"
 #endif
 
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
@@ -211,24 +211,6 @@
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
 
-#if defined(MBEDTLS_TIMING_C)
-int mbedtls_hardclock_poll( void *data,
-                    unsigned char *output, size_t len, size_t *olen )
-{
-    unsigned long timer = mbedtls_timing_hardclock();
-    ((void) data);
-    *olen = 0;
-
-    if( len < sizeof(unsigned long) )
-        return( 0 );
-
-    memcpy( output, &timer, sizeof(unsigned long) );
-    *olen = sizeof(unsigned long);
-
-    return( 0 );
-}
-#endif /* MBEDTLS_TIMING_C */
-
 #if defined(MBEDTLS_ENTROPY_NV_SEED)
 int mbedtls_nv_seed_poll( void *data,
                           unsigned char *output, size_t len, size_t *olen )
diff --git a/library/entropy_poll.h b/library/entropy_poll.h
index 9120fe5..aef1a09 100644
--- a/library/entropy_poll.h
+++ b/library/entropy_poll.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_ENTROPY_POLL_H
 #define MBEDTLS_ENTROPY_POLL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include <stddef.h>
 
@@ -38,7 +34,6 @@
  * Default thresholds for built-in sources, in bytes
  */
 #define MBEDTLS_ENTROPY_MIN_PLATFORM     32     /**< Minimum for platform source    */
-#define MBEDTLS_ENTROPY_MIN_HARDCLOCK     4     /**< Minimum for mbedtls_timing_hardclock()        */
 #if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE)
 #define MBEDTLS_ENTROPY_MIN_HARDWARE     32     /**< Minimum for the hardware source */
 #endif
@@ -51,20 +46,12 @@
                            unsigned char *output, size_t len, size_t *olen );
 #endif
 
-#if defined(MBEDTLS_TIMING_C)
-/**
- * \brief           mbedtls_timing_hardclock-based entropy poll callback
- */
-int mbedtls_hardclock_poll( void *data,
-                    unsigned char *output, size_t len, size_t *olen );
-#endif
-
 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
 /**
  * \brief           Entropy poll callback for a hardware source
  *
  * \warning         This is not provided by mbed TLS!
- *                  See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h.
+ *                  See \c MBEDTLS_ENTROPY_HARDWARE_ALT in mbedtls_config.h.
  *
  * \note            This must accept NULL as its first argument.
  */
diff --git a/library/gcm.c b/library/gcm.c
index 2bd9071..910646b 100644
--- a/library/gcm.c
+++ b/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,
@@ -281,7 +258,7 @@
     GCM_VALIDATE_RET( ctx != NULL );
     GCM_VALIDATE_RET( iv != NULL );
 
-    /* IV is are limited to 2^64 bits, so 2^61 bytes */
+    /* IV is limited to 2^64 bits, so 2^61 bytes */
     /* IV is not allowed to be zero length */
     if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -301,7 +278,7 @@
     else
     {
         memset( work_buf, 0x00, 16 );
-        PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
+        MBEDTLS_PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
 
         p = iv;
         while( iv_len > 0 )
@@ -332,36 +309,72 @@
     return( 0 );
 }
 
-
+/**
+ * mbedtls_gcm_context::buf contains the partial state of the computation of
+ * the authentication tag.
+ * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
+ * different stages of the computation:
+ *     * len == 0 && add_len == 0:      initial state
+ *     * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
+ *                                      a partial block of AD that has been
+ *                                      xored in but not yet multiplied in.
+ *     * len == 0 && add_len % 16 == 0: the authentication tag is correct if
+ *                                      the data ends now.
+ *     * len % 16 != 0:                 the first `len % 16` bytes have
+ *                                      a partial block of ciphertext that has
+ *                                      been xored in but not yet multiplied in.
+ *     * len > 0 && len % 16 == 0:      the authentication tag is correct if
+ *                                      the data ends now.
+ */
 int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
                            const unsigned char *add, size_t add_len )
 {
     const unsigned char *p;
-    size_t use_len, i;
+    size_t use_len, i, offset;
 
     GCM_VALIDATE_RET( add_len == 0 || add != NULL );
 
-    /* IV is are limited to 2^64 bits, so 2^61 bytes */
+    /* IV is limited to 2^64 bits, so 2^61 bytes */
     if( (uint64_t) add_len >> 61 != 0 )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
 
-    /* Calling update_ad multiple times is not yet supported */
-    if( ctx->add_len != 0 )
-        return( MBEDTLS_ERR_GCM_BAD_INPUT );
-
-    ctx->add_len = add_len;
+    offset = ctx->add_len % 16;
     p = add;
-    while( add_len > 0 )
+
+    if( offset != 0 )
     {
-        use_len = ( add_len < 16 ) ? add_len : 16;
+        use_len = 16 - offset;
+        if( use_len > add_len )
+            use_len = add_len;
 
         for( i = 0; i < use_len; i++ )
+            ctx->buf[i+offset] ^= p[i];
+
+        if( offset + use_len == 16 )
+            gcm_mult( ctx, ctx->buf, ctx->buf );
+
+        ctx->add_len += use_len;
+        add_len -= use_len;
+        p += use_len;
+    }
+
+    ctx->add_len += add_len;
+
+    while( add_len >= 16 )
+    {
+        for( i = 0; i < 16; i++ )
             ctx->buf[i] ^= p[i];
 
         gcm_mult( ctx, ctx->buf, ctx->buf );
 
-        add_len -= use_len;
-        p += use_len;
+        add_len -= 16;
+        p += 16;
+    }
+
+    if( add_len > 0 )
+    {
+        for( i = 0; i < add_len; i++ )
+            ctx->buf[i] ^= p[i];
     }
 
     return( 0 );
@@ -423,7 +436,9 @@
     *output_length = input_length;
 
     /* Exit early if input_length==0 so that we don't do any pointer arithmetic
-     * on a potentially null pointer. */
+     * on a potentially null pointer.
+     * Returning early also means that the last partial block of AD remains
+     * untouched for mbedtls_gcm_finish */
     if( input_length == 0 )
         return( 0 );
 
@@ -442,6 +457,11 @@
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
     }
 
+    if( ctx->len == 0 && ctx->add_len % 16 != 0 )
+    {
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+    }
+
     offset = ctx->len % 16;
     if( offset != 0 )
     {
@@ -489,6 +509,7 @@
 
 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
                         unsigned char *output, size_t output_size,
+                        size_t *output_length,
                         unsigned char *tag, size_t tag_len )
 {
     unsigned char work_buf[16];
@@ -503,10 +524,16 @@
      * for the sake of alternative implementations. */
     (void) output;
     (void) output_size;
+    *output_length = 0;
 
     orig_len = ctx->len * 8;
     orig_add_len = ctx->add_len * 8;
 
+    if( ctx->len == 0 && ctx->add_len % 16 != 0 )
+    {
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+    }
+
     if( tag_len > 16 || tag_len < 4 )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
 
@@ -519,10 +546,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];
@@ -568,7 +595,7 @@
                                     output, length, &olen ) ) != 0 )
         return( ret );
 
-    if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
+    if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
         return( ret );
 
     return( 0 );
@@ -1020,7 +1047,7 @@
                     goto exit;
             }
 
-            ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
+            ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
             if( ret != 0 )
                 goto exit;
 
@@ -1092,7 +1119,7 @@
                     goto exit;
             }
 
-            ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
+            ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
             if( ret != 0 )
                 goto exit;
 
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 7e1b4fb..ab353bf 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -59,7 +59,7 @@
 /*
  * HMAC_DRBG update, using optional additional data (10.1.2.2)
  */
-int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
+int mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
                                   const unsigned char *additional,
                                   size_t add_len )
 {
@@ -130,7 +130,7 @@
         return( ret );
     memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
 
-    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
+    if( ( ret = mbedtls_hmac_drbg_update( ctx, data, data_len ) ) != 0 )
         return( ret );
 
     return( 0 );
@@ -205,7 +205,7 @@
     }
 
     /* 2. Update state */
-    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
+    if( ( ret = mbedtls_hmac_drbg_update( ctx, seed, seedlen ) ) != 0 )
         goto exit;
 
     /* 3. Reset reseed_counter */
@@ -348,7 +348,7 @@
     /* 2. Use additional data if any */
     if( additional != NULL && add_len != 0 )
     {
-        if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+        if( ( ret = mbedtls_hmac_drbg_update( ctx,
                                                   additional, add_len ) ) != 0 )
             goto exit;
     }
@@ -372,7 +372,7 @@
     }
 
     /* 6. Update */
-    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+    if( ( ret = mbedtls_hmac_drbg_update( ctx,
                                               additional, add_len ) ) != 0 )
         goto exit;
 
@@ -479,7 +479,7 @@
     fclose( f );
     f = NULL;
 
-    ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
+    ret = mbedtls_hmac_drbg_update( ctx, buf, n );
 
 exit:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
diff --git a/library/md.c b/library/md.c
index 28261ac..a228789 100644
--- a/library/md.c
+++ b/library/md.c
@@ -30,8 +30,6 @@
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
 
-#include "mbedtls/md2.h"
-#include "mbedtls/md4.h"
 #include "mbedtls/md5.h"
 #include "mbedtls/ripemd160.h"
 #include "mbedtls/sha1.h"
@@ -52,24 +50,6 @@
 #include <stdio.h>
 #endif
 
-#if defined(MBEDTLS_MD2_C)
-const mbedtls_md_info_t mbedtls_md2_info = {
-    "MD2",
-    MBEDTLS_MD_MD2,
-    16,
-    16,
-};
-#endif
-
-#if defined(MBEDTLS_MD4_C)
-const mbedtls_md_info_t mbedtls_md4_info = {
-    "MD4",
-    MBEDTLS_MD_MD4,
-    16,
-    64,
-};
-#endif
-
 #if defined(MBEDTLS_MD5_C)
 const mbedtls_md_info_t mbedtls_md5_info = {
     "MD5",
@@ -165,14 +145,6 @@
         MBEDTLS_MD_MD5,
 #endif
 
-#if defined(MBEDTLS_MD4_C)
-        MBEDTLS_MD_MD4,
-#endif
-
-#if defined(MBEDTLS_MD2_C)
-        MBEDTLS_MD_MD2,
-#endif
-
         MBEDTLS_MD_NONE
 };
 
@@ -187,14 +159,6 @@
         return( NULL );
 
     /* Get the appropriate digest information */
-#if defined(MBEDTLS_MD2_C)
-    if( !strcmp( "MD2", md_name ) )
-        return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
-#endif
-#if defined(MBEDTLS_MD4_C)
-    if( !strcmp( "MD4", md_name ) )
-        return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
-#endif
 #if defined(MBEDTLS_MD5_C)
     if( !strcmp( "MD5", md_name ) )
         return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
@@ -230,14 +194,6 @@
 {
     switch( md_type )
     {
-#if defined(MBEDTLS_MD2_C)
-        case MBEDTLS_MD_MD2:
-            return( &mbedtls_md2_info );
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case MBEDTLS_MD_MD4:
-            return( &mbedtls_md4_info );
-#endif
 #if defined(MBEDTLS_MD5_C)
         case MBEDTLS_MD_MD5:
             return( &mbedtls_md5_info );
@@ -285,16 +241,6 @@
     {
         switch( ctx->md_info->type )
         {
-#if defined(MBEDTLS_MD2_C)
-            case MBEDTLS_MD_MD2:
-                mbedtls_md2_free( ctx->md_ctx );
-                break;
-#endif
-#if defined(MBEDTLS_MD4_C)
-            case MBEDTLS_MD_MD4:
-                mbedtls_md4_free( ctx->md_ctx );
-                break;
-#endif
 #if defined(MBEDTLS_MD5_C)
             case MBEDTLS_MD_MD5:
                 mbedtls_md5_free( ctx->md_ctx );
@@ -359,16 +305,6 @@
 
     switch( src->md_info->type )
     {
-#if defined(MBEDTLS_MD2_C)
-        case MBEDTLS_MD_MD2:
-            mbedtls_md2_clone( dst->md_ctx, src->md_ctx );
-            break;
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case MBEDTLS_MD_MD4:
-            mbedtls_md4_clone( dst->md_ctx, src->md_ctx );
-            break;
-#endif
 #if defined(MBEDTLS_MD5_C)
         case MBEDTLS_MD_MD5:
             mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
@@ -431,16 +367,6 @@
 
     switch( md_info->type )
     {
-#if defined(MBEDTLS_MD2_C)
-        case MBEDTLS_MD_MD2:
-            ALLOC( md2 );
-            break;
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case MBEDTLS_MD_MD4:
-            ALLOC( md4 );
-            break;
-#endif
 #if defined(MBEDTLS_MD5_C)
         case MBEDTLS_MD_MD5:
             ALLOC( md5 );
@@ -501,41 +427,33 @@
 
     switch( ctx->md_info->type )
     {
-#if defined(MBEDTLS_MD2_C)
-        case MBEDTLS_MD_MD2:
-            return( mbedtls_md2_starts_ret( ctx->md_ctx ) );
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case MBEDTLS_MD_MD4:
-            return( mbedtls_md4_starts_ret( ctx->md_ctx ) );
-#endif
 #if defined(MBEDTLS_MD5_C)
         case MBEDTLS_MD_MD5:
-            return( mbedtls_md5_starts_ret( ctx->md_ctx ) );
+            return( mbedtls_md5_starts( ctx->md_ctx ) );
 #endif
 #if defined(MBEDTLS_RIPEMD160_C)
         case MBEDTLS_MD_RIPEMD160:
-            return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) );
+            return( mbedtls_ripemd160_starts( ctx->md_ctx ) );
 #endif
 #if defined(MBEDTLS_SHA1_C)
         case MBEDTLS_MD_SHA1:
-            return( mbedtls_sha1_starts_ret( ctx->md_ctx ) );
+            return( mbedtls_sha1_starts( ctx->md_ctx ) );
 #endif
 #if defined(MBEDTLS_SHA224_C)
         case MBEDTLS_MD_SHA224:
-            return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) );
+            return( mbedtls_sha256_starts( ctx->md_ctx, 1 ) );
 #endif
 #if defined(MBEDTLS_SHA256_C)
         case MBEDTLS_MD_SHA256:
-            return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) );
+            return( mbedtls_sha256_starts( ctx->md_ctx, 0 ) );
 #endif
 #if defined(MBEDTLS_SHA384_C)
         case MBEDTLS_MD_SHA384:
-            return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) );
+            return( mbedtls_sha512_starts( ctx->md_ctx, 1 ) );
 #endif
 #if defined(MBEDTLS_SHA512_C)
         case MBEDTLS_MD_SHA512:
-            return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) );
+            return( mbedtls_sha512_starts( ctx->md_ctx, 0 ) );
 #endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
@@ -549,41 +467,33 @@
 
     switch( ctx->md_info->type )
     {
-#if defined(MBEDTLS_MD2_C)
-        case MBEDTLS_MD_MD2:
-            return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) );
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case MBEDTLS_MD_MD4:
-            return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) );
-#endif
 #if defined(MBEDTLS_MD5_C)
         case MBEDTLS_MD_MD5:
-            return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) );
+            return( mbedtls_md5_update( ctx->md_ctx, input, ilen ) );
 #endif
 #if defined(MBEDTLS_RIPEMD160_C)
         case MBEDTLS_MD_RIPEMD160:
-            return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) );
+            return( mbedtls_ripemd160_update( ctx->md_ctx, input, ilen ) );
 #endif
 #if defined(MBEDTLS_SHA1_C)
         case MBEDTLS_MD_SHA1:
-            return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) );
+            return( mbedtls_sha1_update( ctx->md_ctx, input, ilen ) );
 #endif
 #if defined(MBEDTLS_SHA224_C)
         case MBEDTLS_MD_SHA224:
-            return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
+            return( mbedtls_sha256_update( ctx->md_ctx, input, ilen ) );
 #endif
 #if defined(MBEDTLS_SHA256_C)
         case MBEDTLS_MD_SHA256:
-            return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
+            return( mbedtls_sha256_update( ctx->md_ctx, input, ilen ) );
 #endif
 #if defined(MBEDTLS_SHA384_C)
         case MBEDTLS_MD_SHA384:
-            return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
+            return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
 #endif
 #if defined(MBEDTLS_SHA512_C)
         case MBEDTLS_MD_SHA512:
-            return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
+            return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
 #endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
@@ -597,41 +507,33 @@
 
     switch( ctx->md_info->type )
     {
-#if defined(MBEDTLS_MD2_C)
-        case MBEDTLS_MD_MD2:
-            return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) );
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case MBEDTLS_MD_MD4:
-            return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) );
-#endif
 #if defined(MBEDTLS_MD5_C)
         case MBEDTLS_MD_MD5:
-            return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) );
+            return( mbedtls_md5_finish( ctx->md_ctx, output ) );
 #endif
 #if defined(MBEDTLS_RIPEMD160_C)
         case MBEDTLS_MD_RIPEMD160:
-            return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) );
+            return( mbedtls_ripemd160_finish( ctx->md_ctx, output ) );
 #endif
 #if defined(MBEDTLS_SHA1_C)
         case MBEDTLS_MD_SHA1:
-            return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) );
+            return( mbedtls_sha1_finish( ctx->md_ctx, output ) );
 #endif
 #if defined(MBEDTLS_SHA224_C)
         case MBEDTLS_MD_SHA224:
-            return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
+            return( mbedtls_sha256_finish( ctx->md_ctx, output ) );
 #endif
 #if defined(MBEDTLS_SHA256_C)
         case MBEDTLS_MD_SHA256:
-            return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
+            return( mbedtls_sha256_finish( ctx->md_ctx, output ) );
 #endif
 #if defined(MBEDTLS_SHA384_C)
         case MBEDTLS_MD_SHA384:
-            return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
+            return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
 #endif
 #if defined(MBEDTLS_SHA512_C)
         case MBEDTLS_MD_SHA512:
-            return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
+            return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
 #endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
@@ -646,41 +548,33 @@
 
     switch( md_info->type )
     {
-#if defined(MBEDTLS_MD2_C)
-        case MBEDTLS_MD_MD2:
-            return( mbedtls_md2_ret( input, ilen, output ) );
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case MBEDTLS_MD_MD4:
-            return( mbedtls_md4_ret( input, ilen, output ) );
-#endif
 #if defined(MBEDTLS_MD5_C)
         case MBEDTLS_MD_MD5:
-            return( mbedtls_md5_ret( input, ilen, output ) );
+            return( mbedtls_md5( input, ilen, output ) );
 #endif
 #if defined(MBEDTLS_RIPEMD160_C)
         case MBEDTLS_MD_RIPEMD160:
-            return( mbedtls_ripemd160_ret( input, ilen, output ) );
+            return( mbedtls_ripemd160( input, ilen, output ) );
 #endif
 #if defined(MBEDTLS_SHA1_C)
         case MBEDTLS_MD_SHA1:
-            return( mbedtls_sha1_ret( input, ilen, output ) );
+            return( mbedtls_sha1( input, ilen, output ) );
 #endif
 #if defined(MBEDTLS_SHA224_C)
         case MBEDTLS_MD_SHA224:
-            return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
+            return( mbedtls_sha256( input, ilen, output, 1 ) );
 #endif
 #if defined(MBEDTLS_SHA256_C)
         case MBEDTLS_MD_SHA256:
-            return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
+            return( mbedtls_sha256( input, ilen, output, 0 ) );
 #endif
 #if defined(MBEDTLS_SHA384_C)
         case MBEDTLS_MD_SHA384:
-            return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
+            return( mbedtls_sha512( input, ilen, output, 1 ) );
 #endif
 #if defined(MBEDTLS_SHA512_C)
         case MBEDTLS_MD_SHA512:
-            return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
+            return( mbedtls_sha512( input, ilen, output, 0 ) );
 #endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
@@ -858,14 +752,6 @@
 
     switch( ctx->md_info->type )
     {
-#if defined(MBEDTLS_MD2_C)
-        case MBEDTLS_MD_MD2:
-            return( mbedtls_internal_md2_process( ctx->md_ctx ) );
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case MBEDTLS_MD_MD4:
-            return( mbedtls_internal_md4_process( ctx->md_ctx, data ) );
-#endif
 #if defined(MBEDTLS_MD5_C)
         case MBEDTLS_MD_MD5:
             return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
diff --git a/library/md2.c b/library/md2.c
deleted file mode 100644
index a11bc0f..0000000
--- a/library/md2.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- *  RFC 1115/1319 compliant MD2 implementation
- *
- *  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 MD2 algorithm was designed by Ron Rivest in 1989.
- *
- *  http://www.ietf.org/rfc/rfc1115.txt
- *  http://www.ietf.org/rfc/rfc1319.txt
- */
-
-#include "common.h"
-
-#if defined(MBEDTLS_MD2_C)
-
-#include "mbedtls/md2.h"
-#include "mbedtls/platform_util.h"
-#include "mbedtls/error.h"
-
-#include <string.h>
-
-#if defined(MBEDTLS_SELF_TEST)
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST */
-
-#if !defined(MBEDTLS_MD2_ALT)
-
-static const unsigned char PI_SUBST[256] =
-{
-    0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
-    0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
-    0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
-    0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
-    0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
-    0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
-    0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
-    0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
-    0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
-    0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
-    0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
-    0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
-    0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
-    0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
-    0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
-    0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
-    0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
-    0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
-    0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
-    0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
-    0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
-    0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
-    0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
-    0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
-    0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
-    0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
-};
-
-void mbedtls_md2_init( mbedtls_md2_context *ctx )
-{
-    memset( ctx, 0, sizeof( mbedtls_md2_context ) );
-}
-
-void mbedtls_md2_free( mbedtls_md2_context *ctx )
-{
-    if( ctx == NULL )
-        return;
-
-    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md2_context ) );
-}
-
-void mbedtls_md2_clone( mbedtls_md2_context *dst,
-                        const mbedtls_md2_context *src )
-{
-    *dst = *src;
-}
-
-/*
- * MD2 context setup
- */
-int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx )
-{
-    memset( ctx->cksum, 0, 16 );
-    memset( ctx->state, 0, 46 );
-    memset( ctx->buffer, 0, 16 );
-    ctx->left = 0;
-
-    return( 0 );
-}
-
-#if !defined(MBEDTLS_MD2_PROCESS_ALT)
-int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
-{
-    int i, j;
-    unsigned char t = 0;
-
-    for( i = 0; i < 16; i++ )
-    {
-        ctx->state[i + 16] = ctx->buffer[i];
-        ctx->state[i + 32] =
-            (unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
-    }
-
-    for( i = 0; i < 18; i++ )
-    {
-        for( j = 0; j < 48; j++ )
-        {
-            ctx->state[j] = (unsigned char)
-               ( ctx->state[j] ^ PI_SUBST[t] );
-            t  = ctx->state[j];
-        }
-
-        t = (unsigned char)( t + i );
-    }
-
-    t = ctx->cksum[15];
-
-    for( i = 0; i < 16; i++ )
-    {
-        ctx->cksum[i] = (unsigned char)
-           ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
-        t  = ctx->cksum[i];
-    }
-
-    /* Zeroise variables to clear sensitive data from memory. */
-    mbedtls_platform_zeroize( &t, sizeof( t ) );
-
-    return( 0 );
-}
-
-#endif /* !MBEDTLS_MD2_PROCESS_ALT */
-
-/*
- * MD2 process buffer
- */
-int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
-                            const unsigned char *input,
-                            size_t ilen )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t fill;
-
-    while( ilen > 0 )
-    {
-        if( ilen > 16 - ctx->left )
-            fill = 16 - ctx->left;
-        else
-            fill = ilen;
-
-        memcpy( ctx->buffer + ctx->left, input, fill );
-
-        ctx->left += fill;
-        input += fill;
-        ilen  -= fill;
-
-        if( ctx->left == 16 )
-        {
-            ctx->left = 0;
-            if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
-                return( ret );
-        }
-    }
-
-    return( 0 );
-}
-
-/*
- * MD2 final digest
- */
-int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
-                            unsigned char output[16] )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i;
-    unsigned char x;
-
-    x = (unsigned char)( 16 - ctx->left );
-
-    for( i = ctx->left; i < 16; i++ )
-        ctx->buffer[i] = x;
-
-    if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
-        return( ret );
-
-    memcpy( ctx->buffer, ctx->cksum, 16 );
-    if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
-        return( ret );
-
-    memcpy( output, ctx->state, 16 );
-
-    return( 0 );
-}
-
-#endif /* !MBEDTLS_MD2_ALT */
-
-/*
- * output = MD2( input buffer )
- */
-int mbedtls_md2_ret( const unsigned char *input,
-                     size_t ilen,
-                     unsigned char output[16] )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_md2_context ctx;
-
-    mbedtls_md2_init( &ctx );
-
-    if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 )
-        goto exit;
-
-    if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 )
-        goto exit;
-
-    if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 )
-        goto exit;
-
-exit:
-    mbedtls_md2_free( &ctx );
-
-    return( ret );
-}
-
-#if defined(MBEDTLS_SELF_TEST)
-
-/*
- * RFC 1319 test vectors
- */
-static const unsigned char md2_test_str[7][81] =
-{
-    { "" },
-    { "a" },
-    { "abc" },
-    { "message digest" },
-    { "abcdefghijklmnopqrstuvwxyz" },
-    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
-};
-
-static const size_t md2_test_strlen[7] =
-{
-    0, 1, 3, 14, 26, 62, 80
-};
-
-static const unsigned char md2_test_sum[7][16] =
-{
-    { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
-      0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
-    { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
-      0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
-    { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
-      0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
-    { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
-      0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
-    { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
-      0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
-    { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
-      0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
-    { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
-      0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
-};
-
-/*
- * Checkup routine
- */
-int mbedtls_md2_self_test( int verbose )
-{
-    int i, ret = 0;
-    unsigned char md2sum[16];
-
-    for( i = 0; i < 7; i++ )
-    {
-        if( verbose != 0 )
-            mbedtls_printf( "  MD2 test #%d: ", i + 1 );
-
-        ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum );
-        if( ret != 0 )
-            goto fail;
-
-        if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
-        {
-            ret = 1;
-            goto fail;
-        }
-
-        if( verbose != 0 )
-            mbedtls_printf( "passed\n" );
-    }
-
-    if( verbose != 0 )
-        mbedtls_printf( "\n" );
-
-    return( 0 );
-
-fail:
-    if( verbose != 0 )
-        mbedtls_printf( "failed\n" );
-
-    return( ret );
-}
-
-#endif /* MBEDTLS_SELF_TEST */
-
-#endif /* MBEDTLS_MD2_C */
diff --git a/library/md4.c b/library/md4.c
deleted file mode 100644
index c366c0d..0000000
--- a/library/md4.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- *  RFC 1186/1320 compliant MD4 implementation
- *
- *  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 MD4 algorithm was designed by Ron Rivest in 1990.
- *
- *  http://www.ietf.org/rfc/rfc1186.txt
- *  http://www.ietf.org/rfc/rfc1320.txt
- */
-
-#include "common.h"
-
-#if defined(MBEDTLS_MD4_C)
-
-#include "mbedtls/md4.h"
-#include "mbedtls/platform_util.h"
-#include "mbedtls/error.h"
-
-#include <string.h>
-
-#if defined(MBEDTLS_SELF_TEST)
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST */
-
-#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 ) );
-}
-
-void mbedtls_md4_free( mbedtls_md4_context *ctx )
-{
-    if( ctx == NULL )
-        return;
-
-    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
-}
-
-void mbedtls_md4_clone( mbedtls_md4_context *dst,
-                        const mbedtls_md4_context *src )
-{
-    *dst = *src;
-}
-
-/*
- * MD4 context setup
- */
-int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
-{
-    ctx->total[0] = 0;
-    ctx->total[1] = 0;
-
-    ctx->state[0] = 0x67452301;
-    ctx->state[1] = 0xEFCDAB89;
-    ctx->state[2] = 0x98BADCFE;
-    ctx->state[3] = 0x10325476;
-
-    return( 0 );
-}
-
-#if !defined(MBEDTLS_MD4_PROCESS_ALT)
-int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
-                                  const unsigned char data[64] )
-{
-    struct
-    {
-        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 );
-
-#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
-
-    local.A = ctx->state[0];
-    local.B = ctx->state[1];
-    local.C = ctx->state[2];
-    local.D = ctx->state[3];
-
-#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
-#define P(a,b,c,d,x,s)                           \
-    do                                           \
-    {                                            \
-        (a) += F((b),(c),(d)) + (x);             \
-        (a) = S((a),(s));                        \
-    } while( 0 )
-
-
-    P( local.A, local.B, local.C, local.D, local.X[ 0],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 1],  7 );
-    P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
-    P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
-    P( local.A, local.B, local.C, local.D, local.X[ 4],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 5],  7 );
-    P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
-    P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
-    P( local.A, local.B, local.C, local.D, local.X[ 8],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 9],  7 );
-    P( local.C, local.D, local.A, local.B, local.X[10], 11 );
-    P( local.B, local.C, local.D, local.A, local.X[11], 19 );
-    P( local.A, local.B, local.C, local.D, local.X[12],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[13],  7 );
-    P( local.C, local.D, local.A, local.B, local.X[14], 11 );
-    P( local.B, local.C, local.D, local.A, local.X[15], 19 );
-
-#undef P
-#undef F
-
-#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
-#define P(a,b,c,d,x,s)                          \
-    do                                          \
-    {                                           \
-        (a) += F((b),(c),(d)) + (x) + 0x5A827999;       \
-        (a) = S((a),(s));                               \
-    } while( 0 )
-
-    P( local.A, local.B, local.C, local.D, local.X[ 0],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 4],  5 );
-    P( local.C, local.D, local.A, local.B, local.X[ 8],  9 );
-    P( local.B, local.C, local.D, local.A, local.X[12], 13 );
-    P( local.A, local.B, local.C, local.D, local.X[ 1],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 5],  5 );
-    P( local.C, local.D, local.A, local.B, local.X[ 9],  9 );
-    P( local.B, local.C, local.D, local.A, local.X[13], 13 );
-    P( local.A, local.B, local.C, local.D, local.X[ 2],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 6],  5 );
-    P( local.C, local.D, local.A, local.B, local.X[10],  9 );
-    P( local.B, local.C, local.D, local.A, local.X[14], 13 );
-    P( local.A, local.B, local.C, local.D, local.X[ 3],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 7],  5 );
-    P( local.C, local.D, local.A, local.B, local.X[11],  9 );
-    P( local.B, local.C, local.D, local.A, local.X[15], 13 );
-
-#undef P
-#undef F
-
-#define F(x,y,z) ((x) ^ (y) ^ (z))
-#define P(a,b,c,d,x,s)                                  \
-    do                                                  \
-    {                                                   \
-        (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1;       \
-        (a) = S((a),(s));                               \
-    } while( 0 )
-
-    P( local.A, local.B, local.C, local.D, local.X[ 0],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 8],  9 );
-    P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
-    P( local.B, local.C, local.D, local.A, local.X[12], 15 );
-    P( local.A, local.B, local.C, local.D, local.X[ 2],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[10],  9 );
-    P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
-    P( local.B, local.C, local.D, local.A, local.X[14], 15 );
-    P( local.A, local.B, local.C, local.D, local.X[ 1],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[ 9],  9 );
-    P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
-    P( local.B, local.C, local.D, local.A, local.X[13], 15 );
-    P( local.A, local.B, local.C, local.D, local.X[ 3],  3 );
-    P( local.D, local.A, local.B, local.C, local.X[11],  9 );
-    P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
-    P( local.B, local.C, local.D, local.A, local.X[15], 15 );
-
-#undef F
-#undef P
-
-    ctx->state[0] += local.A;
-    ctx->state[1] += local.B;
-    ctx->state[2] += local.C;
-    ctx->state[3] += local.D;
-
-    /* Zeroise variables to clear sensitive data from memory. */
-    mbedtls_platform_zeroize( &local, sizeof( local ) );
-
-    return( 0 );
-}
-
-#endif /* !MBEDTLS_MD4_PROCESS_ALT */
-
-/*
- * MD4 process buffer
- */
-int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
-                            const unsigned char *input,
-                            size_t ilen )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t fill;
-    uint32_t left;
-
-    if( ilen == 0 )
-        return( 0 );
-
-    left = ctx->total[0] & 0x3F;
-    fill = 64 - left;
-
-    ctx->total[0] += (uint32_t) ilen;
-    ctx->total[0] &= 0xFFFFFFFF;
-
-    if( ctx->total[0] < (uint32_t) ilen )
-        ctx->total[1]++;
-
-    if( left && ilen >= fill )
-    {
-        memcpy( (void *) (ctx->buffer + left),
-                (void *) input, fill );
-
-        if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
-            return( ret );
-
-        input += fill;
-        ilen  -= fill;
-        left = 0;
-    }
-
-    while( ilen >= 64 )
-    {
-        if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
-            return( ret );
-
-        input += 64;
-        ilen  -= 64;
-    }
-
-    if( ilen > 0 )
-    {
-        memcpy( (void *) (ctx->buffer + left),
-                (void *) input, ilen );
-    }
-
-    return( 0 );
-}
-
-static const unsigned char md4_padding[64] =
-{
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
- * MD4 final digest
- */
-int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
-                            unsigned char output[16] )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    uint32_t last, padn;
-    uint32_t high, low;
-    unsigned char msglen[8];
-
-    high = ( ctx->total[0] >> 29 )
-         | ( ctx->total[1] <<  3 );
-    low  = ( ctx->total[0] <<  3 );
-
-    PUT_UINT32_LE( low,  msglen, 0 );
-    PUT_UINT32_LE( high, msglen, 4 );
-
-    last = ctx->total[0] & 0x3F;
-    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
-
-    ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
-    if( ret != 0 )
-        return( ret );
-
-    if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 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 );
-
-    return( 0 );
-}
-
-#endif /* !MBEDTLS_MD4_ALT */
-
-/*
- * output = MD4( input buffer )
- */
-int mbedtls_md4_ret( const unsigned char *input,
-                     size_t ilen,
-                     unsigned char output[16] )
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_md4_context ctx;
-
-    mbedtls_md4_init( &ctx );
-
-    if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
-        goto exit;
-
-    if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
-        goto exit;
-
-    if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
-        goto exit;
-
-exit:
-    mbedtls_md4_free( &ctx );
-
-    return( ret );
-}
-
-#if defined(MBEDTLS_SELF_TEST)
-
-/*
- * RFC 1320 test vectors
- */
-static const unsigned char md4_test_str[7][81] =
-{
-    { "" },
-    { "a" },
-    { "abc" },
-    { "message digest" },
-    { "abcdefghijklmnopqrstuvwxyz" },
-    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
-};
-
-static const size_t md4_test_strlen[7] =
-{
-    0, 1, 3, 14, 26, 62, 80
-};
-
-static const unsigned char md4_test_sum[7][16] =
-{
-    { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
-      0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
-    { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
-      0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
-    { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
-      0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
-    { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
-      0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
-    { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
-      0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
-    { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
-      0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
-    { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
-      0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
-};
-
-/*
- * Checkup routine
- */
-int mbedtls_md4_self_test( int verbose )
-{
-    int i, ret = 0;
-    unsigned char md4sum[16];
-
-    for( i = 0; i < 7; i++ )
-    {
-        if( verbose != 0 )
-            mbedtls_printf( "  MD4 test #%d: ", i + 1 );
-
-        ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
-        if( ret != 0 )
-            goto fail;
-
-        if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
-        {
-            ret = 1;
-            goto fail;
-        }
-
-        if( verbose != 0 )
-            mbedtls_printf( "passed\n" );
-    }
-
-    if( verbose != 0 )
-        mbedtls_printf( "\n" );
-
-    return( 0 );
-
-fail:
-    if( verbose != 0 )
-        mbedtls_printf( "failed\n" );
-
-    return( ret );
-}
-
-#endif /* MBEDTLS_SELF_TEST */
-
-#endif /* MBEDTLS_MD4_C */
diff --git a/library/md5.c b/library/md5.c
index 019b7f4..a9bbcb4 100644
--- a/library/md5.c
+++ b/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 ) );
@@ -88,7 +65,7 @@
 /*
  * MD5 context setup
  */
-int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx )
+int mbedtls_md5_starts( mbedtls_md5_context *ctx )
 {
     ctx->total[0] = 0;
     ctx->total[1] = 0;
@@ -110,22 +87,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) ) ) )
@@ -242,7 +219,7 @@
 /*
  * MD5 process buffer
  */
-int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
+int mbedtls_md5_update( mbedtls_md5_context *ctx,
                             const unsigned char *input,
                             size_t ilen )
 {
@@ -293,7 +270,7 @@
 /*
  * MD5 final digest
  */
-int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
+int mbedtls_md5_finish( mbedtls_md5_context *ctx,
                             unsigned char output[16] )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -330,8 +307,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 );
@@ -339,10 +316,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 );
 }
@@ -352,7 +329,7 @@
 /*
  * output = MD5( input buffer )
  */
-int mbedtls_md5_ret( const unsigned char *input,
+int mbedtls_md5( const unsigned char *input,
                      size_t ilen,
                      unsigned char output[16] )
 {
@@ -361,13 +338,13 @@
 
     mbedtls_md5_init( &ctx );
 
-    if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 )
+    if( ( ret = mbedtls_md5_starts( &ctx ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 )
+    if( ( ret = mbedtls_md5_update( &ctx, input, ilen ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 )
+    if( ( ret = mbedtls_md5_finish( &ctx, output ) ) != 0 )
         goto exit;
 
 exit:
@@ -427,7 +404,7 @@
         if( verbose != 0 )
             mbedtls_printf( "  MD5 test #%d: ", i + 1 );
 
-        ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum );
+        ret = mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
         if( ret != 0 )
             goto fail;
 
diff --git a/library/md_wrap.h b/library/md_wrap.h
index 51655f9..90c7957 100644
--- a/library/md_wrap.h
+++ b/library/md_wrap.h
@@ -26,11 +26,7 @@
 #ifndef MBEDTLS_MD_WRAP_H
 #define MBEDTLS_MD_WRAP_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/md.h"
 
@@ -57,12 +53,6 @@
     unsigned char block_size;
 };
 
-#if defined(MBEDTLS_MD2_C)
-extern const mbedtls_md_info_t mbedtls_md2_info;
-#endif
-#if defined(MBEDTLS_MD4_C)
-extern const mbedtls_md_info_t mbedtls_md4_info;
-#endif
 #if defined(MBEDTLS_MD5_C)
 extern const mbedtls_md_info_t mbedtls_md5_info;
 #endif
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 8f79b74..17a9e4a 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -18,7 +18,7 @@
  */
 
 /* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
- * be set before config.h, which pulls in glibc's features.h indirectly.
+ * be set before mbedtls_config.h, which pulls in glibc's features.h indirectly.
  * Harmless on other platforms. */
 #ifndef _POSIX_C_SOURCE
 #define _POSIX_C_SOURCE 200112L
@@ -34,7 +34,7 @@
 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
     !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
     !defined(__HAIKU__) && !defined(__midipix__)
-#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
+#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in mbedtls_config.h"
 #endif
 
 #if defined(MBEDTLS_PLATFORM_C)
@@ -136,6 +136,31 @@
 }
 
 /*
+ * Return 0 if the file descriptor is valid, an error otherwise.
+ * If for_select != 0, check whether the file descriptor is within the range
+ * allowed for fd_set used for the FD_xxx macros and the select() function.
+ */
+static int check_fd( int fd, int for_select )
+{
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
+    !defined(EFI32)
+    (void) for_select;
+#else
+    /* A limitation of select() is that it only works with file descriptors
+     * that are strictly less than FD_SETSIZE. This is a limitation of the
+     * fd_set type. Error out early, because attempting to call FD_SET on a
+     * large file descriptor is a buffer overflow on typical platforms. */
+    if( for_select && fd >= FD_SETSIZE )
+        return( MBEDTLS_ERR_NET_POLL_FAILED );
+#endif
+
+    return( 0 );
+}
+
+/*
  * Initialize a context
  */
 void mbedtls_net_init( mbedtls_net_context *ctx )
@@ -466,15 +491,9 @@
 
     int fd = ctx->fd;
 
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
-
-    /* A limitation of select() is that it only works with file descriptors
-     * that are strictly less than FD_SETSIZE. This is a limitation of the
-     * fd_set type. Error out early, because attempting to call FD_SET on a
-     * large file descriptor is a buffer overflow on typical platforms. */
-    if( fd >= FD_SETSIZE )
-        return( MBEDTLS_ERR_NET_POLL_FAILED );
+    ret = check_fd( fd, 1 );
+    if( ret != 0 )
+        return( ret );
 
 #if defined(__has_feature)
 #if __has_feature(memory_sanitizer)
@@ -553,8 +572,9 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     int fd = ((mbedtls_net_context *) ctx)->fd;
 
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    ret = check_fd( fd, 0 );
+    if( ret != 0 )
+        return( ret );
 
     ret = (int) read( fd, buf, len );
 
@@ -592,15 +612,9 @@
     fd_set read_fds;
     int fd = ((mbedtls_net_context *) ctx)->fd;
 
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
-
-    /* A limitation of select() is that it only works with file descriptors
-     * that are strictly less than FD_SETSIZE. This is a limitation of the
-     * fd_set type. Error out early, because attempting to call FD_SET on a
-     * large file descriptor is a buffer overflow on typical platforms. */
-    if( fd >= FD_SETSIZE )
-        return( MBEDTLS_ERR_NET_POLL_FAILED );
+    ret = check_fd( fd, 1 );
+    if( ret != 0 )
+        return( ret );
 
     FD_ZERO( &read_fds );
     FD_SET( fd, &read_fds );
@@ -640,8 +654,9 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     int fd = ((mbedtls_net_context *) ctx)->fd;
 
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    ret = check_fd( fd, 0 );
+    if( ret != 0 )
+        return( ret );
 
     ret = (int) write( fd, buf, len );
 
diff --git a/library/nist_kw.c b/library/nist_kw.c
index 5054ca2..e2ab256 100644
--- a/library/nist_kw.c
+++ b/library/nist_kw.c
@@ -77,26 +77,6 @@
 /*! 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 +223,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 );
@@ -474,7 +454,7 @@
             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/library/oid.c b/library/oid.c
index c4a4df9..f70ceea 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -340,18 +340,6 @@
 static const oid_sig_alg_t oid_sig_alg[] =
 {
 #if defined(MBEDTLS_RSA_C)
-#if defined(MBEDTLS_MD2_C)
-    {
-        OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD2,        "md2WithRSAEncryption",     "RSA with MD2" ),
-        MBEDTLS_MD_MD2,      MBEDTLS_PK_RSA,
-    },
-#endif /* MBEDTLS_MD2_C */
-#if defined(MBEDTLS_MD4_C)
-    {
-        OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD4,        "md4WithRSAEncryption",     "RSA with MD4" ),
-        MBEDTLS_MD_MD4,      MBEDTLS_PK_RSA,
-    },
-#endif /* MBEDTLS_MD4_C */
 #if defined(MBEDTLS_MD5_C)
     {
         OID_DESCRIPTOR( MBEDTLS_OID_PKCS1_MD5,        "md5WithRSAEncryption",     "RSA with MD5" ),
@@ -609,18 +597,6 @@
 
 static const oid_md_alg_t oid_md_alg[] =
 {
-#if defined(MBEDTLS_MD2_C)
-    {
-        OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD2,       "id-md2",       "MD2" ),
-        MBEDTLS_MD_MD2,
-    },
-#endif /* MBEDTLS_MD2_C */
-#if defined(MBEDTLS_MD4_C)
-    {
-        OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD4,       "id-md4",       "MD4" ),
-        MBEDTLS_MD_MD4,
-    },
-#endif /* MBEDTLS_MD4_C */
 #if defined(MBEDTLS_MD5_C)
     {
         OID_DESCRIPTOR( MBEDTLS_OID_DIGEST_ALG_MD5,       "id-md5",       "MD5" ),
diff --git a/library/padlock.h b/library/padlock.h
index 4f4e400..1506ee0 100644
--- a/library/padlock.h
+++ b/library/padlock.h
@@ -26,11 +26,7 @@
 #ifndef MBEDTLS_PADLOCK_H
 #define MBEDTLS_PADLOCK_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/aes.h"
 
diff --git a/library/pem.c b/library/pem.c
index fcfde94..1b40e5e 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -87,13 +87,13 @@
     /*
      * key[ 0..15] = MD5(pwd || IV)
      */
-    if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
+    if( ( ret = mbedtls_md5_starts( &md5_ctx ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
+    if( ( ret = mbedtls_md5_update( &md5_ctx, pwd, pwdlen ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv,  8 ) ) != 0 )
+    if( ( ret = mbedtls_md5_update( &md5_ctx, iv,  8 ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
+    if( ( ret = mbedtls_md5_finish( &md5_ctx, md5sum ) ) != 0 )
         goto exit;
 
     if( keylen <= 16 )
@@ -107,15 +107,15 @@
     /*
      * key[16..23] = MD5(key[ 0..15] || pwd || IV])
      */
-    if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
+    if( ( ret = mbedtls_md5_starts( &md5_ctx ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, md5sum, 16 ) ) != 0 )
+    if( ( ret = mbedtls_md5_update( &md5_ctx, md5sum, 16 ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
+    if( ( ret = mbedtls_md5_update( &md5_ctx, pwd, pwdlen ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 )
+    if( ( ret = mbedtls_md5_update( &md5_ctx, iv, 8 ) ) != 0 )
         goto exit;
-    if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
+    if( ( ret = mbedtls_md5_finish( &md5_ctx, md5sum ) ) != 0 )
         goto exit;
 
     use_len = 16;
diff --git a/library/pk.c b/library/pk.c
index 06021e2..ea4869c 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -396,7 +396,7 @@
 int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
              mbedtls_md_type_t md_alg,
              const unsigned char *hash, size_t hash_len,
-             unsigned char *sig, size_t *sig_len,
+             unsigned char *sig, size_t sig_size, size_t *sig_len,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
              mbedtls_pk_restart_ctx *rs_ctx )
 {
@@ -421,7 +421,9 @@
             return( ret );
 
         ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
-                hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
+                                          hash, hash_len,
+                                          sig, sig_size, sig_len,
+                                          f_rng, p_rng, rs_ctx->rs_ctx );
 
         if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
             mbedtls_pk_restart_free( rs_ctx );
@@ -435,8 +437,10 @@
     if( ctx->pk_info->sign_func == NULL )
         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
 
-    return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
-                                     sig, sig_len, f_rng, p_rng ) );
+    return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg,
+                                     hash, hash_len,
+                                     sig, sig_size, sig_len,
+                                     f_rng, p_rng ) );
 }
 
 /*
@@ -444,11 +448,12 @@
  */
 int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
              const unsigned char *hash, size_t hash_len,
-             unsigned char *sig, size_t *sig_len,
+             unsigned char *sig, size_t sig_size, size_t *sig_len,
              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
-                                         sig, sig_len, f_rng, p_rng, NULL ) );
+                                         sig, sig_size, sig_len,
+                                         f_rng, p_rng, NULL ) );
 }
 
 /*
@@ -500,7 +505,10 @@
 /*
  * Check public-private key pair
  */
-int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
+int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
+                           const mbedtls_pk_context *prv,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng )
 {
     PK_VALIDATE_RET( pub != NULL );
     PK_VALIDATE_RET( prv != NULL );
@@ -511,6 +519,9 @@
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
     }
 
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
     if( prv->pk_info->check_pair_func == NULL )
         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
 
@@ -525,7 +536,7 @@
             return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
     }
 
-    return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
+    return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx, f_rng, p_rng ) );
 }
 
 /*
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index c351113..80c0aad 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -108,7 +108,7 @@
 
 static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
@@ -119,6 +119,8 @@
 #endif /* SIZE_MAX > UINT_MAX */
 
     *sig_len = mbedtls_rsa_get_len( rsa );
+    if( sig_size < *sig_len )
+        return( MBEDTLS_ERR_PK_BUFFER_TOO_SMALL );
 
     return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng,
                                     md_alg, (unsigned int) hash_len,
@@ -154,8 +156,12 @@
                                        ilen, input, output ) );
 }
 
-static int rsa_check_pair_wrap( const void *pub, const void *prv )
+static int rsa_check_pair_wrap( const void *pub, const void *prv,
+                                int (*f_rng)(void *, unsigned char *, size_t),
+                                void *p_rng )
 {
+    (void) f_rng;
+    (void) p_rng;
     return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
                                 (const mbedtls_rsa_context *) prv ) );
 }
@@ -165,7 +171,7 @@
     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
 
     if( ctx != NULL )
-        mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
+        mbedtls_rsa_init( (mbedtls_rsa_context *) ctx );
 
     return( ctx );
 }
@@ -178,6 +184,11 @@
 
 static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
 {
+#if defined(MBEDTLS_RSA_ALT)
+    /* Not supported */
+    (void) ctx;
+    (void) items;
+#else
     items->type = MBEDTLS_PK_DEBUG_MPI;
     items->name = "rsa.N";
     items->value = &( ((mbedtls_rsa_context *) ctx)->N );
@@ -187,6 +198,7 @@
     items->type = MBEDTLS_PK_DEBUG_MPI;
     items->name = "rsa.E";
     items->value = &( ((mbedtls_rsa_context *) ctx)->E );
+#endif
 }
 
 const mbedtls_pk_info_t mbedtls_rsa_info = {
@@ -237,7 +249,7 @@
 
 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
@@ -259,7 +271,7 @@
 
 static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -268,7 +280,8 @@
     mbedtls_ecdsa_init( &ecdsa );
 
     if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
-        ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
+        ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len,
+                               sig, sig_size, sig_len,
                                f_rng, p_rng );
 
     mbedtls_ecdsa_free( &ecdsa );
@@ -285,7 +298,7 @@
 
 static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
                    void *rs_ctx );
 
@@ -357,7 +370,7 @@
 
 static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
                        void *rs_ctx )
 {
@@ -373,7 +386,7 @@
         MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
 
     MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,
-                                         hash, hash_len, sig, sig_len,
+                                         hash, hash_len, sig, sig_size, sig_len,
                                          f_rng, p_rng, &rs->ecdsa_rs ) );
 
 cleanup:
@@ -382,10 +395,13 @@
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 #endif /* MBEDTLS_ECDSA_C */
 
-static int eckey_check_pair( const void *pub, const void *prv )
+static int eckey_check_pair( const void *pub, const void *prv,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng )
 {
     return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
-                                (const mbedtls_ecp_keypair *) prv ) );
+                                (const mbedtls_ecp_keypair *) prv,
+                                f_rng, p_rng ) );
 }
 
 static void *eckey_alloc_wrap( void )
@@ -639,11 +655,13 @@
 
 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
-                md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
+                                           md_alg, hash, hash_len,
+                                           sig, sig_size, sig_len,
+                                           f_rng, p_rng ) );
 }
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -668,13 +686,13 @@
 
 static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
                    void *rs_ctx )
 {
     return( mbedtls_ecdsa_write_signature_restartable(
                 (mbedtls_ecdsa_context *) ctx,
-                md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
+                md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng,
                 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
 
 }
@@ -757,7 +775,7 @@
 
 static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
@@ -770,6 +788,8 @@
     *sig_len = rsa_alt->key_len_func( rsa_alt->key );
     if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+    if( *sig_len > sig_size )
+        return( MBEDTLS_ERR_PK_BUFFER_TOO_SMALL );
 
     return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng,
                 md_alg, (unsigned int) hash_len, hash, sig ) );
@@ -793,7 +813,9 @@
 }
 
 #if defined(MBEDTLS_RSA_C)
-static int rsa_alt_check_pair( const void *pub, const void *prv )
+static int rsa_alt_check_pair( const void *pub, const void *prv,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng )
 {
     unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
     unsigned char hash[32];
@@ -807,7 +829,8 @@
 
     if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
                                    hash, sizeof( hash ),
-                                   sig, &sig_len, NULL, NULL ) ) != 0 )
+                                   sig, sizeof( sig ), &sig_len,
+                                   f_rng, p_rng ) ) != 0 )
     {
         return( ret );
     }
@@ -995,7 +1018,7 @@
 
 static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                    const unsigned char *hash, size_t hash_len,
-                   unsigned char *sig, size_t *sig_len,
+                   unsigned char *sig, size_t sig_size, size_t *sig_len,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
 #if !defined(MBEDTLS_ECDSA_C)
@@ -1004,41 +1027,28 @@
     ((void) hash);
     ((void) hash_len);
     ((void) sig);
+    ((void) sig_size);
     ((void) sig_len);
     ((void) f_rng);
     ((void) p_rng);
     return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
 #else /* !MBEDTLS_ECDSA_C */
     const psa_key_id_t *key = (const psa_key_id_t *) ctx;
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
-    size_t buf_len;
     psa_status_t status;
 
     /* PSA has its own RNG */
     (void) f_rng;
     (void) p_rng;
 
-    /* PSA needs an output buffer of known size, but our API doesn't provide
-     * that information. Assume that the buffer is large enough for a
-     * maximal-length signature with that key (otherwise the application is
-     * buggy anyway). */
-    status = psa_get_key_attributes( *key, &attributes );
-    if( status != PSA_SUCCESS )
-        return( mbedtls_psa_err_translate_pk( status ) );
-    buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( psa_get_key_bits( &attributes ) );
-    psa_reset_key_attributes( &attributes );
-    if( buf_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )
-        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
-
     /* make the signature */
     status = psa_sign_hash( *key, alg, hash, hash_len,
-                            sig, buf_len, sig_len );
+                            sig, sig_size, sig_len );
     if( status != PSA_SUCCESS )
         return( mbedtls_psa_err_translate_pk( status ) );
 
     /* transcode it to ASN.1 sequence */
-    return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) );
+    return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, sig_size ) );
 #endif /* !MBEDTLS_ECDSA_C */
 }
 
diff --git a/library/pk_wrap.h b/library/pk_wrap.h
index f7f938a..6f5addf 100644
--- a/library/pk_wrap.h
+++ b/library/pk_wrap.h
@@ -23,11 +23,7 @@
 #ifndef MBEDTLS_PK_WRAP_H
 #define MBEDTLS_PK_WRAP_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/pk.h"
 
@@ -53,7 +49,7 @@
     /** Make signature */
     int (*sign_func)( void *ctx, mbedtls_md_type_t md_alg,
                       const unsigned char *hash, size_t hash_len,
-                      unsigned char *sig, size_t *sig_len,
+                      unsigned char *sig, size_t sig_size, size_t *sig_len,
                       int (*f_rng)(void *, unsigned char *, size_t),
                       void *p_rng );
 
@@ -67,7 +63,7 @@
     /** Make signature (restartable) */
     int (*sign_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
                          const unsigned char *hash, size_t hash_len,
-                         unsigned char *sig, size_t *sig_len,
+                         unsigned char *sig, size_t sig_size, size_t *sig_len,
                          int (*f_rng)(void *, unsigned char *, size_t),
                          void *p_rng, void *rs_ctx );
 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
@@ -85,7 +81,9 @@
                          void *p_rng );
 
     /** Check public-private key pair */
-    int (*check_pair_func)( const void *pub, const void *prv );
+    int (*check_pair_func)( const void *pub, const void *prv,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng );
 
     /** Allocate a new context */
     void * (*ctx_alloc_func)( void );
diff --git a/library/pkcs12.c b/library/pkcs12.c
index 9823d96..8f64bc6 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -35,10 +35,6 @@
 
 #include <string.h>
 
-#if defined(MBEDTLS_ARC4_C)
-#include "mbedtls/arc4.h"
-#endif
-
 #if defined(MBEDTLS_DES_C)
 #include "mbedtls/des.h"
 #endif
@@ -125,47 +121,6 @@
 
 #undef PKCS12_MAX_PWDLEN
 
-int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
-                             const unsigned char *pwd,  size_t pwdlen,
-                             const unsigned char *data, size_t len,
-                             unsigned char *output )
-{
-#if !defined(MBEDTLS_ARC4_C)
-    ((void) pbe_params);
-    ((void) mode);
-    ((void) pwd);
-    ((void) pwdlen);
-    ((void) data);
-    ((void) len);
-    ((void) output);
-    return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
-#else
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    unsigned char key[16];
-    mbedtls_arc4_context ctx;
-    ((void) mode);
-
-    mbedtls_arc4_init( &ctx );
-
-    if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1,
-                                          pwd, pwdlen,
-                                          key, 16, NULL, 0 ) ) != 0 )
-    {
-        return( ret );
-    }
-
-    mbedtls_arc4_setup( &ctx, key, 16 );
-    if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 )
-        goto exit;
-
-exit:
-    mbedtls_platform_zeroize( key, sizeof( key ) );
-    mbedtls_arc4_free( &ctx );
-
-    return( ret );
-#endif /* MBEDTLS_ARC4_C */
-}
-
 int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
                 mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
                 const unsigned char *pwd,  size_t pwdlen,
@@ -330,8 +285,8 @@
         for( i = v; i > 0; i-- )
         {
             j = salt_block[i - 1] + hash_block[i - 1] + c;
-            c = (unsigned char) (j >> 8);
-            salt_block[i - 1] = j & 0xFF;
+            c = MBEDTLS_BYTE_1( j );
+            salt_block[i - 1] = MBEDTLS_BYTE_0( j );
         }
 
         // pwd_block  += B
@@ -339,8 +294,8 @@
         for( i = v; i > 0; i-- )
         {
             j = pwd_block[i - 1] + hash_block[i - 1] + c;
-            c = (unsigned char) (j >> 8);
-            pwd_block[i - 1] = j & 0xFF;
+            c = MBEDTLS_BYTE_1( j );
+            pwd_block[i - 1] = MBEDTLS_BYTE_0( j );
         }
     }
 
diff --git a/library/pkparse.c b/library/pkparse.c
index 3222ca2..b2d3bb0 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -123,7 +123,8 @@
  * Load and parse a private key
  */
 int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
-                      const char *path, const char *pwd )
+        const char *path, const char *pwd,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
@@ -136,10 +137,10 @@
         return( ret );
 
     if( pwd == NULL )
-        ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 );
+        ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0, f_rng, p_rng );
     else
         ret = mbedtls_pk_parse_key( ctx, buf, n,
-                (const unsigned char *) pwd, strlen( pwd ) );
+                (const unsigned char *) pwd, strlen( pwd ), f_rng, p_rng );
 
     mbedtls_platform_zeroize( buf, n );
     mbedtls_free( buf );
@@ -859,8 +860,8 @@
  * Parse a SEC1 encoded private EC key
  */
 static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
-                                  const unsigned char *key,
-                                  size_t keylen )
+        const unsigned char *key, size_t keylen,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     int version, pubkey_done;
@@ -967,7 +968,7 @@
 
     if( ! pubkey_done &&
         ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
-                                                      NULL, NULL ) ) != 0 )
+                                 f_rng, p_rng ) ) != 0 )
     {
         mbedtls_ecp_keypair_free( eck );
         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
@@ -997,9 +998,9 @@
  *
  */
 static int pk_parse_key_pkcs8_unencrypted_der(
-                                    mbedtls_pk_context *pk,
-                                    const unsigned char* key,
-                                    size_t keylen )
+        mbedtls_pk_context *pk,
+        const unsigned char* key, size_t keylen,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret, version;
     size_t len;
@@ -1009,6 +1010,11 @@
     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
     const mbedtls_pk_info_t *pk_info;
 
+#if !defined(MBEDTLS_ECP_C)
+    (void) f_rng;
+    (void) p_rng;
+#endif
+
     /*
      * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
      *
@@ -1071,7 +1077,7 @@
     if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH )
     {
         if( ( ret = pk_use_ecparams( &params, &mbedtls_pk_ec( *pk )->grp ) ) != 0 ||
-            ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len )  ) != 0 )
+            ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len, f_rng, p_rng ) ) != 0 )
         {
             mbedtls_pk_free( pk );
             return( ret );
@@ -1094,9 +1100,10 @@
  */
 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
 static int pk_parse_key_pkcs8_encrypted_der(
-                                    mbedtls_pk_context *pk,
-                                    unsigned char *key, size_t keylen,
-                                    const unsigned char *pwd, size_t pwdlen )
+        mbedtls_pk_context *pk,
+        unsigned char *key, size_t keylen,
+        const unsigned char *pwd, size_t pwdlen,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret, decrypted = 0;
     size_t len;
@@ -1163,24 +1170,6 @@
 
         decrypted = 1;
     }
-    else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 )
-    {
-        if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params,
-                                             MBEDTLS_PKCS12_PBE_DECRYPT,
-                                             pwd, pwdlen,
-                                             p, len, buf ) ) != 0 )
-        {
-            return( ret );
-        }
-
-        // Best guess for password mismatch when using RC4. If first tag is
-        // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
-        //
-        if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
-            return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
-
-        decrypted = 1;
-    }
     else
 #endif /* MBEDTLS_PKCS12_C */
 #if defined(MBEDTLS_PKCS5_C)
@@ -1206,7 +1195,7 @@
     if( decrypted == 0 )
         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
 
-    return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
+    return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len, f_rng, p_rng ) );
 }
 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
 
@@ -1215,7 +1204,8 @@
  */
 int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
                   const unsigned char *key, size_t keylen,
-                  const unsigned char *pwd, size_t pwdlen )
+                  const unsigned char *pwd, size_t pwdlen,
+                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     const mbedtls_pk_info_t *pk_info;
@@ -1278,7 +1268,8 @@
 
         if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
             ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
-                                           pem.buf, pem.buflen ) ) != 0 )
+                                           pem.buf, pem.buflen,
+                                           f_rng, p_rng ) ) != 0 )
         {
             mbedtls_pk_free( pk );
         }
@@ -1305,7 +1296,7 @@
     if( ret == 0 )
     {
         if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
-                                                pem.buf, pem.buflen ) ) != 0 )
+                        pem.buf, pem.buflen, f_rng, p_rng ) ) != 0 )
         {
             mbedtls_pk_free( pk );
         }
@@ -1327,9 +1318,8 @@
                                key, NULL, 0, &len );
     if( ret == 0 )
     {
-        if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
-                                                      pem.buf, pem.buflen,
-                                                      pwd, pwdlen ) ) != 0 )
+        if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, pem.buf, pem.buflen,
+                        pwd, pwdlen, f_rng, p_rng ) ) != 0 )
         {
             mbedtls_pk_free( pk );
         }
@@ -1362,7 +1352,7 @@
         memcpy( key_copy, key, keylen );
 
         ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
-                                                pwd, pwdlen );
+                                                pwd, pwdlen, f_rng, p_rng );
 
         mbedtls_platform_zeroize( key_copy, keylen );
         mbedtls_free( key_copy );
@@ -1380,8 +1370,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, f_rng, p_rng );
+    if( ret == 0 )
+    {
         return( 0 );
+    }
 
     mbedtls_pk_free( pk );
     mbedtls_pk_init( pk );
@@ -1403,7 +1396,7 @@
     pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
     if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
         pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
-                               key, keylen ) == 0 )
+                               key, keylen, f_rng, p_rng ) == 0 )
     {
         return( 0 );
     }
diff --git a/library/platform_util.c b/library/platform_util.c
index 98fe5de..3d5cb5b 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -20,7 +20,7 @@
 
 /*
  * Ensure gmtime_r is available even with -std=c99; must be defined before
- * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ * mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms.
  */
 #if !defined(_POSIX_C_SOURCE)
 #define _POSIX_C_SOURCE 200112L
@@ -131,3 +131,8 @@
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 }
 #endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */
+
+#if defined(MBEDTLS_TEST_HOOKS)
+void (*mbedtls_test_hook_test_fail)( const char *, int, const char *);
+#endif /* MBEDTLS_TEST_HOOKS */
+
diff --git a/library/poly1305.c b/library/poly1305.c
index 492d145..7375a0c 100644
--- a/library/poly1305.c
+++ b/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/library/psa_crypto.c b/library/psa_crypto.c
index a954d86..83b45f0 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -26,7 +26,6 @@
 #include "check_crypto_config.h"
 #endif
 
-#include "psa_crypto_service_integration.h"
 #include "psa/crypto.h"
 
 #include "psa_crypto_cipher.h"
@@ -58,11 +57,9 @@
 #endif
 
 #include "mbedtls/aes.h"
-#include "mbedtls/arc4.h"
 #include "mbedtls/asn1.h"
 #include "mbedtls/asn1write.h"
 #include "mbedtls/bignum.h"
-#include "mbedtls/blowfish.h"
 #include "mbedtls/camellia.h"
 #include "mbedtls/chacha20.h"
 #include "mbedtls/chachapoly.h"
@@ -75,8 +72,6 @@
 #include "mbedtls/entropy.h"
 #include "mbedtls/error.h"
 #include "mbedtls/gcm.h"
-#include "mbedtls/md2.h"
-#include "mbedtls/md4.h"
 #include "mbedtls/md5.h"
 #include "mbedtls/md.h"
 #include "md_wrap.h"
@@ -89,7 +84,6 @@
 #include "mbedtls/sha1.h"
 #include "mbedtls/sha256.h"
 #include "mbedtls/sha512.h"
-#include "mbedtls/xtea.h"
 
 #define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
 
@@ -150,12 +144,6 @@
         case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
             return( PSA_ERROR_BUFFER_TOO_SMALL );
 
-#if defined(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA)
-        case MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA:
-#endif
-        case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
-            return( PSA_ERROR_NOT_SUPPORTED );
-
 #if defined(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
         case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA:
 #endif
@@ -278,6 +266,8 @@
             return( PSA_ERROR_NOT_SUPPORTED );
         case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
             return( PSA_ERROR_INVALID_SIGNATURE );
+        case MBEDTLS_ERR_PK_BUFFER_TOO_SMALL:
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
 
         case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED:
             return( PSA_ERROR_HARDWARE_FAILURE );
@@ -302,9 +292,6 @@
         case MBEDTLS_ERR_RSA_RNG_FAILED:
             return( PSA_ERROR_INSUFFICIENT_ENTROPY );
 
-        case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
-            return( PSA_ERROR_INVALID_ARGUMENT );
-
         case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
         case MBEDTLS_ERR_ECP_INVALID_KEY:
             return( PSA_ERROR_INVALID_ARGUMENT );
@@ -335,13 +322,6 @@
 /* Key management */
 /****************************************************************/
 
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-static inline int psa_key_slot_is_external( const psa_key_slot_t *slot )
-{
-    return( psa_key_lifetime_is_external( slot->attr.lifetime ) );
-}
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
-
 /* For now the MBEDTLS_PSA_ACCEL_ guards are also used here since the
  * current test driver in key_management.c is using this function
  * when accelerators are used for ECC key pair and public key.
@@ -450,8 +430,8 @@
         * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) ||
         * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
 
-static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type,
-                                                        size_t bits )
+psa_status_t psa_validate_unstructured_key_bit_size( psa_key_type_t type,
+                                                     size_t bits )
 {
     /* Check that the bit size is acceptable for the key type */
     switch( type )
@@ -478,12 +458,6 @@
                 return( PSA_ERROR_INVALID_ARGUMENT );
             break;
 #endif
-#if defined(PSA_WANT_KEY_TYPE_ARC4)
-        case PSA_KEY_TYPE_ARC4:
-            if( bits < 8 || bits > 2048 )
-                return( PSA_ERROR_INVALID_ARGUMENT );
-            break;
-#endif
 #if defined(PSA_WANT_KEY_TYPE_CHACHA20)
         case PSA_KEY_TYPE_CHACHA20:
             if( bits != 256 )
@@ -584,16 +558,8 @@
     {
         *bits = PSA_BYTES_TO_BITS( data_length );
 
-        /* Ensure that the bytes-to-bits conversion hasn't overflown. */
-        if( data_length > SIZE_MAX / 8 )
-            return( PSA_ERROR_NOT_SUPPORTED );
-
-        /* Enforce a size limit, and in particular ensure that the bit
-         * size fits in its representation type. */
-        if( ( *bits ) > PSA_MAX_KEY_BITS )
-            return( PSA_ERROR_NOT_SUPPORTED );
-
-        status = validate_unstructured_key_bit_size( type, *bits );
+        status = psa_validate_unstructured_key_bit_size( attributes->core.type,
+                                                         *bits );
         if( status != PSA_SUCCESS )
             return( status );
 
@@ -963,16 +929,16 @@
 /** Get a key slot containing a transparent key and lock it.
  *
  * A transparent key is a key for which the key material is directly
- * available, as opposed to a key in a secure element.
+ * available, as opposed to a key in a secure element and/or to be used
+ * by a secure element.
  *
- * This is a temporary function to use instead of
- * psa_get_and_lock_key_slot_with_policy() until secure element support is
- * fully implemented.
+ * This is a temporary function that may be used instead of
+ * psa_get_and_lock_key_slot_with_policy() when there is no opaque key support
+ * for a cryptographic operation.
  *
  * On success, the returned key slot is locked. It is the responsibility of the
  * caller to unlock the key slot when it does not access it anymore.
  */
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
 static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
     mbedtls_svc_key_id_t key,
     psa_key_slot_t **p_slot,
@@ -984,7 +950,7 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    if( psa_key_slot_is_external( *p_slot ) )
+    if( psa_key_lifetime_is_external( (*p_slot)->attr.lifetime ) )
     {
         psa_unlock_key_slot( *p_slot );
         *p_slot = NULL;
@@ -993,11 +959,6 @@
 
     return( PSA_SUCCESS );
 }
-#else /* MBEDTLS_PSA_CRYPTO_SE_C */
-/* With no secure element support, all keys are transparent. */
-#define psa_get_and_lock_transparent_key_slot_with_policy( key, p_slot, usage, alg )   \
-    psa_get_and_lock_key_slot_with_policy( key, p_slot, usage, alg )
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
 psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
 {
@@ -1019,18 +980,17 @@
 {
     psa_status_t status = psa_remove_key_data_from_memory( slot );
 
-    /*
-     * As the return error code may not be handled in case of multiple errors,
-     * do our best to report an unexpected lock counter: if available
-     * call MBEDTLS_PARAM_FAILED that may terminate execution (if called as
-     * part of the execution of a test suite this will stop the test suite
-     * execution).
-     */
+   /*
+    * As the return error code may not be handled in case of multiple errors,
+    * do our best to report an unexpected lock counter. Assert with
+    * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is equal to one:
+    * if the MBEDTLS_TEST_HOOKS configuration option is enabled and the
+    * function is called as part of the execution of a test suite, the
+    * execution of the test suite is stopped in error if the assertion fails.
+    */
     if( slot->lock_count != 1 )
     {
-#ifdef MBEDTLS_CHECK_PARAMS
-        MBEDTLS_PARAM_FAILED( slot->lock_count == 1 );
-#endif
+        MBEDTLS_TEST_HOOK_TEST_ASSERT( slot->lock_count == 1 );
         status = PSA_ERROR_CORRUPTION_DETECTED;
     }
 
@@ -1082,6 +1042,17 @@
        return( PSA_ERROR_GENERIC_ERROR );
     }
 
+    if( PSA_KEY_LIFETIME_IS_READ_ONLY( slot->attr.lifetime ) )
+    {
+        /* Refuse the destruction of a read-only key (which may or may not work
+         * if we attempt it, depending on whether the key is merely read-only
+         * by policy or actually physically read-only).
+         * Just do the best we can, which is to wipe the copy in memory
+         * (done in this function's cleanup code). */
+        overall_status = PSA_ERROR_NOT_PERMITTED;
+        goto exit;
+    }
+
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     driver = psa_get_se_driver_entry( slot->attr.lifetime );
     if( driver != NULL )
@@ -1143,12 +1114,10 @@
     }
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
 exit:
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
     status = psa_wipe_key_slot( slot );
     /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */
-    if( overall_status == PSA_SUCCESS )
+    if( status != PSA_SUCCESS )
         overall_status = status;
     return( overall_status );
 }
@@ -1217,7 +1186,7 @@
                                 MBEDTLS_PSA_KA_MASK_DUAL_USE );
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-    if( psa_key_slot_is_external( slot ) )
+    if( psa_get_se_driver_entry( slot->attr.lifetime ) != NULL )
         psa_set_key_slot_number( attributes,
                                  psa_key_slot_get_slot_number( slot ) );
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
@@ -1228,14 +1197,11 @@
     defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
         case PSA_KEY_TYPE_RSA_KEY_PAIR:
         case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
             /* TODO: reporting the public exponent for opaque keys
              * is not yet implemented.
              * https://github.com/ARMmbed/mbed-crypto/issues/216
              */
-            if( psa_key_slot_is_external( slot ) )
-                break;
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+            if( ! psa_key_lifetime_is_external( slot->attr.lifetime ) )
             {
                 mbedtls_rsa_context *rsa = NULL;
 
@@ -1917,6 +1883,7 @@
     psa_key_slot_t *slot = NULL;
     psa_se_drv_table_entry_t *driver = NULL;
     size_t bits;
+    size_t storage_size = data_length;
 
     *key = MBEDTLS_SVC_KEY_ID_INIT;
 
@@ -1926,18 +1893,29 @@
     if( data_length == 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
+    /* Ensure that the bytes-to-bits conversion cannot overflow. */
+    if( data_length > SIZE_MAX / 8 )
+        return( PSA_ERROR_NOT_SUPPORTED );
+
     status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes,
                                      &slot, &driver );
     if( status != PSA_SUCCESS )
         goto exit;
 
     /* In the case of a transparent key or an opaque key stored in local
-     * storage (thus not in the case of generating a key in a secure element
-     * or cryptoprocessor with storage), we have to allocate a buffer to
-     * hold the generated key material. */
+     * storage ( thus not in the case of importing a key in a secure element
+     * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
+     * buffer to hold the imported key material. */
     if( slot->key.data == NULL )
     {
-        status = psa_allocate_buffer_to_slot( slot, data_length );
+        if( psa_key_lifetime_is_external( attributes->core.lifetime ) )
+        {
+            status = psa_driver_wrapper_get_key_buffer_size_from_key_data(
+                         attributes, data, data_length, &storage_size );
+            if( status != PSA_SUCCESS )
+                goto exit;
+        }
+        status = psa_allocate_buffer_to_slot( slot, storage_size );
         if( status != PSA_SUCCESS )
             goto exit;
     }
@@ -1959,6 +1937,13 @@
         goto exit;
     }
 
+    /* Enforce a size limit, and in particular ensure that the bit
+     * size fits in its representation type.*/
+    if( bits > PSA_MAX_KEY_BITS )
+    {
+        status = PSA_ERROR_NOT_SUPPORTED;
+        goto exit;
+    }
     status = psa_validate_optional_attributes( slot, attributes );
     if( status != PSA_SUCCESS )
         goto exit;
@@ -2006,21 +1991,6 @@
 }
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
-static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
-                                           psa_key_slot_t *target )
-{
-    psa_status_t status = psa_copy_key_material_into_slot( target,
-                                                           source->key.data,
-                                                           source->key.bytes );
-    if( status != PSA_SUCCESS )
-        return( status );
-
-    target->attr.type = source->attr.type;
-    target->attr.bits = source->attr.bits;
-
-    return( PSA_SUCCESS );
-}
-
 psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key,
                            const psa_key_attributes_t *specified_attributes,
                            mbedtls_svc_key_id_t *target_key )
@@ -2031,10 +2001,11 @@
     psa_key_slot_t *target_slot = NULL;
     psa_key_attributes_t actual_attributes = *specified_attributes;
     psa_se_drv_table_entry_t *driver = NULL;
+    size_t storage_size = 0;
 
     *target_key = MBEDTLS_SVC_KEY_ID_INIT;
 
-    status = psa_get_and_lock_transparent_key_slot_with_policy(
+    status = psa_get_and_lock_key_slot_with_policy(
                  source_key, &source_slot, PSA_KEY_USAGE_COPY, 0 );
     if( status != PSA_SUCCESS )
         goto exit;
@@ -2044,6 +2015,15 @@
     if( status != PSA_SUCCESS )
         goto exit;
 
+    /* The target key type and number of bits have been validated by
+     * psa_validate_optional_attributes() to be either equal to zero or
+     * equal to the ones of the source key. So it is safe to inherit
+     * them from the source key now."
+     * */
+    actual_attributes.core.bits = source_slot->attr.bits;
+    actual_attributes.core.type = source_slot->attr.type;
+
+
     status = psa_restrict_key_policy( source_slot->attr.type,
                                       &actual_attributes.core.policy,
                                       &source_slot->attr.policy );
@@ -2054,31 +2034,53 @@
                                      &target_slot, &driver );
     if( status != PSA_SUCCESS )
         goto exit;
-
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-    if( driver != NULL )
+    if( PSA_KEY_LIFETIME_GET_LOCATION( target_slot->attr.lifetime ) !=
+        PSA_KEY_LIFETIME_GET_LOCATION( source_slot->attr.lifetime ) )
     {
-        /* Copying to a secure element is not implemented yet. */
+        /*
+         * If the source and target keys are stored in different locations,
+         * the source key would need to be exported as plaintext and re-imported
+         * in the other location. This has security implications which have not
+         * been fully mapped. For now, this can be achieved through
+         * appropriate API invocations from the application, if needed.
+         * */
         status = PSA_ERROR_NOT_SUPPORTED;
         goto exit;
     }
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
-
+    /*
+     * When the source and target keys are within the same location,
+     * - For transparent keys it is a blind copy without any driver invocation,
+     * - For opaque keys this translates to an invocation of the drivers'
+     *   copy_key entry point through the dispatch layer.
+     * */
     if( psa_key_lifetime_is_external( actual_attributes.core.lifetime ) )
     {
-        /*
-         * Copying through an opaque driver is not implemented yet, consider
-         * a lifetime with an external location as an invalid parameter for
-         * now.
-         */
-        status = PSA_ERROR_INVALID_ARGUMENT;
-        goto exit;
+        status = psa_driver_wrapper_get_key_buffer_size( &actual_attributes,
+                                                         &storage_size );
+        if( status != PSA_SUCCESS )
+            goto exit;
+
+        status = psa_allocate_buffer_to_slot( target_slot, storage_size );
+        if( status != PSA_SUCCESS )
+            goto exit;
+
+        status = psa_driver_wrapper_copy_key( &actual_attributes,
+                                              source_slot->key.data,
+                                              source_slot->key.bytes,
+                                              target_slot->key.data,
+                                              target_slot->key.bytes,
+                                              &target_slot->key.bytes );
+        if( status != PSA_SUCCESS )
+            goto exit;
     }
-
-    status = psa_copy_key_material( source_slot, target_slot );
-    if( status != PSA_SUCCESS )
-        goto exit;
-
+    else
+    {
+       status = psa_copy_key_material_into_slot( target_slot,
+                                                 source_slot->key.data,
+                                                 source_slot->key.bytes );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
     status = psa_finish_key_creation( target_slot, driver, target_key );
 exit:
     if( status != PSA_SUCCESS )
@@ -2110,34 +2112,54 @@
 psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
                              psa_algorithm_t alg )
 {
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
     /* A context must be freshly initialized before it can be set up. */
     if( operation->id != 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( !PSA_ALG_IS_HASH( alg ) )
-        return( PSA_ERROR_INVALID_ARGUMENT );
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
 
     /* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
      * directly zeroes the int-sized dummy member of the context union. */
     memset( &operation->ctx, 0, sizeof( operation->ctx ) );
 
-    return( psa_driver_wrapper_hash_setup( operation, alg ) );
+    status = psa_driver_wrapper_hash_setup( operation, alg );
+
+exit:
+    if( status != PSA_SUCCESS )
+        psa_hash_abort( operation );
+
+    return status;
 }
 
 psa_status_t psa_hash_update( psa_hash_operation_t *operation,
                               const uint8_t *input,
                               size_t input_length )
 {
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
     if( operation->id == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     /* Don't require hash implementations to behave correctly on a
      * zero-length input, which may have an invalid pointer. */
     if( input_length == 0 )
         return( PSA_SUCCESS );
 
-    psa_status_t status = psa_driver_wrapper_hash_update( operation,
-                                                          input, input_length );
+    status = psa_driver_wrapper_hash_update( operation, input, input_length );
+
+exit:
     if( status != PSA_SUCCESS )
         psa_hash_abort( operation );
 
@@ -2169,13 +2191,24 @@
                             operation,
                             actual_hash, sizeof( actual_hash ),
                             &actual_hash_length );
+
     if( status != PSA_SUCCESS )
-        return( status );
+        goto exit;
+
     if( actual_hash_length != hash_length )
-        return( PSA_ERROR_INVALID_SIGNATURE );
+    {
+        status = PSA_ERROR_INVALID_SIGNATURE;
+        goto exit;
+    }
+
     if( mbedtls_psa_safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
-        return( PSA_ERROR_INVALID_SIGNATURE );
-    return( PSA_SUCCESS );
+        status = PSA_ERROR_INVALID_SIGNATURE;
+
+exit:
+    if( status != PSA_SUCCESS )
+        psa_hash_abort(operation);
+
+    return( status );
 }
 
 psa_status_t psa_hash_compute( psa_algorithm_t alg,
@@ -2250,6 +2283,46 @@
     return( status );
 }
 
+static psa_status_t psa_mac_finalize_alg_and_key_validation(
+    psa_algorithm_t alg,
+    const psa_key_attributes_t *attributes,
+    uint8_t *mac_size )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_type_t key_type = psa_get_key_type( attributes );
+    size_t key_bits = psa_get_key_bits( attributes );
+
+    if( ! PSA_ALG_IS_MAC( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    /* Validate the combination of key type and algorithm */
+    status = psa_mac_key_can_do( alg, key_type );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    /* Get the output length for the algorithm and key combination */
+    *mac_size = PSA_MAC_LENGTH( key_type, key_bits, alg );
+
+    if( *mac_size < 4 )
+    {
+        /* A very short MAC is too short for security since it can be
+         * brute-forced. Ancient protocols with 32-bit MACs do exist,
+         * so we make this our minimum, even though 32 bits is still
+         * too small for security. */
+        return( PSA_ERROR_NOT_SUPPORTED );
+    }
+
+    if( *mac_size > PSA_MAC_LENGTH( key_type, key_bits,
+                                    PSA_ALG_FULL_LENGTH_MAC( alg ) ) )
+    {
+        /* It's impossible to "truncate" to a larger length than the full length
+         * of the algorithm. */
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+
+    return( PSA_SUCCESS );
+}
+
 static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
                                    mbedtls_svc_key_id_t key,
                                    psa_algorithm_t alg,
@@ -2257,60 +2330,33 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
-    psa_key_slot_t *slot;
+    psa_key_slot_t *slot = NULL;
 
     /* A context must be freshly initialized before it can be set up. */
     if( operation->id != 0 )
-        return( PSA_ERROR_BAD_STATE );
-
-    if( ! PSA_ALG_IS_MAC( alg ) )
-        return( PSA_ERROR_INVALID_ARGUMENT );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     status = psa_get_and_lock_key_slot_with_policy(
                  key,
                  &slot,
-                 is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH,
+                 is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE,
                  alg );
     if( status != PSA_SUCCESS )
-        return( status );
+        goto exit;
 
     psa_key_attributes_t attributes = {
         .core = slot->attr
     };
 
-    /* Validate the combination of key type and algorithm */
-    status = psa_mac_key_can_do( alg, psa_get_key_type( &attributes ) );
+    status = psa_mac_finalize_alg_and_key_validation( alg, &attributes,
+                                                      &operation->mac_size );
     if( status != PSA_SUCCESS )
         goto exit;
 
     operation->is_sign = is_sign;
-
-    /* Get the output length for the algorithm and key combination */
-    operation->mac_size = PSA_MAC_LENGTH(
-                            psa_get_key_type( &attributes ),
-                            psa_get_key_bits( &attributes ),
-                            alg );
-
-    if( operation->mac_size < 4 )
-    {
-        /* A very short MAC is too short for security since it can be
-         * brute-forced. Ancient protocols with 32-bit MACs do exist,
-         * so we make this our minimum, even though 32 bits is still
-         * too small for security. */
-        status = PSA_ERROR_NOT_SUPPORTED;
-        goto exit;
-    }
-
-    if( operation->mac_size > PSA_MAC_LENGTH( psa_get_key_type( &attributes ),
-                                              psa_get_key_bits( &attributes ),
-                                              PSA_ALG_FULL_LENGTH_MAC( alg ) ) )
-    {
-        /* It's impossible to "truncate" to a larger length than the full length
-         * of the algorithm. */
-        status = PSA_ERROR_INVALID_ARGUMENT;
-        goto exit;
-    }
-
     /* Dispatch the MAC setup call with validated input */
     if( is_sign )
     {
@@ -2380,47 +2426,53 @@
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
 
-    /* Set the output length and content to a safe default, such that in
-     * case the caller misses an error check, the output would be an
-     * unachievable MAC. */
-    *mac_length = mac_size;
-
     if( operation->id == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( ! operation->is_sign )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     /* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL)
      * once all the error checks are done. */
     if( operation->mac_size == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( mac_size < operation->mac_size )
-        return( PSA_ERROR_BUFFER_TOO_SMALL );
+    {
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        goto exit;
+    }
 
     status = psa_driver_wrapper_mac_sign_finish( operation,
                                                  mac, operation->mac_size,
                                                  mac_length );
 
-    if( status == PSA_SUCCESS )
+exit:
+    /* In case of success, set the potential excess room in the output buffer
+     * to an invalid value, to avoid potentially leaking a longer MAC.
+     * In case of error, set the output length and content to a safe default,
+     * such that in case the caller misses an error check, the output would be
+     * an unachievable MAC.
+     */
+    if( status != PSA_SUCCESS )
     {
-        /* Set the excess room in the output buffer to an invalid value, to
-         * avoid potentially leaking a longer MAC. */
-        if( mac_size > operation->mac_size )
-            memset( &mac[operation->mac_size],
-                    '!',
-                    mac_size - operation->mac_size );
-    }
-    else
-    {
-        /* Set the output length and content to a safe default, such that in
-         * case the caller misses an error check, the output would be an
-         * unachievable MAC. */
         *mac_length = mac_size;
-        memset( mac, '!', mac_size );
+        operation->mac_size = 0;
     }
 
+    if( mac_size > operation->mac_size )
+        memset( &mac[operation->mac_size], '!',
+                mac_size - operation->mac_size );
+
     abort_status = psa_mac_abort( operation );
 
     return( status == PSA_SUCCESS ? abort_status : status );
@@ -2434,27 +2486,143 @@
     psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
 
     if( operation->id == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( operation->is_sign )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( operation->mac_size != mac_length )
     {
         status = PSA_ERROR_INVALID_SIGNATURE;
-        goto cleanup;
+        goto exit;
     }
 
     status = psa_driver_wrapper_mac_verify_finish( operation,
                                                    mac, mac_length );
 
-cleanup:
+exit:
     abort_status = psa_mac_abort( operation );
 
     return( status == PSA_SUCCESS ? abort_status : status );
 }
 
+static psa_status_t psa_mac_compute_internal( mbedtls_svc_key_id_t key,
+                                              psa_algorithm_t alg,
+                                              const uint8_t *input,
+                                              size_t input_length,
+                                              uint8_t *mac,
+                                              size_t mac_size,
+                                              size_t *mac_length,
+                                              int is_sign )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot;
+    uint8_t operation_mac_size = 0;
 
+    status = psa_get_and_lock_key_slot_with_policy(
+                 key,
+                 &slot,
+                 is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE,
+                 alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    psa_key_attributes_t attributes = {
+        .core = slot->attr
+    };
+
+    status = psa_mac_finalize_alg_and_key_validation( alg, &attributes,
+                                                      &operation_mac_size );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    if( mac_size < operation_mac_size )
+    {
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        goto exit;
+    }
+
+    status = psa_driver_wrapper_mac_compute(
+                 &attributes,
+                 slot->key.data, slot->key.bytes,
+                 alg,
+                 input, input_length,
+                 mac, operation_mac_size, mac_length );
+
+exit:
+    /* In case of success, set the potential excess room in the output buffer
+     * to an invalid value, to avoid potentially leaking a longer MAC.
+     * In case of error, set the output length and content to a safe default,
+     * such that in case the caller misses an error check, the output would be
+     * an unachievable MAC.
+     */
+    if( status != PSA_SUCCESS )
+    {
+        *mac_length = mac_size;
+        operation_mac_size = 0;
+    }
+    if( mac_size > operation_mac_size )
+        memset( &mac[operation_mac_size], '!', mac_size - operation_mac_size );
+
+    unlock_status = psa_unlock_key_slot( slot );
+
+    return( ( status == PSA_SUCCESS ) ? unlock_status : status );
+}
+
+psa_status_t psa_mac_compute( mbedtls_svc_key_id_t key,
+                              psa_algorithm_t alg,
+                              const uint8_t *input,
+                              size_t input_length,
+                              uint8_t *mac,
+                              size_t mac_size,
+                              size_t *mac_length)
+{
+    return( psa_mac_compute_internal( key, alg,
+                                      input, input_length,
+                                      mac, mac_size, mac_length, 1 ) );
+}
+
+psa_status_t psa_mac_verify( mbedtls_svc_key_id_t key,
+                             psa_algorithm_t alg,
+                             const uint8_t *input,
+                             size_t input_length,
+                             const uint8_t *mac,
+                             size_t mac_length)
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    uint8_t actual_mac[PSA_MAC_MAX_SIZE];
+    size_t actual_mac_length;
+
+    status = psa_mac_compute_internal( key, alg,
+                                       input, input_length,
+                                       actual_mac, sizeof( actual_mac ),
+                                       &actual_mac_length, 0 );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    if( mac_length != actual_mac_length )
+    {
+        status = PSA_ERROR_INVALID_SIGNATURE;
+        goto exit;
+    }
+    if( mbedtls_psa_safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 )
+    {
+        status = PSA_ERROR_INVALID_SIGNATURE;
+        goto exit;
+    }
+
+exit:
+    mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );
+
+    return ( status );
+}
 
 /****************************************************************/
 /* Asymmetric cryptography */
@@ -2848,13 +3016,14 @@
 }
 
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
-static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
-                                           mbedtls_rsa_context *rsa )
+static int psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
+                                          mbedtls_rsa_context *rsa )
 {
     psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
     const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
     mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
-    mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
+
+    return( mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg ) );
 }
 #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
 
@@ -2927,7 +3096,11 @@
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
         if( PSA_ALG_IS_RSA_OAEP( alg ) )
         {
-            psa_rsa_oaep_set_padding_mode( alg, rsa );
+            status = mbedtls_to_psa_error(
+                         psa_rsa_oaep_set_padding_mode( alg, rsa ) );
+            if( status != PSA_SUCCESS )
+                goto rsa_exit;
+
             status = mbedtls_to_psa_error(
                 mbedtls_rsa_rsaes_oaep_encrypt( rsa,
                                                 mbedtls_psa_get_random,
@@ -3033,7 +3206,11 @@
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
         if( PSA_ALG_IS_RSA_OAEP( alg ) )
         {
-            psa_rsa_oaep_set_padding_mode( alg, rsa );
+            status = mbedtls_to_psa_error(
+                         psa_rsa_oaep_set_padding_mode( alg, rsa ) );
+            if( status != PSA_SUCCESS )
+                goto rsa_exit;
+
             status = mbedtls_to_psa_error(
                 mbedtls_rsa_rsaes_oaep_decrypt( rsa,
                                                 mbedtls_psa_get_random,
@@ -3080,20 +3257,24 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
-    psa_key_slot_t *slot;
+    psa_key_slot_t *slot = NULL;
     psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
                               PSA_KEY_USAGE_ENCRYPT :
                               PSA_KEY_USAGE_DECRYPT );
 
     /* A context must be freshly initialized before it can be set up. */
     if( operation->id != 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
-    /* The requested algorithm must be one that can be processed by cipher. */
     if( ! PSA_ALG_IS_CIPHER( alg ) )
-        return( PSA_ERROR_INVALID_ARGUMENT );
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
 
-    /* Fetch key material from key storage. */
     status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg );
     if( status != PSA_SUCCESS )
         goto exit;
@@ -3161,12 +3342,14 @@
 
     if( operation->id == 0 )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
 
     if( operation->iv_set || ! operation->iv_required )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
 
     if( iv_size < operation->default_iv_length )
@@ -3202,18 +3385,28 @@
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
 
     if( operation->id == 0 )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( operation->iv_set || ! operation->iv_required )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
 
     if( iv_length > PSA_CIPHER_IV_MAX_SIZE )
-        return( PSA_ERROR_INVALID_ARGUMENT );
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
 
     status = psa_driver_wrapper_cipher_set_iv( operation,
                                                iv,
                                                iv_length );
 
+exit:
     if( status == PSA_SUCCESS )
         operation->iv_set = 1;
     else
@@ -3232,11 +3425,14 @@
 
     if( operation->id == 0 )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
+
     if( operation->iv_required && ! operation->iv_set )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
 
     status = psa_driver_wrapper_cipher_update( operation,
@@ -3245,6 +3441,8 @@
                                                output,
                                                output_size,
                                                output_length );
+
+exit:
     if( status != PSA_SUCCESS )
         psa_cipher_abort( operation );
 
@@ -3260,17 +3458,22 @@
 
     if( operation->id == 0 )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
+
     if( operation->iv_required && ! operation->iv_set )
     {
-        return( PSA_ERROR_BAD_STATE );
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
     }
 
     status = psa_driver_wrapper_cipher_finish( operation,
                                                output,
                                                output_size,
                                                output_length );
+
+exit:
     if( status == PSA_SUCCESS )
         return( psa_cipher_abort( operation ) );
     else
@@ -3301,6 +3504,107 @@
     return( PSA_SUCCESS );
 }
 
+psa_status_t psa_cipher_encrypt( mbedtls_svc_key_id_t key,
+                                 psa_algorithm_t alg,
+                                 const uint8_t *input,
+                                 size_t input_length,
+                                 uint8_t *output,
+                                 size_t output_size,
+                                 size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot;
+    psa_key_type_t key_type;
+    size_t iv_length;
+
+    *output_length = 0;
+
+    if( ! PSA_ALG_IS_CIPHER( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    status = psa_get_and_lock_key_slot_with_policy( key, &slot,
+                                                    PSA_KEY_USAGE_ENCRYPT,
+                                                    alg );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    psa_key_attributes_t attributes = {
+      .core = slot->attr
+    };
+
+    key_type = slot->attr.type;
+    iv_length = PSA_CIPHER_IV_LENGTH( key_type, alg );
+
+    if( iv_length > 0 )
+    {
+        if( output_size < iv_length )
+        {
+            status = PSA_ERROR_BUFFER_TOO_SMALL;
+            goto exit;
+        }
+
+        status = psa_generate_random( output, iv_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
+
+    status = psa_driver_wrapper_cipher_encrypt(
+        &attributes, slot->key.data, slot->key.bytes,
+        alg, input, input_length,
+        output, output_size, output_length );
+
+exit:
+    unlock_status = psa_unlock_key_slot( slot );
+
+    return( ( status == PSA_SUCCESS ) ? unlock_status : status );
+}
+
+psa_status_t psa_cipher_decrypt( mbedtls_svc_key_id_t key,
+                                 psa_algorithm_t alg,
+                                 const uint8_t *input,
+                                 size_t input_length,
+                                 uint8_t *output,
+                                 size_t output_size,
+                                 size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot;
+
+    *output_length = 0;
+
+    if( ! PSA_ALG_IS_CIPHER( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    status = psa_get_and_lock_key_slot_with_policy( key, &slot,
+                                                    PSA_KEY_USAGE_DECRYPT,
+                                                    alg );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    psa_key_attributes_t attributes = {
+      .core = slot->attr
+    };
+
+    if( input_length < PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ) )
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+
+    status = psa_driver_wrapper_cipher_decrypt(
+        &attributes, slot->key.data, slot->key.bytes,
+        alg, input, input_length,
+        output, output_size, output_length );
+
+exit:
+    unlock_status = psa_unlock_key_slot( slot );
+
+    return( ( status == PSA_SUCCESS ) ? unlock_status : status );
+}
+
+
 /****************************************************************/
 /* AEAD */
 /****************************************************************/
@@ -4163,6 +4467,17 @@
     psa_status_t status;
     uint8_t offset, length;
 
+    switch( tls12_prf->state )
+    {
+        case PSA_TLS12_PRF_STATE_LABEL_SET:
+            tls12_prf->state = PSA_TLS12_PRF_STATE_OUTPUT;
+            break;
+        case PSA_TLS12_PRF_STATE_OUTPUT:
+            break;
+        default:
+            return( PSA_ERROR_BAD_STATE );
+    }
+
     while( output_length != 0 )
     {
         /* Check if we have fully processed the current block. */
@@ -4287,6 +4602,7 @@
 {
     uint8_t *data = NULL;
     size_t bytes = PSA_BITS_TO_BYTES( bits );
+    size_t storage_size = bytes;
     psa_status_t status;
 
     if( ! key_type_is_raw_bytes( slot->attr.type ) )
@@ -4305,15 +4621,22 @@
         psa_des_set_key_parity( data, bytes );
 #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
 
-    status = psa_allocate_buffer_to_slot( slot, bytes );
-    if( status != PSA_SUCCESS )
-        goto exit;
-
     slot->attr.bits = (psa_key_bits_t) bits;
     psa_key_attributes_t attributes = {
       .core = slot->attr
     };
 
+    if( psa_key_lifetime_is_external( attributes.core.lifetime ) )
+    {
+        status = psa_driver_wrapper_get_key_buffer_size( &attributes,
+                                                         &storage_size );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
+    status = psa_allocate_buffer_to_slot( slot, storage_size );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
     status = psa_driver_wrapper_import_key( &attributes,
                                             data, bytes,
                                             slot->key.data,
@@ -4637,8 +4960,8 @@
      * uint16 with the value N, and the PSK itself.
      */
 
-    *cur++ = ( data_length >> 8 ) & 0xff;
-    *cur++ = ( data_length >> 0 ) & 0xff;
+    *cur++ = MBEDTLS_BYTE_1( data_length );
+    *cur++ = MBEDTLS_BYTE_0( data_length );
     memset( cur, 0, data_length );
     cur += data_length;
     *cur++ = pms[0];
@@ -5192,7 +5515,7 @@
 
     if( key_type_is_raw_bytes( type ) )
     {
-        status = validate_unstructured_key_bit_size( type, bits );
+        status = psa_validate_unstructured_key_bit_size( type, bits );
         if( status != PSA_SUCCESS )
             return( status );
     }
@@ -5302,9 +5625,9 @@
         goto exit;
 
     /* In the case of a transparent key or an opaque key stored in local
-     * storage (thus not in the case of generating a key in a secure element
-     * or cryptoprocessor with storage), we have to allocate a buffer to
-     * hold the generated key material. */
+     * storage ( thus not in the case of generating a key in a secure element
+     * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
+     * buffer to hold the generated key material. */
     if( slot->key.data == NULL )
     {
         if ( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) ==
diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c
index 01d5d19..9000abf 100644
--- a/library/psa_crypto_aead.c
+++ b/library/psa_crypto_aead.c
@@ -643,7 +643,7 @@
 
         status =  mbedtls_to_psa_error(
             mbedtls_gcm_finish( &operation->ctx.gcm,
-                                ciphertext, ciphertext_size,
+                                ciphertext, ciphertext_size, ciphertext_length,
                                 tag, operation->tag_length ) );
     }
     else
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index 4992a6e..2268fc5 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -131,9 +131,6 @@
         case PSA_KEY_TYPE_CAMELLIA:
             cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
             break;
-        case PSA_KEY_TYPE_ARC4:
-            cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
-            break;
         case PSA_KEY_TYPE_CHACHA20:
             cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
             break;
@@ -163,9 +160,7 @@
 
     (void)key_buffer_size;
 
-    /* Proceed with initializing an mbed TLS cipher context if no driver is
-     * available for the given algorithm & key. */
-    mbedtls_cipher_init( &operation->cipher );
+    mbedtls_cipher_init( &operation->ctx.cipher );
 
     operation->alg = alg;
     key_bits = attributes->core.bits;
@@ -174,7 +169,7 @@
     if( cipher_info == NULL )
         return( PSA_ERROR_NOT_SUPPORTED );
 
-    ret = mbedtls_cipher_setup( &operation->cipher, cipher_info );
+    ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
     if( ret != 0 )
         goto exit;
 
@@ -185,14 +180,14 @@
         uint8_t keys[24];
         memcpy( keys, key_buffer, 16 );
         memcpy( keys + 16, key_buffer, 8 );
-        ret = mbedtls_cipher_setkey( &operation->cipher,
+        ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
                                      keys,
                                      192, cipher_operation );
     }
     else
 #endif
     {
-        ret = mbedtls_cipher_setkey( &operation->cipher, key_buffer,
+        ret = mbedtls_cipher_setkey( &operation->ctx.cipher, key_buffer,
                                      (int) key_bits, cipher_operation );
     }
     if( ret != 0 )
@@ -203,11 +198,11 @@
     switch( alg )
     {
         case PSA_ALG_CBC_NO_PADDING:
-            ret = mbedtls_cipher_set_padding_mode( &operation->cipher,
+            ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
                                                    MBEDTLS_PADDING_NONE );
             break;
         case PSA_ALG_CBC_PKCS7:
-            ret = mbedtls_cipher_set_padding_mode( &operation->cipher,
+            ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
                                                    MBEDTLS_PADDING_PKCS7 );
             break;
         default:
@@ -256,20 +251,38 @@
         return( PSA_ERROR_INVALID_ARGUMENT );
 
     return( mbedtls_to_psa_error(
-                mbedtls_cipher_set_iv( &operation->cipher,
+                mbedtls_cipher_set_iv( &operation->ctx.cipher,
                                        iv, iv_length ) ) );
 }
 
-/* Process input for which the algorithm is set to ECB mode. This requires
- * manual processing, since the PSA API is defined as being able to process
- * arbitrary-length calls to psa_cipher_update() with ECB mode, but the
- * underlying mbedtls_cipher_update only takes full blocks. */
+/** Process input for which the algorithm is set to ECB mode.
+ *
+ * This requires manual processing, since the PSA API is defined as being
+ * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
+ * but the underlying mbedtls_cipher_update only takes full blocks.
+ *
+ * \param ctx           The mbedtls cipher context to use. It must have been
+ *                      set up for ECB.
+ * \param[in] input     The input plaintext or ciphertext to process.
+ * \param input_length  The number of bytes to process from \p input.
+ *                      This does not need to be aligned to a block boundary.
+ *                      If there is a partial block at the end of the input,
+ *                      it is stored in \p ctx for future processing.
+ * \param output        The buffer where the output is written. It must be
+ *                      at least `BS * floor((p + input_length) / BS)` bytes
+ *                      long, where `p` is the number of bytes in the
+ *                      unprocessed partial block in \p ctx (with
+ *                      `0 <= p <= BS - 1`) and `BS` is the block size.
+ * \param output_length On success, the number of bytes written to \p output.
+ *                      \c 0 on error.
+ *
+ * \return #PSA_SUCCESS or an error from a hardware accelerator
+ */
 static psa_status_t psa_cipher_update_ecb(
     mbedtls_cipher_context_t *ctx,
     const uint8_t *input,
     size_t input_length,
     uint8_t *output,
-    size_t output_size,
     size_t *output_length )
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
@@ -309,7 +322,6 @@
                 goto exit;
 
             output += internal_output_length;
-            output_size -= internal_output_length;
             *output_length += internal_output_length;
             ctx->unprocessed_len = 0;
         }
@@ -330,7 +342,6 @@
         input += block_size;
 
         output += internal_output_length;
-        output_size -= internal_output_length;
         *output_length += internal_output_length;
     }
 
@@ -365,7 +376,7 @@
          * the last partial block, if any. You get the data that will be
          * output in this call. */
         expected_output_size =
-            ( operation->cipher.unprocessed_len + input_length )
+            ( operation->ctx.cipher.unprocessed_len + input_length )
             / operation->block_length * operation->block_length;
     }
     else
@@ -381,18 +392,20 @@
         /* mbedtls_cipher_update has an API inconsistency: it will only
         * process a single block at a time in ECB mode. Abstract away that
         * inconsistency here to match the PSA API behaviour. */
-        status = psa_cipher_update_ecb( &operation->cipher,
+        status = psa_cipher_update_ecb( &operation->ctx.cipher,
                                         input,
                                         input_length,
                                         output,
-                                        output_size,
                                         output_length );
     }
     else
     {
         status = mbedtls_to_psa_error(
-            mbedtls_cipher_update( &operation->cipher, input,
+            mbedtls_cipher_update( &operation->ctx.cipher, input,
                                    input_length, output, output_length ) );
+
+        if( *output_length > output_size )
+            return( PSA_ERROR_CORRUPTION_DETECTED );
     }
 
     return( status );
@@ -406,7 +419,7 @@
     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
     uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
 
-    if( operation->cipher.unprocessed_len != 0 )
+    if( operation->ctx.cipher.unprocessed_len != 0 )
     {
         if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
             operation->alg == PSA_ALG_CBC_NO_PADDING )
@@ -417,7 +430,7 @@
     }
 
     status = mbedtls_to_psa_error(
-        mbedtls_cipher_finish( &operation->cipher,
+        mbedtls_cipher_finish( &operation->ctx.cipher,
                                temp_output_buffer,
                                output_length ) );
     if( status != PSA_SUCCESS )
@@ -444,10 +457,112 @@
     if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
         return( PSA_ERROR_BAD_STATE );
 
-    mbedtls_cipher_free( &operation->cipher );
+    mbedtls_cipher_free( &operation->ctx.cipher );
 
     return( PSA_SUCCESS );
 }
+
+static psa_status_t cipher_encrypt( const psa_key_attributes_t *attributes,
+                                    const uint8_t *key_buffer,
+                                    size_t key_buffer_size,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
+    size_t olength, accumulated_length;
+
+    status = cipher_encrypt_setup( &operation, attributes,
+                                   key_buffer, key_buffer_size, alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    accumulated_length = 0;
+    if( operation.iv_length > 0 )
+    {
+        status = cipher_set_iv( &operation, output, operation.iv_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+
+        accumulated_length = operation.iv_length;
+    }
+
+    status = cipher_update( &operation, input, input_length,
+                            output + operation.iv_length,
+                            output_size - operation.iv_length,
+                            &olength );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    accumulated_length += olength;
+
+    status = cipher_finish( &operation, output + accumulated_length,
+                            output_size - accumulated_length, &olength );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    *output_length = accumulated_length + olength;
+
+exit:
+    if( status == PSA_SUCCESS )
+        status = cipher_abort( &operation );
+    else
+        cipher_abort( &operation );
+    return( status );
+}
+
+static psa_status_t cipher_decrypt( const psa_key_attributes_t *attributes,
+                                    const uint8_t *key_buffer,
+                                    size_t key_buffer_size,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
+    size_t olength, accumulated_length;
+
+    status = cipher_decrypt_setup( &operation, attributes,
+                                   key_buffer, key_buffer_size, alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    if( operation.iv_length > 0 )
+    {
+        status = cipher_set_iv( &operation, input, operation.iv_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
+
+    status = cipher_update( &operation, input + operation.iv_length,
+                            input_length - operation.iv_length,
+                            output, output_size, &olength );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    accumulated_length = olength;
+
+    status = cipher_finish( &operation, output + accumulated_length,
+                            output_size - accumulated_length, &olength );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    *output_length = accumulated_length + olength;
+
+exit:
+    if ( status == PSA_SUCCESS )
+        status = cipher_abort( &operation );
+    else
+        cipher_abort( &operation );
+    return( status );
+}
 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER || PSA_CRYPTO_DRIVER_TEST */
 
 #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
@@ -501,6 +616,36 @@
 {
     return( cipher_abort( operation ) );
 }
+
+psa_status_t mbedtls_psa_cipher_encrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length )
+{
+    return( cipher_encrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
+
+psa_status_t mbedtls_psa_cipher_decrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length )
+{
+    return( cipher_decrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
 
 /*
@@ -556,6 +701,38 @@
 {
     return( cipher_abort( operation ) );
 }
+
+psa_status_t mbedtls_transparent_test_driver_cipher_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
+{
+    return( cipher_encrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
+
+psa_status_t mbedtls_transparent_test_driver_cipher_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
+{
+    return( cipher_decrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_cipher.h b/library/psa_crypto_cipher.h
index 3e1a7a0..5971e8d 100644
--- a/library/psa_crypto_cipher.h
+++ b/library/psa_crypto_cipher.h
@@ -199,6 +199,111 @@
  */
 psa_status_t mbedtls_psa_cipher_abort( mbedtls_psa_cipher_operation_t *operation );
 
+/** Encrypt a message using a symmetric cipher.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       cipher_encrypt entry point. This function behaves as a
+ *       cipher_encrypt entry point as defined in the PSA driver
+ *       interface specification for transparent drivers.
+ *
+ * \param[in] attributes        The attributes of the key to use for the
+ *                              operation.
+ * \param[in] key_buffer        The buffer containing the key context.
+ * \param[in] key_buffer_size   Size of the \p key_buffer buffer in bytes.
+ * \param[in] alg               The cipher algorithm to compute
+ *                              (\c PSA_ALG_XXX value such that
+ *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param[in]  input            Buffer containing the message to encrypt.
+ * \param[in]  input_length     Size of the \p input buffer in bytes.
+ * \param[in,out] output        Buffer where the output is to be written.
+ *                              The core has generated and written the IV
+ *                              at the beginning of this buffer before
+ *                              this function is called. The size of the IV
+ *                              is PSA_CIPHER_IV_LENGTH( key_type, alg ) where
+ *                              \c key_type is the type of the key identified
+ *                              by \p key and \p alg is the cipher algorithm
+ *                              to compute.
+ * \param[in]  output_size      Size of the \p output buffer in bytes.
+ * \param[out] output_length    On success, the number of bytes that make up
+ *                              the returned output. Initialized to zero
+ *                              by the core.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size of \p iv is not acceptable for the chosen algorithm,
+ *         or the chosen algorithm does not use an IV.
+ *         The total input size passed to this operation is not valid for
+ *         this particular algorithm. For example, the algorithm is a based
+ *         on block cipher and requires a whole number of blocks, but the
+ *         total input size is not a multiple of the block size.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ *         This is a decryption operation for an algorithm that includes
+ *         padding, and the ciphertext does not contain valid padding.
+ */
+psa_status_t mbedtls_psa_cipher_encrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length );
+
+/** Decrypt a message using a symmetric cipher.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       cipher_decrypt entry point. This function behaves as a
+ *       cipher_decrypt entry point as defined in the PSA driver
+ *       interface specification for transparent drivers.
+ *
+ * \param[in]  attributes       The attributes of the key to use for the
+ *                              operation.
+ * \param[in]  key_buffer       The buffer containing the key context.
+ * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
+ * \param[in]  alg              The cipher algorithm to compute
+ *                              (\c PSA_ALG_XXX value such that
+ *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param[in]  input            Buffer containing the iv and the ciphertext.
+ * \param[in]  input_length     Size of the \p input buffer in bytes.
+ * \param[out] output           Buffer where the output is to be written.
+ * \param[in]  output_size      Size of the \p output buffer in bytes.
+ * \param[out] output_length    On success, the number of bytes that make up
+ *                              the returned output. Initialized to zero
+ *                              by the core.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size of \p iv is not acceptable for the chosen algorithm,
+ *         or the chosen algorithm does not use an IV.
+ *         The total input size passed to this operation is not valid for
+ *         this particular algorithm. For example, the algorithm is a based
+ *         on block cipher and requires a whole number of blocks, but the
+ *         total input size is not a multiple of the block size.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ *         This is a decryption operation for an algorithm that includes
+ *         padding, and the ciphertext does not contain valid padding.
+ */
+psa_status_t mbedtls_psa_cipher_decrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length );
+
 /*
  * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
  */
@@ -231,6 +336,28 @@
 
 psa_status_t mbedtls_transparent_test_driver_cipher_abort(
     mbedtls_psa_cipher_operation_t *operation );
+
+psa_status_t mbedtls_transparent_test_driver_cipher_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length );
+
+psa_status_t mbedtls_transparent_test_driver_cipher_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* PSA_CRYPTO_CIPHER_H */
diff --git a/library/psa_crypto_client.c b/library/psa_crypto_client.c
index e84cf30..629feb7 100644
--- a/library/psa_crypto_client.c
+++ b/library/psa_crypto_client.c
@@ -19,7 +19,6 @@
  */
 
 #include "common.h"
-#include "psa_crypto_service_integration.h"
 #include "psa/crypto.h"
 
 #if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index 4420ec2..8c91b04 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -21,11 +21,7 @@
 #ifndef PSA_CRYPTO_CORE_H
 #define PSA_CRYPTO_CORE_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "psa/crypto.h"
 #include "psa/crypto_se_driver.h"
@@ -532,4 +528,23 @@
     psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
     const uint8_t *signature, size_t signature_length );
 
+/**
+ * \brief Validate the key bit size for unstructured keys.
+ *
+ * \note  Check that the bit size is acceptable for a given key type for
+ *        unstructured keys.
+ *
+ * \param[in]  type  The key type
+ * \param[in]  bits  The number of bits of the key
+ *
+ * \retval #PSA_SUCCESS
+ *         The key type and size are valid.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size in bits of the key is not valid.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         The type and/or the size in bits of the key or the combination of
+ *         the two is not supported.
+ */
+psa_status_t psa_validate_unstructured_key_bit_size( psa_key_type_t type,
+                                                     size_t bits );
 #endif /* PSA_CRYPTO_CORE_H */
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 4c56162..cfc77fb 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -19,6 +19,7 @@
  *  limitations under the License.
  */
 
+#include "common.h"
 #include "psa_crypto_aead.h"
 #include "psa_crypto_cipher.h"
 #include "psa_crypto_core.h"
@@ -379,8 +380,49 @@
     }
 }
 
+/** Calculate the key buffer size required to store the key material of a key
+ *  associated with an opaque driver from input key data.
+ *
+ * \param[in] attributes        The key attributes
+ * \param[in] data              The input key data.
+ * \param[in] data_length       The input data length.
+ * \param[out] key_buffer_size  Minimum buffer size to contain the key material.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ */
+psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *data,
+    size_t data_length,
+    size_t *key_buffer_size )
+{
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+    psa_key_type_t key_type = attributes->core.type;
+
+    *key_buffer_size = 0;
+    switch( location )
+    {
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TEST_DRIVER_LOCATION:
+            *key_buffer_size = mbedtls_test_opaque_size_function( key_type,
+                                     PSA_BYTES_TO_BITS( data_length ) );
+            return( ( *key_buffer_size != 0 ) ?
+                    PSA_SUCCESS : PSA_ERROR_NOT_SUPPORTED );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+
+        default:
+            (void)key_type;
+            (void)data;
+            (void)data_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+}
+
 /** Get the key buffer size required to store the key material of a key
- *  associated with an opaque driver without storage.
+ *  associated with an opaque driver.
  *
  * \param[in] attributes  The key attributes.
  * \param[out] key_buffer_size  Minimum buffer size to contain the key material
@@ -388,11 +430,11 @@
  * \retval #PSA_SUCCESS
  *         The minimum size for a buffer to contain the key material has been
  *         returned successfully.
- * \retval #PSA_ERROR_INVALID_ARGUMENT
- *         The size in bits of the key is not valid.
  * \retval #PSA_ERROR_NOT_SUPPORTED
  *         The type and/or the size in bits of the key or the combination of
  *         the two is not supported.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The key is declared with a lifetime not known to us.
  */
 psa_status_t psa_driver_wrapper_get_key_buffer_size(
     const psa_key_attributes_t *attributes,
@@ -417,7 +459,8 @@
                 return( PSA_SUCCESS );
             }
 #endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
-            *key_buffer_size = mbedtls_test_size_function( key_type, key_bits );
+            *key_buffer_size = mbedtls_test_opaque_size_function( key_type,
+                                                                  key_bits );
             return( ( *key_buffer_size != 0 ) ?
                     PSA_SUCCESS : PSA_ERROR_NOT_SUPPORTED );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
@@ -425,7 +468,7 @@
         default:
             (void)key_type;
             (void)key_bits;
-            return( PSA_ERROR_NOT_SUPPORTED );
+            return( PSA_ERROR_INVALID_ARGUMENT );
     }
 }
 
@@ -565,10 +608,18 @@
                                               data, data_length,
                                               key_buffer, key_buffer_size,
                                               key_buffer_length, bits ) );
-
+        /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TEST_DRIVER_LOCATION:
+            return( mbedtls_test_opaque_import_key(
+                         attributes,
+                         data, data_length,
+                         key_buffer, key_buffer_size,
+                         key_buffer_length, bits ) );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
         default:
-            /* Importing a key with external storage in not yet supported.
-             * Return in error indicating that the lifetime is not valid. */
             (void)status;
             return( PSA_ERROR_INVALID_ARGUMENT );
     }
@@ -732,11 +783,57 @@
     }
 }
 
+psa_status_t psa_driver_wrapper_copy_key(
+    psa_key_attributes_t *attributes,
+    const uint8_t *source_key, size_t source_key_length,
+    uint8_t *target_key_buffer, size_t target_key_buffer_size,
+    size_t *target_key_buffer_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+    const psa_drv_se_t *drv;
+    psa_drv_se_context_t *drv_context;
+
+    if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+    {
+        /* Copying to a secure element is not implemented yet. */
+        return( PSA_ERROR_NOT_SUPPORTED );
+    }
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+
+    switch( location )
+    {
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
+#if defined(PSA_CRYPTO_DRIVER_TEST)
+        case PSA_CRYPTO_TEST_DRIVER_LOCATION:
+            return( mbedtls_test_opaque_copy_key( attributes, source_key,
+                                                  source_key_length,
+                                                  target_key_buffer,
+                                                  target_key_buffer_size,
+                                                  target_key_buffer_length) );
+#endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+        default:
+            (void)source_key;
+            (void)source_key_length;
+            (void)target_key_buffer;
+            (void)target_key_buffer_size;
+            (void)target_key_buffer_length;
+            status = PSA_ERROR_INVALID_ARGUMENT;
+    }
+    return( status );
+}
+
 /*
  * Cipher functions
  */
 psa_status_t psa_driver_wrapper_cipher_encrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -744,22 +841,20 @@
     size_t output_size,
     size_t *output_length )
 {
-#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-    psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
-    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
-    psa_key_attributes_t attributes = {
-      .core = slot->attr
-    };
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
 
     switch( location )
     {
         case PSA_KEY_LOCATION_LOCAL_STORAGE:
             /* Key is stored in the slot in export representation, so
              * cycle through all known transparent accelerators */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = mbedtls_test_transparent_cipher_encrypt( &attributes,
-                                                              slot->key.data,
-                                                              slot->key.bytes,
+            status = mbedtls_test_transparent_cipher_encrypt( attributes,
+                                                              key_buffer,
+                                                              key_buffer_size,
                                                               alg,
                                                               input,
                                                               input_length,
@@ -770,14 +865,29 @@
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
-            /* Fell through, meaning no accelerator supports this operation */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
+            return( mbedtls_psa_cipher_encrypt( attributes,
+                                                key_buffer,
+                                                key_buffer_size,
+                                                alg,
+                                                input,
+                                                input_length,
+                                                output,
+                                                output_size,
+                                                output_length ) );
+#else
             return( PSA_ERROR_NOT_SUPPORTED );
+#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
+
         /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
         case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_cipher_encrypt( &attributes,
-                                                        slot->key.data,
-                                                        slot->key.bytes,
+            return( mbedtls_test_opaque_cipher_encrypt( attributes,
+                                                        key_buffer,
+                                                        key_buffer_size,
                                                         alg,
                                                         input,
                                                         input_length,
@@ -785,25 +895,27 @@
                                                         output_size,
                                                         output_length ) );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
         default:
             /* Key is declared with a lifetime not known to us */
-            return( status );
+            (void)status;
+            (void)key_buffer;
+            (void)key_buffer_size;
+            (void)alg;
+            (void)input;
+            (void)input_length;
+            (void)output;
+            (void)output_size;
+            (void)output_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
     }
-#else /* PSA_CRYPTO_DRIVER_PRESENT */
-    (void) slot;
-    (void) alg;
-    (void) input;
-    (void) input_length;
-    (void) output;
-    (void) output_size;
-    (void) output_length;
-
-    return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
 psa_status_t psa_driver_wrapper_cipher_decrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -811,22 +923,20 @@
     size_t output_size,
     size_t *output_length )
 {
-#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-    psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
-    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
-    psa_key_attributes_t attributes = {
-      .core = slot->attr
-    };
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
 
     switch( location )
     {
         case PSA_KEY_LOCATION_LOCAL_STORAGE:
             /* Key is stored in the slot in export representation, so
              * cycle through all known transparent accelerators */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = mbedtls_test_transparent_cipher_decrypt( &attributes,
-                                                              slot->key.data,
-                                                              slot->key.bytes,
+            status = mbedtls_test_transparent_cipher_decrypt( attributes,
+                                                              key_buffer,
+                                                              key_buffer_size,
                                                               alg,
                                                               input,
                                                               input_length,
@@ -837,14 +947,29 @@
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
-            /* Fell through, meaning no accelerator supports this operation */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
+            return( mbedtls_psa_cipher_decrypt( attributes,
+                                                key_buffer,
+                                                key_buffer_size,
+                                                alg,
+                                                input,
+                                                input_length,
+                                                output,
+                                                output_size,
+                                                output_length ) );
+#else
             return( PSA_ERROR_NOT_SUPPORTED );
+#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
+
         /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
         case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_cipher_decrypt( &attributes,
-                                                        slot->key.data,
-                                                        slot->key.bytes,
+            return( mbedtls_test_opaque_cipher_decrypt( attributes,
+                                                        key_buffer,
+                                                        key_buffer_size,
                                                         alg,
                                                         input,
                                                         input_length,
@@ -852,21 +977,21 @@
                                                         output_size,
                                                         output_length ) );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
         default:
             /* Key is declared with a lifetime not known to us */
-            return( status );
+            (void)status;
+            (void)key_buffer;
+            (void)key_buffer_size;
+            (void)alg;
+            (void)input;
+            (void)input_length;
+            (void)output;
+            (void)output_size;
+            (void)output_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
     }
-#else /* PSA_CRYPTO_DRIVER_PRESENT */
-    (void) slot;
-    (void) alg;
-    (void) input;
-    (void) input_length;
-    (void) output;
-    (void) output_size;
-    (void) output_length;
-
-    return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
 psa_status_t psa_driver_wrapper_cipher_encrypt_setup(
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index eefdaa6..0873b73 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -85,6 +85,12 @@
     const psa_key_attributes_t *attributes,
     size_t *key_buffer_size );
 
+psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *data,
+    size_t data_length,
+    size_t *key_buffer_size );
+
 psa_status_t psa_driver_wrapper_generate_key(
     const psa_key_attributes_t *attributes,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length );
@@ -94,11 +100,18 @@
     psa_key_attributes_t *attributes,
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length );
 
+psa_status_t psa_driver_wrapper_copy_key(
+    psa_key_attributes_t *attributes,
+    const uint8_t *source_key, size_t source_key_length,
+    uint8_t *target_key_buffer, size_t target_key_buffer_size,
+    size_t *target_key_buffer_length );
 /*
  * Cipher functions
  */
 psa_status_t psa_driver_wrapper_cipher_encrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -107,7 +120,9 @@
     size_t *output_length );
 
 psa_status_t psa_driver_wrapper_cipher_decrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c
index 3ce232c..144ba1c 100644
--- a/library/psa_crypto_ecp.c
+++ b/library/psa_crypto_ecp.c
@@ -572,7 +572,7 @@
 #if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
     defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
 
-psa_status_t mbedtls_transparent_test_driver_ecp_import_key(
+psa_status_t mbedtls_test_driver_ecp_import_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *data, size_t data_length,
     uint8_t *key_buffer, size_t key_buffer_size,
@@ -583,7 +583,7 @@
                             key_buffer_length, bits ) );
 }
 
-psa_status_t mbedtls_transparent_test_driver_ecp_export_public_key(
+psa_status_t mbedtls_test_driver_ecp_export_public_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length )
diff --git a/library/psa_crypto_ecp.h b/library/psa_crypto_ecp.h
index 0c2b928..dc9e887 100644
--- a/library/psa_crypto_ecp.h
+++ b/library/psa_crypto_ecp.h
@@ -224,13 +224,13 @@
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 
-psa_status_t mbedtls_transparent_test_driver_ecp_import_key(
+psa_status_t mbedtls_test_driver_ecp_import_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *data, size_t data_length,
     uint8_t *key_buffer, size_t key_buffer_size,
     size_t *key_buffer_length, size_t *bits );
 
-psa_status_t mbedtls_transparent_test_driver_ecp_export_public_key(
+psa_status_t mbedtls_test_driver_ecp_export_public_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length );
diff --git a/library/psa_crypto_hash.c b/library/psa_crypto_hash.c
index d0f986e..92dcbba 100644
--- a/library/psa_crypto_hash.c
+++ b/library/psa_crypto_hash.c
@@ -31,14 +31,6 @@
 
 /* Use builtin defines specific to this compilation unit, since the test driver
  * relies on the software driver. */
-#if( defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) || \
-    ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_MD2) ) )
-#define BUILTIN_ALG_MD2         1
-#endif
-#if( defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) || \
-    ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_MD4) ) )
-#define BUILTIN_ALG_MD4         1
-#endif
 #if( defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) || \
     ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_MD5) ) )
 #define BUILTIN_ALG_MD5         1
@@ -76,14 +68,6 @@
 {
     switch( alg )
     {
-#if defined(MBEDTLS_MD2_C)
-        case PSA_ALG_MD2:
-            return( &mbedtls_md2_info );
-#endif
-#if defined(MBEDTLS_MD4_C)
-        case PSA_ALG_MD4:
-            return( &mbedtls_md4_info );
-#endif
 #if defined(MBEDTLS_MD5_C)
         case PSA_ALG_MD5:
             return( &mbedtls_md5_info );
@@ -134,16 +118,6 @@
              * in use. It's ok to call abort on such an object, and there's
              * nothing to do. */
             break;
-#if defined(BUILTIN_ALG_MD2)
-        case PSA_ALG_MD2:
-            mbedtls_md2_free( &operation->ctx.md2 );
-            break;
-#endif
-#if defined(BUILTIN_ALG_MD4)
-        case PSA_ALG_MD4:
-            mbedtls_md4_free( &operation->ctx.md4 );
-            break;
-#endif
 #if defined(BUILTIN_ALG_MD5)
         case PSA_ALG_MD5:
             mbedtls_md5_free( &operation->ctx.md5 );
@@ -200,58 +174,46 @@
 
     switch( alg )
     {
-#if defined(BUILTIN_ALG_MD2)
-        case PSA_ALG_MD2:
-            mbedtls_md2_init( &operation->ctx.md2 );
-            ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
-            break;
-#endif
-#if defined(BUILTIN_ALG_MD4)
-        case PSA_ALG_MD4:
-            mbedtls_md4_init( &operation->ctx.md4 );
-            ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
-            break;
-#endif
 #if defined(BUILTIN_ALG_MD5)
         case PSA_ALG_MD5:
             mbedtls_md5_init( &operation->ctx.md5 );
-            ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
+            ret = mbedtls_md5_starts( &operation->ctx.md5 );
             break;
 #endif
 #if defined(BUILTIN_ALG_RIPEMD160)
         case PSA_ALG_RIPEMD160:
             mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
-            ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
+            ret = mbedtls_ripemd160_starts( &operation->ctx.ripemd160 );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_1)
         case PSA_ALG_SHA_1:
             mbedtls_sha1_init( &operation->ctx.sha1 );
-            ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
+            ret = mbedtls_sha1_starts( &operation->ctx.sha1 );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_224)
         case PSA_ALG_SHA_224:
             mbedtls_sha256_init( &operation->ctx.sha256 );
-            ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
+            ret = mbedtls_sha256_starts( &operation->ctx.sha256, 1 );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_256)
         case PSA_ALG_SHA_256:
             mbedtls_sha256_init( &operation->ctx.sha256 );
-            ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
+            ret = mbedtls_sha256_starts( &operation->ctx.sha256, 0 );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_384)
         case PSA_ALG_SHA_384:
             mbedtls_sha512_init( &operation->ctx.sha512 );
-            ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
+            ret = mbedtls_sha512_starts( &operation->ctx.sha512, 1 );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_512)
         case PSA_ALG_SHA_512:
             mbedtls_sha512_init( &operation->ctx.sha512 );
-            ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
+            ret = mbedtls_sha512_starts( &operation->ctx.sha512, 0 );
             break;
 #endif
         default:
@@ -274,18 +236,6 @@
     {
         case 0:
             return( PSA_ERROR_BAD_STATE );
-#if defined(BUILTIN_ALG_MD2)
-        case PSA_ALG_MD2:
-            mbedtls_md2_clone( &target_operation->ctx.md2,
-                               &source_operation->ctx.md2 );
-            break;
-#endif
-#if defined(BUILTIN_ALG_MD4)
-        case PSA_ALG_MD4:
-            mbedtls_md4_clone( &target_operation->ctx.md4,
-                               &source_operation->ctx.md4 );
-            break;
-#endif
 #if defined(BUILTIN_ALG_MD5)
         case PSA_ALG_MD5:
             mbedtls_md5_clone( &target_operation->ctx.md5,
@@ -347,57 +297,45 @@
 
     switch( operation->alg )
     {
-#if defined(BUILTIN_ALG_MD2)
-        case PSA_ALG_MD2:
-            ret = mbedtls_md2_update_ret( &operation->ctx.md2,
-                                          input, input_length );
-            break;
-#endif
-#if defined(BUILTIN_ALG_MD4)
-        case PSA_ALG_MD4:
-            ret = mbedtls_md4_update_ret( &operation->ctx.md4,
-                                          input, input_length );
-            break;
-#endif
 #if defined(BUILTIN_ALG_MD5)
         case PSA_ALG_MD5:
-            ret = mbedtls_md5_update_ret( &operation->ctx.md5,
+            ret = mbedtls_md5_update( &operation->ctx.md5,
                                           input, input_length );
             break;
 #endif
 #if defined(BUILTIN_ALG_RIPEMD160)
         case PSA_ALG_RIPEMD160:
-            ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
+            ret = mbedtls_ripemd160_update( &operation->ctx.ripemd160,
                                                 input, input_length );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_1)
         case PSA_ALG_SHA_1:
-            ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
+            ret = mbedtls_sha1_update( &operation->ctx.sha1,
                                            input, input_length );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_224)
         case PSA_ALG_SHA_224:
-            ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
+            ret = mbedtls_sha256_update( &operation->ctx.sha256,
                                              input, input_length );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_256)
         case PSA_ALG_SHA_256:
-            ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
+            ret = mbedtls_sha256_update( &operation->ctx.sha256,
                                              input, input_length );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_384)
         case PSA_ALG_SHA_384:
-            ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
+            ret = mbedtls_sha512_update( &operation->ctx.sha512,
                                              input, input_length );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_512)
         case PSA_ALG_SHA_512:
-            ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
+            ret = mbedtls_sha512_update( &operation->ctx.sha512,
                                              input, input_length );
             break;
 #endif
@@ -437,49 +375,39 @@
 
     switch( operation->alg )
     {
-#if defined(BUILTIN_ALG_MD2)
-        case PSA_ALG_MD2:
-            ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
-            break;
-#endif
-#if defined(BUILTIN_ALG_MD4)
-        case PSA_ALG_MD4:
-            ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
-            break;
-#endif
 #if defined(BUILTIN_ALG_MD5)
         case PSA_ALG_MD5:
-            ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
+            ret = mbedtls_md5_finish( &operation->ctx.md5, hash );
             break;
 #endif
 #if defined(BUILTIN_ALG_RIPEMD160)
         case PSA_ALG_RIPEMD160:
-            ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
+            ret = mbedtls_ripemd160_finish( &operation->ctx.ripemd160, hash );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_1)
         case PSA_ALG_SHA_1:
-            ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
+            ret = mbedtls_sha1_finish( &operation->ctx.sha1, hash );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_224)
         case PSA_ALG_SHA_224:
-            ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
+            ret = mbedtls_sha256_finish( &operation->ctx.sha256, hash );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_256)
         case PSA_ALG_SHA_256:
-            ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
+            ret = mbedtls_sha256_finish( &operation->ctx.sha256, hash );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_384)
         case PSA_ALG_SHA_384:
-            ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
+            ret = mbedtls_sha512_finish( &operation->ctx.sha512, hash );
             break;
 #endif
 #if defined(BUILTIN_ALG_SHA_512)
         case PSA_ALG_SHA_512:
-            ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
+            ret = mbedtls_sha512_finish( &operation->ctx.sha512, hash );
             break;
 #endif
         default:
@@ -587,14 +515,6 @@
 {
     switch( alg )
     {
-#if defined(MBEDTLS_PSA_ACCEL_ALG_MD2)
-        case PSA_ALG_MD2:
-            return( 1 );
-#endif
-#if defined(MBEDTLS_PSA_ACCEL_ALG_MD4)
-        case PSA_ALG_MD4:
-            return( 1 );
-#endif
 #if defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
         case PSA_ALG_MD5:
             return( 1 );
diff --git a/library/psa_crypto_invasive.h b/library/psa_crypto_invasive.h
index 1e5a407..1dd9579 100644
--- a/library/psa_crypto_invasive.h
+++ b/library/psa_crypto_invasive.h
@@ -28,11 +28,7 @@
 #ifndef PSA_CRYPTO_INVASIVE_H
 #define PSA_CRYPTO_INVASIVE_H
 
-#if defined(MBEDTLS_CONFIG_FILE)
-#include MBEDTLS_CONFIG_FILE
-#else
-#include "mbedtls/config.h"
-#endif
+#include "mbedtls/build_info.h"
 
 #include "psa/crypto.h"
 #include "common.h"
diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c
index 20c56a0..2c079d4 100644
--- a/library/psa_crypto_mac.c
+++ b/library/psa_crypto_mac.c
@@ -46,10 +46,6 @@
 {
     switch( alg )
     {
-        case PSA_ALG_MD2:
-            return( 16 );
-        case PSA_ALG_MD4:
-            return( 64 );
         case PSA_ALG_MD5:
             return( 64 );
         case PSA_ALG_RIPEMD160:
@@ -359,30 +355,6 @@
     return( status );
 }
 
-static psa_status_t mac_compute(
-    const psa_key_attributes_t *attributes,
-    const uint8_t *key_buffer,
-    size_t key_buffer_size,
-    psa_algorithm_t alg,
-    const uint8_t *input,
-    size_t input_length,
-    uint8_t *mac,
-    size_t mac_size,
-    size_t *mac_length )
-{
-    /* One-shot MAC has not been implemented in this PSA implementation yet. */
-    (void) attributes;
-    (void) key_buffer;
-    (void) key_buffer_size;
-    (void) alg;
-    (void) input;
-    (void) input_length;
-    (void) mac;
-    (void) mac_size;
-    (void) mac_length;
-    return( PSA_ERROR_NOT_SUPPORTED );
-}
-
 static psa_status_t mac_update(
     mbedtls_psa_mac_operation_t *operation,
     const uint8_t *input,
@@ -497,6 +469,44 @@
 
     return( status );
 }
+
+static psa_status_t mac_compute(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *mac,
+    size_t mac_size,
+    size_t *mac_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
+
+    status = mac_setup( &operation,
+                        attributes, key_buffer, key_buffer_size,
+                        alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    if( input_length > 0 )
+    {
+        status = mac_update( &operation, input, input_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
+
+    status = mac_finish_internal( &operation, mac, mac_size );
+    if( status == PSA_SUCCESS )
+        *mac_length = mac_size;
+
+exit:
+    mac_abort( &operation );
+
+    return( status );
+}
+
 #endif /* BUILTIN_ALG_HMAC || BUILTIN_ALG_CMAC */
 
 #if defined(MBEDTLS_PSA_BUILTIN_MAC)
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index b5aec20..2c357c9 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -108,7 +108,8 @@
     /* Parse the data. */
     if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
         status = mbedtls_to_psa_error(
-            mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0 ) );
+            mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0,
+                mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
     else
         status = mbedtls_to_psa_error(
             mbedtls_pk_parse_public_key( &ctx, data, data_length ) );
@@ -317,7 +318,7 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
+    mbedtls_rsa_init( &rsa );
     ret = mbedtls_rsa_gen_key( &rsa,
                                mbedtls_psa_get_random,
                                MBEDTLS_PSA_RANDOM_STATE,
@@ -360,27 +361,14 @@
         return( PSA_ERROR_INVALID_ARGUMENT );
 #endif
 
-#if defined(BUILTIN_ALG_RSA_PKCS1V15_SIGN)
-    /* For PKCS#1 v1.5 signature, if using a hash, the hash length
-     * must be correct. */
-    if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
-        alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
+    /* For signatures using a hash, the hash length must be correct. */
+    if( alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
     {
         if( md_info == NULL )
             return( PSA_ERROR_NOT_SUPPORTED );
         if( mbedtls_md_get_size( md_info ) != hash_length )
             return( PSA_ERROR_INVALID_ARGUMENT );
     }
-#endif /* BUILTIN_ALG_RSA_PKCS1V15_SIGN */
-
-#if defined(BUILTIN_ALG_RSA_PSS)
-    /* PSS requires a hash internally. */
-    if( PSA_ALG_IS_RSA_PSS( alg ) )
-    {
-        if( md_info == NULL )
-            return( PSA_ERROR_NOT_SUPPORTED );
-    }
-#endif /* BUILTIN_ALG_RSA_PSS */
 
     return( PSA_SUCCESS );
 }
@@ -416,29 +404,36 @@
 #if defined(BUILTIN_ALG_RSA_PKCS1V15_SIGN)
     if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
     {
-        mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
-                                 MBEDTLS_MD_NONE );
-        ret = mbedtls_rsa_pkcs1_sign( rsa,
-                                      mbedtls_psa_get_random,
-                                      MBEDTLS_PSA_RANDOM_STATE,
-                                      md_alg,
-                                      (unsigned int) hash_length,
-                                      hash,
-                                      signature );
+        ret = mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
+                                       MBEDTLS_MD_NONE );
+        if( ret == 0 )
+        {
+            ret = mbedtls_rsa_pkcs1_sign( rsa,
+                                          mbedtls_psa_get_random,
+                                          MBEDTLS_PSA_RANDOM_STATE,
+                                          md_alg,
+                                          (unsigned int) hash_length,
+                                          hash,
+                                          signature );
+        }
     }
     else
 #endif /* BUILTIN_ALG_RSA_PKCS1V15_SIGN */
 #if defined(BUILTIN_ALG_RSA_PSS)
     if( PSA_ALG_IS_RSA_PSS( alg ) )
     {
-        mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
-        ret = mbedtls_rsa_rsassa_pss_sign( rsa,
-                                           mbedtls_psa_get_random,
-                                           MBEDTLS_PSA_RANDOM_STATE,
-                                           MBEDTLS_MD_NONE,
-                                           (unsigned int) hash_length,
-                                           hash,
-                                           signature );
+        ret = mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
+
+        if( ret == 0 )
+        {
+            ret = mbedtls_rsa_rsassa_pss_sign( rsa,
+                                               mbedtls_psa_get_random,
+                                               MBEDTLS_PSA_RANDOM_STATE,
+                                               MBEDTLS_MD_NONE,
+                                               (unsigned int) hash_length,
+                                               hash,
+                                               signature );
+        }
     }
     else
 #endif /* BUILTIN_ALG_RSA_PSS */
@@ -489,25 +484,31 @@
 #if defined(BUILTIN_ALG_RSA_PKCS1V15_SIGN)
     if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
     {
-        mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
-                                 MBEDTLS_MD_NONE );
-        ret = mbedtls_rsa_pkcs1_verify( rsa,
-                                        md_alg,
-                                        (unsigned int) hash_length,
-                                        hash,
-                                        signature );
+        ret = mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
+                                       MBEDTLS_MD_NONE );
+        if( ret == 0 )
+        {
+            ret = mbedtls_rsa_pkcs1_verify( rsa,
+                                            md_alg,
+                                            (unsigned int) hash_length,
+                                            hash,
+                                            signature );
+        }
     }
     else
 #endif /* BUILTIN_ALG_RSA_PKCS1V15_SIGN */
 #if defined(BUILTIN_ALG_RSA_PSS)
     if( PSA_ALG_IS_RSA_PSS( alg ) )
     {
-        mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
-        ret = mbedtls_rsa_rsassa_pss_verify( rsa,
-                                             MBEDTLS_MD_NONE,
-                                             (unsigned int) hash_length,
-                                             hash,
-                                             signature );
+        ret = mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
+        if( ret == 0 )
+        {
+            ret = mbedtls_rsa_rsassa_pss_verify( rsa,
+                                                 md_alg,
+                                                 (unsigned int) hash_length,
+                                                 hash,
+                                                 signature );
+        }
     }
     else
 #endif /* BUILTIN_ALG_RSA_PSS */
@@ -610,7 +611,7 @@
 #if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) || \
     defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY)
 
-psa_status_t mbedtls_transparent_test_driver_rsa_import_key(
+psa_status_t mbedtls_test_driver_rsa_import_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *data, size_t data_length,
     uint8_t *key_buffer, size_t key_buffer_size,
@@ -621,7 +622,7 @@
                             key_buffer_length, bits ) );
 }
 
-psa_status_t mbedtls_transparent_test_driver_rsa_export_public_key(
+psa_status_t mbedtls_test_driver_rsa_export_public_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length )
diff --git a/library/psa_crypto_rsa.h b/library/psa_crypto_rsa.h
index 41a90f7..5540684 100644
--- a/library/psa_crypto_rsa.h
+++ b/library/psa_crypto_rsa.h
@@ -218,13 +218,13 @@
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
 
-psa_status_t mbedtls_transparent_test_driver_rsa_import_key(
+psa_status_t mbedtls_test_driver_rsa_import_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *data, size_t data_length,
     uint8_t *key_buffer, size_t key_buffer_size,
     size_t *key_buffer_length, size_t *bits );
 
-psa_status_t mbedtls_transparent_test_driver_rsa_export_public_key(
+psa_status_t mbedtls_test_driver_rsa_export_public_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length );
diff --git a/library/psa_crypto_se.h b/library/psa_crypto_se.h
index 7104261..549dfb6 100644
--- a/library/psa_crypto_se.h
+++ b/library/psa_crypto_se.h
@@ -21,11 +21,7 @@
 #ifndef PSA_CRYPTO_SE_H
 #define PSA_CRYPTO_SE_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "psa/crypto.h"
 #include "psa/crypto_se_driver.h"
diff --git a/library/psa_crypto_service_integration.h b/library/psa_crypto_service_integration.h
deleted file mode 100644
index 87889af..0000000
--- a/library/psa_crypto_service_integration.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Copyright The Mbed TLS Contributors
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-#ifndef PSA_CRYPTO_SERVICE_INTEGRATION_H
-#define PSA_CRYPTO_SERVICE_INTEGRATION_H
-
-/*
- * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM
- * (Secure Partition Manager) integration which separates the code into two
- * parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing
- * Environment). When building for the SPE, an additional header file should be
- * included.
- */
-#if defined(MBEDTLS_PSA_CRYPTO_SPM)
-/*
- * PSA_CRYPTO_SECURE means that the file which included this file is being
- * compiled for SPE. The files crypto_structs.h and crypto_types.h have
- * different implementations for NSPE and SPE and are compiled according to this
- * flag.
- */
-#define PSA_CRYPTO_SECURE 1
-#include "crypto_spe.h"
-#endif // MBEDTLS_PSA_CRYPTO_SPM
-
-#endif // PSA_CRYPTO_SERVICE_INTEGRATION_H
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 0b1a3c1..a18350e 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -22,7 +22,6 @@
 
 #if defined(MBEDTLS_PSA_CRYPTO_C)
 
-#include "psa_crypto_service_integration.h"
 #include "psa/crypto.h"
 
 #include "psa_crypto_core.h"
@@ -392,6 +391,10 @@
         if( status == PSA_ERROR_DOES_NOT_EXIST )
             status = PSA_ERROR_INVALID_HANDLE;
     }
+    else
+        /* Add implicit usage flags. */
+        psa_extend_key_usage_flags( &(*p_slot)->attr.policy.usage );
+
     return( status );
 #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
     return( PSA_ERROR_INVALID_HANDLE );
@@ -409,17 +412,15 @@
         return( PSA_SUCCESS );
     }
 
-    /*
-     * As the return error code may not be handled in case of multiple errors,
-     * do our best to report if the lock counter is equal to zero: if
-     * available call MBEDTLS_PARAM_FAILED that may terminate execution (if
-     * called as part of the execution of a unit test suite this will stop the
-     * test suite execution).
-     */
-#ifdef MBEDTLS_CHECK_PARAMS
-    MBEDTLS_PARAM_FAILED( slot->lock_count > 0 );
-#endif
-
+   /*
+    * As the return error code may not be handled in case of multiple errors,
+    * do our best to report if the lock counter is equal to zero. Assert with
+    * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is strictly greater
+    * than zero: if the MBEDTLS_TEST_HOOKS configuration option is enabled and
+    * the function is called as part of the execution of a test suite, the
+    * execution of the test suite is stopped in error if the assertion fails.
+    */
+    MBEDTLS_TEST_HOOK_TEST_ASSERT( slot->lock_count > 0 );
     return( PSA_ERROR_CORRUPTION_DETECTED );
 }
 
@@ -466,7 +467,10 @@
     {
         /* Persistent keys require storage support */
 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
-        return( PSA_SUCCESS );
+        if( PSA_KEY_LIFETIME_IS_READ_ONLY( lifetime ) )
+            return( PSA_ERROR_INVALID_ARGUMENT );
+        else
+            return( PSA_SUCCESS );
 #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
         return( PSA_ERROR_NOT_SUPPORTED );
 #endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
@@ -475,7 +479,8 @@
 
 psa_status_t psa_open_key( mbedtls_svc_key_id_t key, psa_key_handle_t *handle )
 {
-#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \
+    defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
     psa_status_t status;
     psa_key_slot_t *slot;
 
@@ -493,11 +498,11 @@
 
     return( psa_unlock_key_slot( slot ) );
 
-#else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
+#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
     (void) key;
     *handle = PSA_KEY_HANDLE_INIT;
     return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
+#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
 }
 
 psa_status_t psa_close_key( psa_key_handle_t handle )
@@ -556,16 +561,17 @@
             ++stats->empty_slots;
             continue;
         }
-        if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE )
+        if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
             ++stats->volatile_slots;
-        else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT )
+        else
         {
             psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id );
             ++stats->persistent_slots;
             if( id > stats->max_open_internal_key_id )
                 stats->max_open_internal_key_id = id;
         }
-        else
+        if( PSA_KEY_LIFETIME_GET_LOCATION( slot->attr.lifetime ) !=
+            PSA_KEY_LOCATION_LOCAL_STORAGE )
         {
             psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id );
             ++stats->external_slots;
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index 773d3aa..c6660b9 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -18,18 +18,13 @@
  *  limitations under the License.
  */
 
-#if defined(MBEDTLS_CONFIG_FILE)
-#include MBEDTLS_CONFIG_FILE
-#else
-#include "mbedtls/config.h"
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
 
 #include <stdlib.h>
 #include <string.h>
 
-#include "psa_crypto_service_integration.h"
 #include "psa/crypto.h"
 #include "psa_crypto_storage.h"
 #include "mbedtls/platform_util.h"
@@ -235,48 +230,6 @@
     return( PSA_SUCCESS );
 }
 
-/*
- * 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
-
-/*
- * 16-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT16_LE
-#define GET_UINT16_LE( n, b, i )                        \
-{                                                       \
-    (n) = ( (uint16_t) (b)[(i)    ]       )             \
-        | ( (uint16_t) (b)[(i) + 1] <<  8 );            \
-}
-#endif
-
-#ifndef PUT_UINT16_LE
-#define PUT_UINT16_LE( n, b, i )                                \
-{                                                               \
-    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
-    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
-}
-#endif
-
 /**
  * Persistent key storage magic header.
  */
@@ -303,14 +256,14 @@
         (psa_persistent_key_storage_format *) storage_data;
 
     memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
-    PUT_UINT32_LE( 0, storage_format->version, 0 );
-    PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
-    PUT_UINT16_LE( (uint16_t) attr->type, storage_format->type, 0 );
-    PUT_UINT16_LE( (uint16_t) attr->bits, storage_format->bits, 0 );
-    PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
-    PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
-    PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
-    PUT_UINT32_LE( data_length, storage_format->data_len, 0 );
+    MBEDTLS_PUT_UINT32_LE( 0, storage_format->version, 0 );
+    MBEDTLS_PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
+    MBEDTLS_PUT_UINT16_LE( (uint16_t) attr->type, storage_format->type, 0 );
+    MBEDTLS_PUT_UINT16_LE( (uint16_t) attr->bits, storage_format->bits, 0 );
+    MBEDTLS_PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
+    MBEDTLS_PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
+    MBEDTLS_PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
+    MBEDTLS_PUT_UINT32_LE( data_length, storage_format->data_len, 0 );
     memcpy( storage_format->key_data, data, data_length );
 }
 
@@ -340,11 +293,11 @@
     if( status != PSA_SUCCESS )
         return( status );
 
-    GET_UINT32_LE( version, storage_format->version, 0 );
+    version = MBEDTLS_GET_UINT32_LE( storage_format->version, 0 );
     if( version != 0 )
         return( PSA_ERROR_DATA_INVALID );
 
-    GET_UINT32_LE( *key_data_length, storage_format->data_len, 0 );
+    *key_data_length = MBEDTLS_GET_UINT32_LE( storage_format->data_len, 0 );
     if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
         *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
         return( PSA_ERROR_DATA_INVALID );
@@ -361,12 +314,12 @@
         memcpy( *key_data, storage_format->key_data, *key_data_length );
     }
 
-    GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
-    GET_UINT16_LE( attr->type, storage_format->type, 0 );
-    GET_UINT16_LE( attr->bits, storage_format->bits, 0 );
-    GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
-    GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
-    GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
+    attr->lifetime = MBEDTLS_GET_UINT32_LE( storage_format->lifetime, 0 );
+    attr->type = MBEDTLS_GET_UINT16_LE( storage_format->type, 0 );
+    attr->bits = MBEDTLS_GET_UINT16_LE( storage_format->bits, 0 );
+    attr->policy.usage = MBEDTLS_GET_UINT32_LE( storage_format->policy, 0 );
+    attr->policy.alg = MBEDTLS_GET_UINT32_LE( storage_format->policy, sizeof( uint32_t ) );
+    attr->policy.alg2 = MBEDTLS_GET_UINT32_LE( storage_format->policy, 2 * sizeof( uint32_t ) );
 
     return( PSA_SUCCESS );
 }
diff --git a/library/psa_its_file.c b/library/psa_its_file.c
index 7798da6..c4782cd 100644
--- a/library/psa_its_file.c
+++ b/library/psa_its_file.c
@@ -18,11 +18,7 @@
  *  limitations under the License.
  */
 
-#if defined(MBEDTLS_CONFIG_FILE)
-#include MBEDTLS_CONFIG_FILE
-#else
-#include "mbedtls/config.h"
-#endif
+#include "common.h"
 
 #if defined(MBEDTLS_PSA_ITS_FILE_C)
 
@@ -195,14 +191,8 @@
     size_t n;
 
     memcpy( header.magic, PSA_ITS_MAGIC_STRING, PSA_ITS_MAGIC_LENGTH );
-    header.size[0] = data_length & 0xff;
-    header.size[1] = ( data_length >> 8 ) & 0xff;
-    header.size[2] = ( data_length >> 16 ) & 0xff;
-    header.size[3] = ( data_length >> 24 ) & 0xff;
-    header.flags[0] = create_flags & 0xff;
-    header.flags[1] = ( create_flags >> 8 ) & 0xff;
-    header.flags[2] = ( create_flags >> 16 ) & 0xff;
-    header.flags[3] = ( create_flags >> 24 ) & 0xff;
+    MBEDTLS_PUT_UINT32_LE( data_length, header.size, 0 );
+    MBEDTLS_PUT_UINT32_LE( create_flags, header.flags, 0 );
 
     psa_its_fill_filename( uid, filename );
     stream = fopen( PSA_ITS_STORAGE_TEMP, "wb" );
diff --git a/library/ripemd160.c b/library/ripemd160.c
index 0e1df8f..41d8387 100644
--- a/library/ripemd160.c
+++ b/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 ) );
@@ -89,7 +66,7 @@
 /*
  * RIPEMD-160 context setup
  */
-int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx )
+int mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
 {
     ctx->total[0] = 0;
     ctx->total[1] = 0;
@@ -115,22 +92,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];
@@ -305,7 +282,7 @@
 /*
  * RIPEMD-160 process buffer
  */
-int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
+int mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
                                   const unsigned char *input,
                                   size_t ilen )
 {
@@ -365,7 +342,7 @@
 /*
  * RIPEMD-160 final digest
  */
-int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
+int mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
                                   unsigned char output[20] )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -377,25 +354,25 @@
          | ( 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 );
 
-    ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
+    ret = mbedtls_ripemd160_update( ctx, ripemd160_padding, padn );
     if( ret != 0 )
         return( ret );
 
-    ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
+    ret = mbedtls_ripemd160_update( ctx, msglen, 8 );
     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 );
 }
@@ -405,7 +382,7 @@
 /*
  * output = RIPEMD-160( input buffer )
  */
-int mbedtls_ripemd160_ret( const unsigned char *input,
+int mbedtls_ripemd160( const unsigned char *input,
                            size_t ilen,
                            unsigned char output[20] )
 {
@@ -414,13 +391,13 @@
 
     mbedtls_ripemd160_init( &ctx );
 
-    if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
+    if( ( ret = mbedtls_ripemd160_starts( &ctx ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
+    if( ( ret = mbedtls_ripemd160_update( &ctx, input, ilen ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
+    if( ( ret = mbedtls_ripemd160_finish( &ctx, output ) ) != 0 )
         goto exit;
 
 exit:
@@ -487,7 +464,7 @@
         if( verbose != 0 )
             mbedtls_printf( "  RIPEMD-160 test #%d: ", i + 1 );
 
-        ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
+        ret = mbedtls_ripemd160( ripemd160_test_str[i],
                                      ripemd160_test_strlen[i], output );
         if( ret != 0 )
             goto fail;
diff --git a/library/rsa.c b/library/rsa.c
index 36424bd..e818e6d 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -477,17 +477,14 @@
 /*
  * Initialize an RSA context
  */
-void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
-               int padding,
-               int hash_id )
+void mbedtls_rsa_init( mbedtls_rsa_context *ctx )
 {
     RSA_VALIDATE( ctx != NULL );
-    RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
-                  padding == MBEDTLS_RSA_PKCS_V21 );
 
     memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
 
-    mbedtls_rsa_set_padding( ctx, padding, hash_id );
+    ctx->padding = MBEDTLS_RSA_PKCS_V15;
+    ctx->hash_id = MBEDTLS_MD_NONE;
 
 #if defined(MBEDTLS_THREADING_C)
     /* Set ctx->ver to nonzero to indicate that the mutex has been
@@ -500,15 +497,38 @@
 /*
  * Set padding for an existing RSA context
  */
-void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
-                              int hash_id )
+int mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
+                             mbedtls_md_type_t hash_id )
 {
-    RSA_VALIDATE( ctx != NULL );
-    RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
-                  padding == MBEDTLS_RSA_PKCS_V21 );
+    switch( padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            break;
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            break;
+#endif
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+
+    if( ( padding == MBEDTLS_RSA_PKCS_V21 ) &&
+        ( hash_id != MBEDTLS_MD_NONE ) )
+    {
+        const mbedtls_md_info_t *md_info;
+
+        md_info = mbedtls_md_info_from_type( hash_id );
+        if( md_info == NULL )
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
 
     ctx->padding = padding;
     ctx->hash_id = hash_id;
+
+    return( 0 );
 }
 
 /*
@@ -909,8 +929,11 @@
     RSA_VALIDATE_RET( input  != NULL );
     RSA_VALIDATE_RET( output != NULL );
 
-    if( rsa_check_context( ctx, 1             /* private key checks */,
-                                f_rng != NULL /* blinding y/n       */ ) != 0 )
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    if( rsa_check_context( ctx, 1 /* private key checks */,
+                                1 /* blinding on        */ ) != 0 )
     {
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
     }
@@ -927,15 +950,12 @@
     mbedtls_mpi_init( &Q1 );
     mbedtls_mpi_init( &R );
 
-    if( f_rng != NULL )
-    {
 #if defined(MBEDTLS_RSA_NO_CRT)
-        mbedtls_mpi_init( &D_blind );
+    mbedtls_mpi_init( &D_blind );
 #else
-        mbedtls_mpi_init( &DP_blind );
-        mbedtls_mpi_init( &DQ_blind );
+    mbedtls_mpi_init( &DP_blind );
+    mbedtls_mpi_init( &DQ_blind );
 #endif
-    }
 
 #if !defined(MBEDTLS_RSA_NO_CRT)
     mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
@@ -955,57 +975,54 @@
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
 
-    if( f_rng != NULL )
-    {
-        /*
-         * Blinding
-         * T = T * Vi mod N
-         */
-        MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
+    /*
+     * Blinding
+     * T = T * Vi mod N
+     */
+    MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
 
-        /*
-         * Exponent blinding
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+    /*
+     * Exponent blinding
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
 
 #if defined(MBEDTLS_RSA_NO_CRT)
-        /*
-         * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
-                         f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
+    /*
+     * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                     f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
 
-        D = &D_blind;
+    D = &D_blind;
 #else
-        /*
-         * DP_blind = ( P - 1 ) * R + DP
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
-                         f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
-                    &ctx->DP ) );
+    /*
+     * DP_blind = ( P - 1 ) * R + DP
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                     f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
+                &ctx->DP ) );
 
-        DP = &DP_blind;
+    DP = &DP_blind;
 
-        /*
-         * DQ_blind = ( Q - 1 ) * R + DQ
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
-                         f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
-                    &ctx->DQ ) );
+    /*
+     * DQ_blind = ( Q - 1 ) * R + DQ
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                     f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
+                &ctx->DQ ) );
 
-        DQ = &DQ_blind;
+    DQ = &DQ_blind;
 #endif /* MBEDTLS_RSA_NO_CRT */
-    }
 
 #if defined(MBEDTLS_RSA_NO_CRT)
     MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
@@ -1034,15 +1051,12 @@
     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
 #endif /* MBEDTLS_RSA_NO_CRT */
 
-    if( f_rng != NULL )
-    {
-        /*
-         * Unblind
-         * T = T * Vf mod N
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
-    }
+    /*
+     * Unblind
+     * T = T * Vf mod N
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
 
     /* Verify the result to prevent glitching attacks. */
     MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
@@ -1066,15 +1080,12 @@
     mbedtls_mpi_free( &Q1 );
     mbedtls_mpi_free( &R );
 
-    if( f_rng != NULL )
-    {
 #if defined(MBEDTLS_RSA_NO_CRT)
-        mbedtls_mpi_free( &D_blind );
+    mbedtls_mpi_free( &D_blind );
 #else
-        mbedtls_mpi_free( &DP_blind );
-        mbedtls_mpi_free( &DQ_blind );
+    mbedtls_mpi_free( &DP_blind );
+    mbedtls_mpi_free( &DQ_blind );
 #endif
-    }
 
     mbedtls_mpi_free( &T );
 
@@ -1779,7 +1790,8 @@
         if( md_info == NULL )
             return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-        hashlen = mbedtls_md_get_size( md_info );
+        if( hashlen != mbedtls_md_get_size( md_info ) )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
     }
 
     md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
@@ -1914,14 +1926,13 @@
  * Parameters:
  * - md_alg:  Identifies the hash algorithm used to generate the given hash;
  *            MBEDTLS_MD_NONE if raw data is signed.
- * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE.
+ * - hashlen: Length of hash. Must match md_alg if that's not NONE.
  * - hash:    Buffer containing the hashed message or the raw data.
  * - dst_len: Length of the encoded message.
  * - dst:     Buffer to hold the encoded message.
  *
  * Assumptions:
- * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE.
- * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE.
+ * - hash has size hashlen.
  * - dst points to a buffer of size at least dst_len.
  *
  */
@@ -1946,7 +1957,8 @@
         if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
             return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-        hashlen = mbedtls_md_get_size( md_info );
+        if( hashlen != mbedtls_md_get_size( md_info ) )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
         /* Double-check that 8 + hashlen + oid_size can be used as a
          * 1-byte ASN.1 length encoding and that there's no overflow. */
@@ -2192,7 +2204,8 @@
         if( md_info == NULL )
             return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
-        hashlen = mbedtls_md_get_size( md_info );
+        if( hashlen != mbedtls_md_get_size( md_info ) )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
     }
 
     md_info = mbedtls_md_info_from_type( mgf1_hash_id );
@@ -2580,7 +2593,7 @@
     mbedtls_mpi K;
 
     mbedtls_mpi_init( &K );
-    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
+    mbedtls_rsa_init( &rsa );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N  ) );
     MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
@@ -2654,7 +2667,7 @@
     if( verbose != 0 )
         mbedtls_printf( "  PKCS#1 data sign  : " );
 
-    if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
+    if( mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
     {
         if( verbose != 0 )
             mbedtls_printf( "failed\n" );
@@ -2663,7 +2676,7 @@
     }
 
     if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
-                                MBEDTLS_MD_SHA1, 0,
+                                MBEDTLS_MD_SHA1, 20,
                                 sha1sum, rsa_ciphertext ) != 0 )
     {
         if( verbose != 0 )
@@ -2676,7 +2689,7 @@
     if( verbose != 0 )
         mbedtls_printf( "passed\n  PKCS#1 sig. verify: " );
 
-    if( mbedtls_rsa_pkcs1_verify( &rsa, MBEDTLS_MD_SHA1, 0,
+    if( mbedtls_rsa_pkcs1_verify( &rsa, MBEDTLS_MD_SHA1, 20,
                                   sha1sum, rsa_ciphertext ) != 0 )
     {
         if( verbose != 0 )
diff --git a/library/rsa_alt_helpers.h b/library/rsa_alt_helpers.h
index 90c88a2..d6fc8e5 100644
--- a/library/rsa_alt_helpers.h
+++ b/library/rsa_alt_helpers.h
@@ -55,11 +55,7 @@
 #ifndef MBEDTLS_RSA_INTERNAL_H
 #define MBEDTLS_RSA_INTERNAL_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/bignum.h"
 
diff --git a/library/sha1.c b/library/sha1.c
index c6087ac..6fc9371 100644
--- a/library/sha1.c
+++ b/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 );
@@ -98,7 +75,7 @@
 /*
  * SHA-1 context setup
  */
-int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
+int mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
 {
     SHA1_VALIDATE_RET( ctx != NULL );
 
@@ -126,22 +103,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))))
 
@@ -292,7 +269,7 @@
 /*
  * SHA-1 process buffer
  */
-int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
+int mbedtls_sha1_update( mbedtls_sha1_context *ctx,
                              const unsigned char *input,
                              size_t ilen )
 {
@@ -345,7 +322,7 @@
 /*
  * SHA-1 final digest
  */
-int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
+int mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
                              unsigned char output[20] )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -385,8 +362,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 );
@@ -394,11 +371,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 );
 }
@@ -408,7 +385,7 @@
 /*
  * output = SHA-1( input buffer )
  */
-int mbedtls_sha1_ret( const unsigned char *input,
+int mbedtls_sha1( const unsigned char *input,
                       size_t ilen,
                       unsigned char output[20] )
 {
@@ -420,13 +397,13 @@
 
     mbedtls_sha1_init( &ctx );
 
-    if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
+    if( ( ret = mbedtls_sha1_starts( &ctx ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 )
+    if( ( ret = mbedtls_sha1_update( &ctx, input, ilen ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 )
+    if( ( ret = mbedtls_sha1_finish( &ctx, output ) ) != 0 )
         goto exit;
 
 exit:
@@ -481,7 +458,7 @@
         if( verbose != 0 )
             mbedtls_printf( "  SHA-1 test #%d: ", i + 1 );
 
-        if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
+        if( ( ret = mbedtls_sha1_starts( &ctx ) ) != 0 )
             goto fail;
 
         if( i == 2 )
@@ -490,20 +467,20 @@
 
             for( j = 0; j < 1000; j++ )
             {
-                ret = mbedtls_sha1_update_ret( &ctx, buf, buflen );
+                ret = mbedtls_sha1_update( &ctx, buf, buflen );
                 if( ret != 0 )
                     goto fail;
             }
         }
         else
         {
-            ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i],
+            ret = mbedtls_sha1_update( &ctx, sha1_test_buf[i],
                                            sha1_test_buflen[i] );
             if( ret != 0 )
                 goto fail;
         }
 
-        if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 )
+        if( ( ret = mbedtls_sha1_finish( &ctx, sha1sum ) ) != 0 )
             goto fail;
 
         if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
diff --git a/library/sha256.c b/library/sha256.c
index 3cb2122..c3573f8 100644
--- a/library/sha256.c
+++ b/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 );
@@ -100,7 +77,7 @@
 /*
  * SHA-256 context setup
  */
-int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
+int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
 {
     SHA256_VALIDATE_RET( ctx != NULL );
 
@@ -213,7 +190,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 );
 
@@ -228,7 +205,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 )
     {
@@ -285,7 +262,7 @@
 /*
  * SHA-256 process buffer
  */
-int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
+int mbedtls_sha256_update( mbedtls_sha256_context *ctx,
                                const unsigned char *input,
                                size_t ilen )
 {
@@ -338,7 +315,7 @@
 /*
  * SHA-256 final digest
  */
-int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
+int mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
                                unsigned char *output )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -378,8 +355,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 );
@@ -387,18 +364,18 @@
     /*
      * 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 defined(MBEDTLS_SHA224_C)
     if( ctx->is224 == 0 )
 #endif
-        PUT_UINT32_BE( ctx->state[7], output, 28 );
+        MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
 
     return( 0 );
 }
@@ -408,7 +385,7 @@
 /*
  * output = SHA-256( input buffer )
  */
-int mbedtls_sha256_ret( const unsigned char *input,
+int mbedtls_sha256( const unsigned char *input,
                         size_t ilen,
                         unsigned char *output,
                         int is224 )
@@ -427,13 +404,13 @@
 
     mbedtls_sha256_init( &ctx );
 
-    if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
+    if( ( ret = mbedtls_sha256_starts( &ctx, is224 ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
+    if( ( ret = mbedtls_sha256_update( &ctx, input, ilen ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
+    if( ( ret = mbedtls_sha256_finish( &ctx, output ) ) != 0 )
         goto exit;
 
 exit:
@@ -522,7 +499,7 @@
         if( verbose != 0 )
             mbedtls_printf( "  SHA-%d test #%d: ", 256 - k * 32, j + 1 );
 
-        if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
+        if( ( ret = mbedtls_sha256_starts( &ctx, k ) ) != 0 )
             goto fail;
 
         if( j == 2 )
@@ -531,7 +508,7 @@
 
             for( j = 0; j < 1000; j++ )
             {
-                ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
+                ret = mbedtls_sha256_update( &ctx, buf, buflen );
                 if( ret != 0 )
                     goto fail;
             }
@@ -539,13 +516,13 @@
         }
         else
         {
-            ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
+            ret = mbedtls_sha256_update( &ctx, sha256_test_buf[j],
                                              sha256_test_buflen[j] );
             if( ret != 0 )
                  goto fail;
         }
 
-        if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
+        if( ( ret = mbedtls_sha256_finish( &ctx, sha256sum ) ) != 0 )
             goto fail;
 
 
diff --git a/library/sha512.c b/library/sha512.c
index 315e516..2b4cc54 100644
--- a/library/sha512.c
+++ b/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 )
@@ -123,7 +92,7 @@
 /*
  * SHA-512 context setup
  */
-int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
+int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
 {
     SHA512_VALIDATE_RET( ctx != NULL );
 #if defined(MBEDTLS_SHA384_C)
@@ -261,7 +230,7 @@
     {
         if( i < 16 )
         {
-            GET_UINT64_BE( local.W[i], data, i << 3 );
+            local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
         }
         else
         {
@@ -281,7 +250,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++ )
@@ -327,7 +296,7 @@
 /*
  * SHA-512 process buffer
  */
-int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
+int mbedtls_sha512_update( mbedtls_sha512_context *ctx,
                                const unsigned char *input,
                                size_t ilen )
 {
@@ -379,7 +348,7 @@
 /*
  * SHA-512 final digest
  */
-int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
+int mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
                                unsigned char *output )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@@ -451,7 +420,7 @@
 /*
  * output = SHA-512( input buffer )
  */
-int mbedtls_sha512_ret( const unsigned char *input,
+int mbedtls_sha512( const unsigned char *input,
                     size_t ilen,
                     unsigned char *output,
                     int is384 )
@@ -469,13 +438,13 @@
 
     mbedtls_sha512_init( &ctx );
 
-    if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
+    if( ( ret = mbedtls_sha512_starts( &ctx, is384 ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
+    if( ( ret = mbedtls_sha512_update( &ctx, input, ilen ) ) != 0 )
         goto exit;
 
-    if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
+    if( ( ret = mbedtls_sha512_finish( &ctx, output ) ) != 0 )
         goto exit;
 
 exit:
@@ -591,7 +560,7 @@
         if( verbose != 0 )
             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
 
-        if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
+        if( ( ret = mbedtls_sha512_starts( &ctx, k ) ) != 0 )
             goto fail;
 
         if( j == 2 )
@@ -600,20 +569,20 @@
 
             for( j = 0; j < 1000; j++ )
             {
-                ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
+                ret = mbedtls_sha512_update( &ctx, buf, buflen );
                 if( ret != 0 )
                     goto fail;
             }
         }
         else
         {
-            ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
+            ret = mbedtls_sha512_update( &ctx, sha512_test_buf[j],
                                              sha512_test_buflen[j] );
             if( ret != 0 )
                 goto fail;
         }
 
-        if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
+        if( ( ret = mbedtls_sha512_finish( &ctx, sha512sum ) ) != 0 )
             goto fail;
 
         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index ac2c50a..b10a963 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -31,13 +31,14 @@
 
 #include "mbedtls/ssl_ciphersuites.h"
 #include "mbedtls/ssl.h"
+#include "ssl_misc.h"
 
 #include <string.h>
 
 /*
  * Ordered from most preferred to least preferred in terms of security.
  *
- * Current rule (except RC4 and 3DES, weak and null which come last):
+ * Current rule (except weak and null which come last):
  * 1. By key exchange:
  *    Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK
  * 2. By key length and cipher:
@@ -51,6 +52,15 @@
 #if defined(MBEDTLS_SSL_CIPHERSUITES)
     MBEDTLS_SSL_CIPHERSUITES,
 #else
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    /* TLS 1.3 ciphersuites */
+    MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
+    MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
+    MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
+    MBEDTLS_TLS1_3_AES_128_CCM_SHA256,
+    MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256,
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
     /* Chacha-Poly ephemeral suites */
     MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
@@ -254,18 +264,6 @@
     MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
     MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
 
-    /* 3DES suites */
-    MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
-    MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
-
     /* NULL suites */
     MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
     MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA,
@@ -294,6 +292,52 @@
 
 static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
 {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA384_C)
+    { MBEDTLS_TLS1_3_AES_256_GCM_SHA384, "TLS1-3-AES-256-GCM-SHA384",
+    MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384,
+    MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
+    MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+    MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+    0 },
+#endif /* MBEDTLS_SHA384_C */
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS1_3_AES_128_GCM_SHA256, "TLS1-3-AES-128-GCM-SHA256",
+    MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256,
+    MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
+    MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+    MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+    0 },
+#endif /* MBEDTLS_SHA256_C */
+#endif /* MBEDTLS_GCM_C */
+#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS1_3_AES_128_CCM_SHA256, "TLS1-3-AES-128-CCM-SHA256",
+    MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256,
+    MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
+    MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+    MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+    0 },
+    { MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256, "TLS1-3-AES-128-CCM-8-SHA256",
+    MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256,
+    MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
+    MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+    MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+    MBEDTLS_CIPHERSUITE_SHORT_TAG },
+#endif /* MBEDTLS_SHA256_C && MBEDTLS_CCM_C */
+#endif /* MBEDTLS_AES_C */
+#if defined(MBEDTLS_CHACHAPOLY_C) && defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
+      "TLS1-3-CHACHA20-POLY1305-SHA256",
+      MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
+      MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4,
+      0 },
+#endif /* MBEDTLS_CHACHAPOLY_C && MBEDTLS_SHA256_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 #if defined(MBEDTLS_CHACHAPOLY_C) && \
     defined(MBEDTLS_SHA256_C) && \
     defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -369,12 +413,12 @@
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
     { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -440,14 +484,14 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -471,23 +515,11 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA1_C */
@@ -500,12 +532,12 @@
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
     { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -549,14 +581,14 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -580,23 +612,11 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA1_C */
@@ -642,13 +662,13 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 
     { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA1_C */
@@ -696,13 +716,13 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 
     { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA1_C */
@@ -726,17 +746,6 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
@@ -778,13 +787,13 @@
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 
     { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -832,13 +841,13 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 
     { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA1_C */
@@ -863,18 +872,6 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
@@ -883,12 +880,12 @@
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
     { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -932,14 +929,14 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -963,23 +960,11 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA1_C */
@@ -992,12 +977,12 @@
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
     { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -1041,14 +1026,14 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -1072,23 +1057,11 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA1_C */
@@ -1119,7 +1092,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
@@ -1127,7 +1100,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -1135,13 +1108,13 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 
     { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA1_C */
@@ -1175,7 +1148,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
@@ -1183,7 +1156,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -1208,18 +1181,6 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
@@ -1246,7 +1207,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
@@ -1254,7 +1215,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -1262,13 +1223,13 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 
     { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA1_C */
@@ -1302,7 +1263,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
@@ -1310,7 +1271,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -1335,18 +1296,6 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
@@ -1356,7 +1305,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
@@ -1364,7 +1313,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -1372,13 +1321,13 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 
     { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA1_C */
@@ -1390,7 +1339,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
@@ -1398,25 +1347,13 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
 #endif /* MBEDTLS_CIPHER_MODE_CBC */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
@@ -1443,7 +1380,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
@@ -1451,7 +1388,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -1459,13 +1396,13 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA",
       MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 
     { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA",
       MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA1_C */
@@ -1477,7 +1414,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256",
       MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA256_C */
@@ -1485,7 +1422,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
 #endif /* MBEDTLS_SHA384_C */
@@ -1510,18 +1447,6 @@
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
-#if defined(MBEDTLS_DES_C)
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-#if defined(MBEDTLS_SHA1_C)
-    { MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA",
-      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
-      0 },
-#endif /* MBEDTLS_SHA1_C */
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* MBEDTLS_DES_C */
-
 #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1541,7 +1466,7 @@
 #if defined(MBEDTLS_MD5_C)
     { MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif
@@ -1549,7 +1474,7 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif
@@ -1557,7 +1482,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif
@@ -1567,7 +1492,7 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA1_C */
@@ -1575,7 +1500,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif
@@ -1583,7 +1508,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA384_C */
@@ -1593,7 +1518,7 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA1_C */
@@ -1601,7 +1526,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif
@@ -1609,7 +1534,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA384_C */
@@ -1619,7 +1544,7 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA1_C */
@@ -1627,7 +1552,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif
@@ -1635,7 +1560,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA384_C */
@@ -1645,7 +1570,7 @@
 #if defined(MBEDTLS_SHA1_C)
     { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA1_C */
@@ -1653,7 +1578,7 @@
 #if defined(MBEDTLS_SHA256_C)
     { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif
@@ -1661,7 +1586,7 @@
 #if defined(MBEDTLS_SHA384_C)
     { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384",
       MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
-      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_CIPHERSUITE_WEAK },
 #endif /* MBEDTLS_SHA384_C */
@@ -2047,14 +1972,6 @@
 {
     (void)cs_info;
 
-#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES)
-    if( cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_ECB ||
-        cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_CBC )
-    {
-        return( 1 );
-    }
-#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */
-
     return( 0 );
 }
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 6cf283e..9120aa2 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -136,18 +136,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 );
 
@@ -181,14 +182,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 );
 
@@ -283,14 +282,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;
 
@@ -354,20 +353,18 @@
          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;
 
@@ -388,10 +385,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;
@@ -427,8 +422,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 +465,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;
 
@@ -510,11 +505,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 );
@@ -543,10 +538,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;
@@ -559,36 +552,6 @@
 }
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
-                                         unsigned char *buf,
-                                         const unsigned char *end,
-                                         size_t *olen )
-{
-    unsigned char *p = buf;
-
-    *olen = 0;
-
-    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
-        return( 0 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 3,
-        ( "client hello, adding truncated_hmac extension" ) );
-
-    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 );
-
-    *p++ = 0x00;
-    *p++ = 0x00;
-
-    *olen = 4;
-
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
 static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
                                            unsigned char *buf,
@@ -607,8 +570,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;
@@ -637,10 +600,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;
@@ -671,11 +632,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;
 
@@ -715,8 +676,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>;
@@ -743,12 +704,10 @@
     *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 );
 }
@@ -800,12 +759,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:
@@ -816,8 +774,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;
@@ -829,8 +786,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
         {
@@ -898,10 +855,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 ) );
@@ -1155,8 +1110,7 @@
     /*
      * Ciphersuite list
      */
-    ciphersuites = mbedtls_ssl_get_protocol_version_ciphersuites( ssl->conf,
-                                                                ssl->minor_ver );
+    ciphersuites = ssl->conf->ciphersuite_list;
 
     /* Skip writing ciphersuite length for now */
     n = 0;
@@ -1185,8 +1139,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,
@@ -1201,8 +1155,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++;
     }
 
@@ -1305,16 +1259,6 @@
     ext_len += olen;
 #endif
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-    if( ( ret = ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len,
-                                              end, &olen ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_truncated_hmac_ext", ret );
-        return( ret );
-    }
-    ext_len += olen;
-#endif
-
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
     if( ( ret = ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len,
                                                 end, &olen ) ) != 0 )
@@ -1375,9 +1319,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;
@@ -1431,7 +1374,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
     }
     else
@@ -1445,7 +1388,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
 
         ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
@@ -1472,39 +1415,14 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     return( 0 );
 }
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
-                                         const unsigned char *buf,
-                                         size_t len )
-{
-    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
-        len != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1,
-            ( "non-matching truncated HMAC extension" ) );
-        mbedtls_ssl_send_alert_message(
-            ssl,
-            MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
-    }
-
-    ((void) buf);
-
-    ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
-
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
 static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
                               const unsigned char *buf,
@@ -1519,16 +1437,16 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension unexpected" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     if( len == 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     peer_cid_len = *buf++;
@@ -1538,16 +1456,16 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+                                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     if( len != peer_cid_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
@@ -1574,8 +1492,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     ((void) buf);
@@ -1599,8 +1517,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     ((void) buf);
@@ -1624,8 +1542,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     ((void) buf);
@@ -1650,7 +1568,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     list_size = buf[0];
 
@@ -1664,7 +1582,8 @@
             ssl->handshake->ecdh_ctx.point_format = p[0];
 #endif
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-            ssl->handshake->ecjpake_ctx.point_format = p[0];
+            mbedtls_ecjpake_set_point_format( &ssl->handshake->ecjpake_ctx,
+                                              p[0] );
 #endif
             MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
             return( 0 );
@@ -1677,7 +1596,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
     mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-    return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
 }
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
@@ -1730,8 +1649,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+        return( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION );
     }
 
     /*
@@ -1749,7 +1668,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     list_len = ( buf[0] << 8 ) | buf[1];
@@ -1757,7 +1676,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     name_len = buf[2];
@@ -1765,7 +1684,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Check that the server chosen protocol was in our list and save it */
@@ -1782,7 +1701,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) );
     mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-    return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
@@ -1824,7 +1743,7 @@
      *                                      and optional srtp_mki
      */
     if( ( len < 5 ) || ( len != ( buf[4] + 5u ) ) )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     /*
      * get the server protection profile
@@ -1835,7 +1754,7 @@
      * one protection profile in server Hello
      */
     if( (  buf[0] != 0 ) || ( buf[1] != 2 ) )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
     server_protection = mbedtls_ssl_check_srtp_profile_value(
@@ -1869,7 +1788,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     /* If server does not use mki in its reply, make sure the client won't keep
@@ -1890,7 +1809,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 #if defined (MBEDTLS_DEBUG_C)
     if( len > 5 )
@@ -1925,7 +1844,7 @@
             ( "incoming HelloVerifyRequest message is too short" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -1952,7 +1871,7 @@
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
 
-        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
     }
 
     cookie_len = *p++;
@@ -1962,7 +1881,7 @@
             ( "cookie length does not match incoming message size" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                     MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
 
@@ -2070,7 +1989,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -2089,6 +2008,7 @@
     MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
     mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
                       ssl->conf->transport, buf + 0 );
+    ssl->session_negotiate->minor_ver = ssl->minor_ver;
 
     if( ssl->major_ver < ssl->conf->min_major_ver ||
         ssl->minor_ver < ssl->conf->min_minor_ver ||
@@ -2106,7 +2026,7 @@
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
 
-        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu",
@@ -2126,7 +2046,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n )
@@ -2142,7 +2062,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
     }
     else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n )
@@ -2154,7 +2074,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* ciphersuite (used later) */
@@ -2244,17 +2164,17 @@
     i = 0;
     while( 1 )
     {
-        if( mbedtls_ssl_get_protocol_version_ciphersuites( ssl->conf, ssl->minor_ver )[i] == 0 )
+        if( ssl->conf->ciphersuite_list[i] == 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
             mbedtls_ssl_send_alert_message(
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
-        if( mbedtls_ssl_get_protocol_version_ciphersuites( ssl->conf, ssl->minor_ver )[i++] ==
+        if( ssl->conf->ciphersuite_list[i++] ==
             ssl->session_negotiate->ciphersuite )
         {
             break;
@@ -2270,8 +2190,8 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3,
@@ -2293,7 +2213,7 @@
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
     ssl->session_negotiate->compression = comp;
 
@@ -2315,7 +2235,7 @@
             mbedtls_ssl_send_alert_message(
                 ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         switch( ext_id )
@@ -2346,19 +2266,6 @@
             break;
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-        case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
-            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
-
-            if( ( ret = ssl_parse_truncated_hmac_ext( ssl,
-                            ext + 4, ext_size ) ) != 0 )
-            {
-                return( ret );
-            }
-
-            break;
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
         case MBEDTLS_TLS_EXT_CID:
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) );
@@ -2473,7 +2380,7 @@
         if( ext_len > 0 && ext_len < 4 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
     }
 
@@ -2521,7 +2428,7 @@
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
@@ -2554,13 +2461,13 @@
         return( ret );
     }
 
-    dhm_actual_bitlen = mbedtls_mpi_bitlen( &ssl->handshake->dhm_ctx.P );
+    dhm_actual_bitlen = mbedtls_dhm_get_bitlen( &ssl->handshake->dhm_ctx );
     if( dhm_actual_bitlen < ssl->conf->dhm_min_bitlen )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u",
                                     dhm_actual_bitlen,
                                     ssl->conf->dhm_min_bitlen ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P  );
@@ -2632,11 +2539,11 @@
      */
 
     if( end - *p < 4 )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     /* First byte is curve_type; only named_curve is handled */
     if( *(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
 
     /* Next two bytes are the namedcurve value */
     tls_id = *(*p)++;
@@ -2647,10 +2554,10 @@
     if( ( handshake->ecdh_psa_type =
           mbedtls_psa_parse_tls_ecc_group( tls_id, &ecdh_bits ) ) == 0 )
     {
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
     if( ecdh_bits > 0xffff )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     handshake->ecdh_bits = (uint16_t) ecdh_bits;
 
     /*
@@ -2659,7 +2566,7 @@
 
     ecpoint_len = *(*p)++;
     if( (size_t)( end - *p ) < ecpoint_len )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     if( mbedtls_psa_tls_ecpoint_to_psa_ec(
                                     *p, ecpoint_len,
@@ -2709,7 +2616,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "bad server key exchange message (ECDHE curve)" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     return( ret );
@@ -2736,7 +2643,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "bad server key exchange message (psk_identity_hint length)" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     len = (*p)[0] << 8 | (*p)[1];
     *p += 2;
@@ -2745,7 +2652,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "bad server key exchange message (psk_identity_hint length)" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -2833,8 +2740,7 @@
 #if 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
@@ -2869,7 +2775,7 @@
     }
 
     if( (*p) + 2 > end )
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     /*
      * Get hash algorithm
@@ -2879,7 +2785,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "Server used unsupported HashAlgorithm %d", *(p)[0] ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     /*
@@ -2890,7 +2796,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     /*
@@ -2900,7 +2806,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "server used HashAlgorithm %d that was not offered", *(p)[0] ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d",
@@ -2954,7 +2860,7 @@
     if( ssl_check_server_ecdh_params( ssl ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
     }
 
 #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
@@ -3084,8 +2990,8 @@
             mbedtls_ssl_send_alert_message(
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
     } /* FALLTROUGH */
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
@@ -3110,7 +3016,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
     }
     else
@@ -3129,7 +3035,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
     }
     else
@@ -3150,7 +3056,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
     }
     else
@@ -3168,8 +3074,8 @@
             mbedtls_ssl_send_alert_message(
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
     }
     else
@@ -3207,7 +3113,7 @@
                     ssl,
                     MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-                return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+                return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
             }
 
             if( pk_alg !=
@@ -3219,7 +3125,7 @@
                     ssl,
                     MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-                return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+                return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
             }
         }
         else
@@ -3240,7 +3146,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
         sig_len = ( p[0] << 8 ) | p[1];
         p += 2;
@@ -3252,7 +3158,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
@@ -3441,7 +3347,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
     n = cert_type_len;
@@ -3461,7 +3367,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* supported_signature_algorithms */
@@ -3496,7 +3402,7 @@
                 ssl,
                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
 #if defined(MBEDTLS_DEBUG_C)
@@ -3523,7 +3429,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
 exit:
@@ -3557,7 +3463,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     ssl->state++;
@@ -3589,14 +3495,13 @@
         /*
          * DHM key exchange -- send G^X mod P
          */
-        content_len = ssl->handshake->dhm_ctx.len;
+        content_len = mbedtls_dhm_get_len( &ssl->handshake->dhm_ctx );
 
-        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,
-                          (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
+                          (int) mbedtls_dhm_get_len( &ssl->handshake->dhm_ctx ),
                           &ssl->out_msg[header_len], content_len,
                           ssl->conf->f_rng, ssl->conf->p_rng );
         if( ret != 0 )
@@ -3807,8 +3712,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,
@@ -3849,7 +3754,7 @@
             /*
              * ClientDiffieHellmanPublic public (DHM send G^X mod P)
              */
-            content_len = ssl->handshake->dhm_ctx.len;
+            content_len = mbedtls_dhm_get_len( &ssl->handshake->dhm_ctx );
 
             if( header_len + 2 + content_len >
                 MBEDTLS_SSL_OUT_CONTENT_LEN )
@@ -3859,11 +3764,11 @@
                 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 ),
+                    (int) mbedtls_dhm_get_len( &ssl->handshake->dhm_ctx ),
                     &ssl->out_msg[header_len], content_len,
                     ssl->conf->f_rng, ssl->conf->p_rng );
             if( ret != 0 )
@@ -4026,6 +3931,11 @@
     mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
     size_t hashlen;
     void *rs_ctx = NULL;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+    size_t out_buf_len = ssl->out_buf_len - ( ssl->out_msg - ssl->out_buf );
+#else
+    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - ( ssl->out_msg - ssl->out_buf );
+#endif
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
 
@@ -4124,7 +4034,9 @@
 
     if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ),
                          md_alg, hash_start, hashlen,
-                         ssl->out_msg + 6 + offset, &n,
+                         ssl->out_msg + 6 + offset,
+                         out_buf_len - 6 - offset,
+                         &n,
                          ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
@@ -4135,8 +4047,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;
@@ -4199,7 +4110,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
@@ -4214,7 +4125,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len ) );
@@ -4280,23 +4191,8 @@
 {
     int ret = 0;
 
-    if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
 
-    if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
-        return( ret );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
-        ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
-    {
-        if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
-            return( ret );
-    }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
     /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
      * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index 40b8913..986b141 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -165,10 +165,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)
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 1f1de2b..7035c27 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -22,11 +22,7 @@
 #ifndef MBEDTLS_SSL_MISC_H
 #define MBEDTLS_SSL_MISC_H
 
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "mbedtls/build_info.h"
 
 #include "mbedtls/ssl.h"
 #include "mbedtls/cipher.h"
@@ -65,6 +61,17 @@
 #define inline __inline
 #endif
 
+/* Legacy minor version numbers as defined by:
+ * - RFC 2246: ProtocolVersion version = { 3, 1 };     // TLS v1.0
+ * - RFC 4346: ProtocolVersion version = { 3, 2 };     // TLS v1.1
+ *
+ * We no longer support these versions, but some code still references those
+ * constants as part of negotiating with the peer, so keep them available
+ * internally.
+ */
+#define MBEDTLS_SSL_MINOR_VERSION_1             1
+#define MBEDTLS_SSL_MINOR_VERSION_2             2
+
 /* Determine minimum supported version */
 #define MBEDTLS_SSL_MIN_MAJOR_VERSION           MBEDTLS_SSL_MAJOR_VERSION_3
 
@@ -96,6 +103,61 @@
 #define MBEDTLS_SSL_RENEGOTIATION_PENDING       3   /* Requested (server only) */
 
 /*
+ * Mask of TLS 1.3 handshake extensions used in extensions_present
+ * of mbedtls_ssl_handshake_params.
+ */
+#define MBEDTLS_SSL_EXT_NONE                        0
+
+#define MBEDTLS_SSL_EXT_SERVERNAME                  ( 1 <<  0 )
+#define MBEDTLS_SSL_EXT_MAX_FRAGMENT_LENGTH         ( 1 <<  1 )
+#define MBEDTLS_SSL_EXT_STATUS_REQUEST              ( 1 <<  2 )
+#define MBEDTLS_SSL_EXT_SUPPORTED_GROUPS            ( 1 <<  3 )
+#define MBEDTLS_SSL_EXT_SIG_ALG                     ( 1 <<  4 )
+#define MBEDTLS_SSL_EXT_USE_SRTP                    ( 1 <<  5 )
+#define MBEDTLS_SSL_EXT_HEARTBEAT                   ( 1 <<  6 )
+#define MBEDTLS_SSL_EXT_ALPN                        ( 1 <<  7 )
+#define MBEDTLS_SSL_EXT_SCT                         ( 1 <<  8 )
+#define MBEDTLS_SSL_EXT_CLI_CERT_TYPE               ( 1 <<  9 )
+#define MBEDTLS_SSL_EXT_SERV_CERT_TYPE              ( 1 << 10 )
+#define MBEDTLS_SSL_EXT_PADDING                     ( 1 << 11 )
+#define MBEDTLS_SSL_EXT_PRE_SHARED_KEY              ( 1 << 12 )
+#define MBEDTLS_SSL_EXT_EARLY_DATA                  ( 1 << 13 )
+#define MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS          ( 1 << 14 )
+#define MBEDTLS_SSL_EXT_COOKIE                      ( 1 << 15 )
+#define MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES      ( 1 << 16 )
+#define MBEDTLS_SSL_EXT_CERT_AUTH                   ( 1 << 17 )
+#define MBEDTLS_SSL_EXT_OID_FILTERS                 ( 1 << 18 )
+#define MBEDTLS_SSL_EXT_POST_HANDSHAKE_AUTH         ( 1 << 19 )
+#define MBEDTLS_SSL_EXT_SIG_ALG_CERT                ( 1 << 20 )
+#define MBEDTLS_SSL_EXT_KEY_SHARE                   ( 1 << 21 )
+
+/*
+ * Helper macros for function call with return check.
+ */
+/*
+ * Exit when return non-zero value
+ */
+#define MBEDTLS_SSL_PROC_CHK( f )                               \
+    do {                                                        \
+        ret = ( f );                                            \
+        if( ret != 0 )                                          \
+        {                                                       \
+            goto cleanup;                                       \
+        }                                                       \
+    } while( 0 )
+/*
+ * Exit when return negative value
+ */
+#define MBEDTLS_SSL_PROC_CHK_NEG( f )                           \
+    do {                                                        \
+        ret = ( f );                                            \
+        if( ret < 0 )                                           \
+        {                                                       \
+            goto cleanup;                                       \
+        }                                                       \
+    } while( 0 )
+
+/*
  * DTLS retransmission states, see RFC 6347 4.2.4
  *
  * The SENDING state is merged in PREPARING for initial sends,
@@ -164,7 +226,7 @@
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-#define MBEDTLS_SSL_MAX_CID_EXPANSION      MBEDTLS_SSL_CID_PADDING_GRANULARITY
+#define MBEDTLS_SSL_MAX_CID_EXPANSION      MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY
 #else
 #define MBEDTLS_SSL_MAX_CID_EXPANSION        0
 #endif
@@ -245,6 +307,39 @@
       + ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) )
 #endif
 
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+/**
+ * \brief          Return the maximum fragment length (payload, in bytes) for
+ *                 the output buffer. For the client, this is the configured
+ *                 value. For the server, it is the minimum of two - the
+ *                 configured value and the negotiated one.
+ *
+ * \sa             mbedtls_ssl_conf_max_frag_len()
+ * \sa             mbedtls_ssl_get_max_out_record_payload()
+ *
+ * \param ssl      SSL context
+ *
+ * \return         Current maximum fragment length for the output buffer.
+ */
+size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Return the maximum fragment length (payload, in bytes) for
+ *                 the input buffer. This is the negotiated maximum fragment
+ *                 length, or, if there is none, MBEDTLS_SSL_IN_CONTENT_LEN.
+ *                 If it is not defined either, the value is 2^14. This function
+ *                 works as its predecessor, \c mbedtls_ssl_get_max_frag_len().
+ *
+ * \sa             mbedtls_ssl_conf_max_frag_len()
+ * \sa             mbedtls_ssl_get_max_in_record_payload()
+ *
+ * \param ssl      SSL context
+ *
+ * \return         Current maximum fragment length for the output buffer.
+ */
+size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
 static inline size_t mbedtls_ssl_get_output_buflen( const mbedtls_ssl_context *ctx )
 {
@@ -522,6 +617,13 @@
     uint16_t mtu;                       /*!<  Handshake mtu, used to fragment outgoing messages */
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    /*! TLS 1.3 transforms for 0-RTT and encrypted handshake messages.
+     *  Those pointers own the transforms they reference. */
+    mbedtls_ssl_transform *transform_handshake;
+    mbedtls_ssl_transform *transform_earlydata;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
     /*
      * Checksum contexts
      */
@@ -559,6 +661,11 @@
     int max_major_ver;                  /*!< max. major version client*/
     int max_minor_ver;                  /*!< max. minor version client*/
     int cli_exts;                       /*!< client extension presence*/
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    int extensions_present;             /*!< extension presence; Each bitfield
+                                             represents an extension and defined
+                                             as \c MBEDTLS_SSL_EXT_XXX */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
     int new_session_ticket;             /*!< use NewSessionTicket?    */
@@ -587,20 +694,14 @@
  * Representation of decryption/encryption transformations on records
  *
  * There are the following general types of record transformations:
- * - Stream transformations (TLS versions <= 1.2 only)
+ * - Stream transformations (TLS versions == 1.2 only)
  *   Transformation adding a MAC and applying a stream-cipher
  *   to the authenticated message.
- * - CBC block cipher transformations ([D]TLS versions <= 1.2 only)
- *   In addition to the distinction of the order of encryption and
- *   authentication, there's a fundamental difference between the
- *   handling in TLS 1.0 and TLS 1.1 and TLS 1.2: For TLS 1.0,
- *   the final IV after processing a record is used
- *   as the IV for the next record. No explicit IV is contained
- *   in an encrypted record. The IV for the first record is extracted
- *   at key extraction time. In contrast, for TLS 1.1 and 1.2, no
- *   IV is generated at key extraction time, but every encrypted
- *   record is explicitly prefixed by the IV with which it was encrypted.
- * - AEAD transformations ([D]TLS versions >= 1.2 only)
+ * - CBC block cipher transformations ([D]TLS versions == 1.2 only)
+ *   For TLS 1.2, no IV is generated at key extraction time, but every
+ *   encrypted record is explicitly prefixed by the IV with which it was
+ *   encrypted.
+ * - AEAD transformations ([D]TLS versions == 1.2 only)
  *   These come in two fundamentally different versions, the first one
  *   used in TLS 1.2, excluding ChaChaPoly ciphersuites, and the second
  *   one used for ChaChaPoly ciphersuites in TLS 1.2 as well as for TLS 1.3.
@@ -623,19 +724,13 @@
  * - For stream/CBC, (static) encryption/decryption keys for the digest.
  * - For AEAD transformations, the size (potentially 0) of an explicit,
  *   random initialization vector placed in encrypted records.
- * - For some transformations (currently AEAD and CBC in TLS 1.0)
- *   an implicit IV. It may be static (e.g. AEAD) or dynamic (e.g. CBC)
+ * - For some transformations (currently AEAD) an implicit IV. It is static
  *   and (if present) is combined with the explicit IV in a transformation-
- *   dependent way (e.g. appending in TLS 1.2 and XOR'ing in TLS 1.3).
+ *   -dependent way (e.g. appending in TLS 1.2 and XOR'ing in TLS 1.3).
  * - For stream/CBC, a flag determining the order of encryption and MAC.
  * - The details of the transformation depend on the SSL/TLS version.
  * - The length of the authentication tag.
  *
- * Note: Except for CBC in TLS 1.0, these parameters are
- *       constant across multiple encryption/decryption operations.
- *       For CBC, the implicit IV needs to be updated after each
- *       operation.
- *
  * The struct below refines this abstract view as follows:
  * - The cipher underlying the transformation is managed in
  *   cipher contexts cipher_ctx_{enc/dec}, which must have the
@@ -648,11 +743,9 @@
  * - For stream/CBC transformations, the message digest contexts
  *   used for the MAC's are stored in md_ctx_{enc/dec}. These contexts
  *   are unused for AEAD transformations.
- * - For stream/CBC transformations and versions >= TLS 1.0, the
- *   MAC keys are not stored explicitly but maintained within
- *   md_ctx_{enc/dec}.
- * - The mac_enc and mac_dec fields are unused for EAD transformations or
- *   transformations >= TLS 1.0.
+ * - For stream/CBC transformations, the MAC keys are not stored explicitly
+ *   but maintained within md_ctx_{enc/dec}.
+ * - The mac_enc and mac_dec fields are unused for EAD transformations.
  * - For transformations using an implicit IV maintained within
  *   the transformation context, its contents are stored within
  *   iv_{enc/dec}.
@@ -666,10 +759,6 @@
  *   and indicates the length of the static part of the IV which is
  *   constant throughout the communication, and which is stored in
  *   the first fixed_ivlen bytes of the iv_{enc/dec} arrays.
- *   Note: For CBC in TLS 1.0, the fields iv_{enc/dec}
- *   still store IV's for continued use across multiple transformations,
- *   so it is not true that fixed_ivlen == 0 means that iv_{enc/dec} are
- *   not being used!
  * - minor_ver denotes the SSL/TLS version
  * - For stream/CBC transformations, maclen denotes the length of the
  *   authentication tag, while taglen is unused and 0.
@@ -718,7 +807,8 @@
 
 #if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
     /* We need the Hello random bytes in order to re-derive keys from the
-     * Master Secret and other session info, see ssl_populate_transform() */
+     * Master Secret and other session info,
+     * see ssl_tls12_populate_transform() */
     unsigned char randbytes[64]; /*!< ServerHello.random+ClientHello.random */
 #endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
 };
@@ -749,7 +839,7 @@
  *     pre-expansion during record protection. Concretely,
  *     this is the length of the fixed part of the explicit IV
  *     used for encryption, or 0 if no explicit IV is used
- *     (e.g. for CBC in TLS 1.0, or stream ciphers).
+ *     (e.g. for stream ciphers).
  *
  * The reason for the data_offset in the unencrypted case
  * is to allow for in-place conversion of an unencrypted to
@@ -859,6 +949,21 @@
 int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
 void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl );
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+/**
+ * \brief           TLS 1.3 client side state machine entry
+ *
+ * \param ssl       SSL context
+ */
+int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief           TLS 1.3 server side state machine entry
+ *
+ * \param ssl       SSL context
+ */
+int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl );
+#endif
 
 int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl );
 
@@ -949,7 +1054,13 @@
                              unsigned update_hs_digest );
 int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
 
-int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_handshake_msg_ext( mbedtls_ssl_context *ssl,
+                                         int update_checksum );
+static inline int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
+{
+    return( mbedtls_ssl_write_handshake_msg_ext( ssl, 1 /* update checksum */ ) );
+}
+
 int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush );
 int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl );
 
@@ -1237,4 +1348,90 @@
 void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight );
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
+/**
+ * ssl utils functions for checking configuration.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+static inline int mbedtls_ssl_conf_is_tls13_only( const mbedtls_ssl_config *conf )
+{
+    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 &&
+        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+static inline int mbedtls_ssl_conf_is_tls12_only( const mbedtls_ssl_config *conf )
+{
+    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13( const mbedtls_ssl_config *conf )
+{
+    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL*/
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+static inline void mbedtls_ssl_handshake_set_state( mbedtls_ssl_context *ssl,
+                                                    mbedtls_ssl_states state )
+{
+    ssl->state = ( int ) state;
+}
+
+/*
+ * Write TLS 1.3 handshake message header
+ */
+int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
+                                           unsigned hs_type,
+                                           unsigned char **buf,
+                                           size_t *buflen );
+/*
+ * Write TLS 1.3 handshake message tail
+ */
+int mbedtls_ssl_tls13_finish_handshake_msg( mbedtls_ssl_context *ssl,
+                                            size_t buf_len,
+                                            size_t msg_len );
+/*
+ * Update checksum with handshake header
+ */
+void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
+                                               unsigned hs_type,
+                                               size_t total_hs_len );
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/*
+ * Write TLS 1.3 Signature Algorithm extension
+ */
+int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
+                                         unsigned char *buf,
+                                         unsigned char *end,
+                                         size_t *olen);
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 #endif /* ssl_misc.h */
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index ff628b9..2fe801a 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -100,9 +100,7 @@
     MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen );
 
     /* We don't support record checking in TLS because
-     * (a) there doesn't seem to be a usecase for it, and
-     * (b) In TLS 1.0, CBC record decryption has state
-     *     and we'd need to backup the transform here.
+     * there doesn't seem to be a usecase for it.
      */
     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
     {
@@ -386,7 +384,8 @@
 static void ssl_extract_add_data_from_record( unsigned char* add_data,
                                               size_t *add_data_len,
                                               mbedtls_record *rec,
-                                              unsigned minor_ver )
+                                              unsigned minor_ver,
+                                              size_t taglen )
 {
     /* Quoting RFC 5246 (TLS 1.2):
      *
@@ -405,15 +404,37 @@
      *
      * For TLS 1.3, the record sequence number is dropped from the AAD
      * and encoded within the nonce of the AEAD operation instead.
+     * Moreover, the additional data involves the length of the TLS
+     * ciphertext, not the TLS plaintext as in earlier versions.
+     * Quoting RFC 8446 (TLS 1.3):
+     *
+     *      additional_data = TLSCiphertext.opaque_type ||
+     *                        TLSCiphertext.legacy_record_version ||
+     *                        TLSCiphertext.length
+     *
+     * We pass the tag length to this function in order to compute the
+     * ciphertext length from the inner plaintext length rec->data_len via
+     *
+     *     TLSCiphertext.length = TLSInnerPlaintext.length + taglen.
+     *
      */
 
     unsigned char *cur = add_data;
+    size_t ad_len_field = rec->data_len;
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
-    if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 )
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+    {
+        /* In TLS 1.3, the AAD contains the length of the TLSCiphertext,
+         * which differs from the length of the TLSInnerPlaintext
+         * by the length of the authentication tag. */
+        ad_len_field += taglen;
+    }
+    else
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
     {
         ((void) minor_ver);
+        ((void) taglen);
         memcpy( cur, rec->ctr, sizeof( rec->ctr ) );
         cur += sizeof( rec->ctr );
     }
@@ -433,15 +454,13 @@
         *cur = rec->cid_len;
         cur++;
 
-        cur[0] = ( rec->data_len >> 8 ) & 0xFF;
-        cur[1] = ( rec->data_len >> 0 ) & 0xFF;
+        MBEDTLS_PUT_UINT16_BE( ad_len_field, 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( ad_len_field, cur, 0 );
         cur += 2;
     }
 
@@ -579,7 +598,7 @@
     {
         size_t padding =
             ssl_compute_padding_length( rec->data_len,
-                                        MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY );
+                                        MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY );
         if( ssl_build_inner_plaintext( data,
                                        &rec->data_len,
                                        post_avail,
@@ -605,7 +624,7 @@
     {
         size_t padding =
             ssl_compute_padding_length( rec->data_len,
-                                        MBEDTLS_SSL_CID_PADDING_GRANULARITY );
+                                        MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY );
         /*
          * Wrap plaintext into DTLSInnerPlaintext structure.
          * See ssl_build_inner_plaintext() for more information.
@@ -645,28 +664,20 @@
             return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
         }
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-        if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
-        {
-            unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+        unsigned char mac[MBEDTLS_SSL_MAC_ADD];
 
-            ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
-                                              transform->minor_ver );
+        ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+                                          transform->minor_ver,
+                                          transform->taglen );
 
-            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 );
+        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 );
 
-            memcpy( data + rec->data_len, mac, transform->maclen );
-        }
-        else
+        memcpy( data + rec->data_len, mac, transform->maclen );
 #endif
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-        }
 
         MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len,
                                transform->maclen );
@@ -754,7 +765,8 @@
          * This depends on the TLS version.
          */
         ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
-                                          transform->minor_ver );
+                                          transform->minor_ver,
+                                          transform->taglen );
 
         MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
                                iv, transform->ivlen );
@@ -839,31 +851,26 @@
          * Prepend per-record IV for block cipher in TLS v1.2 as per
          * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
          */
-        if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_3 )
+        if( f_rng == NULL )
         {
-            if( f_rng == NULL )
-            {
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) );
-                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-            }
-
-            if( rec->data_offset < transform->ivlen )
-            {
-                MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
-                return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-            }
-
-            /*
-             * Generate IV
-             */
-            ret = f_rng( p_rng, transform->iv_enc, transform->ivlen );
-            if( ret != 0 )
-                return( ret );
-
-            memcpy( data - transform->ivlen, transform->iv_enc,
-                    transform->ivlen );
-
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
         }
+
+        if( rec->data_offset < transform->ivlen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+            return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+        }
+
+        /*
+         * Generate IV
+         */
+        ret = f_rng( p_rng, transform->iv_enc, transform->ivlen );
+        if( ret != 0 )
+            return( ret );
+
+        memcpy( data - transform->ivlen, transform->iv_enc, transform->ivlen );
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
@@ -902,7 +909,7 @@
              *     TLSCipherText.type +
              *     TLSCipherText.version +
              *     length_of( (IV +) ENC(...) ) +
-             *     IV + // except for TLS 1.0
+             *     IV +
              *     ENC(content + padding + padding_length));
              */
 
@@ -913,7 +920,8 @@
             }
 
             ssl_extract_add_data_from_record( add_data, &add_data_len,
-                                              rec, transform->minor_ver );
+                                              rec, transform->minor_ver,
+                                              transform->taglen );
 
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
             MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
@@ -1107,7 +1115,7 @@
      * 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,
+    /* TLS 1.2 only supports 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;
@@ -1148,6 +1156,9 @@
             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 ) );
@@ -1317,7 +1328,8 @@
          * This depends on the TLS version.
          */
         ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
-                                          transform->minor_ver );
+                                          transform->minor_ver,
+                                          transform->taglen );
         MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
                                add_data, add_data_len );
 
@@ -1368,11 +1380,8 @@
          * Check immediate ciphertext sanity
          */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-        if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_3 )
-        {
-            /* The ciphertext is prefixed with the CBC IV. */
-            minlen += transform->ivlen;
-        }
+        /* The ciphertext is prefixed with the CBC IV. */
+        minlen += transform->ivlen;
 #endif
 
         /* Size considerations:
@@ -1430,7 +1439,8 @@
              * Further, we still know that data_len > minlen */
             rec->data_len -= transform->maclen;
             ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
-                                              transform->minor_ver );
+                                              transform->minor_ver,
+                                              transform->taglen );
 
             /* Calculate expected MAC. */
             MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
@@ -1477,15 +1487,12 @@
         /*
          * Initialize for prepended IV for block cipher in TLS v1.2
          */
-        if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_3 )
-        {
-            /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
-            memcpy( transform->iv_dec, data, transform->ivlen );
+        /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
+        memcpy( transform->iv_dec, data, transform->ivlen );
 
-            data += transform->ivlen;
-            rec->data_offset += transform->ivlen;
-            rec->data_len -= transform->ivlen;
-        }
+        data += transform->ivlen;
+        rec->data_offset += transform->ivlen;
+        rec->data_len -= transform->ivlen;
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
         /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
@@ -1625,7 +1632,8 @@
          */
         rec->data_len -= transform->maclen;
         ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
-                                          transform->minor_ver );
+                                          transform->minor_ver,
+                                          transform->taglen );
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         /*
@@ -2245,13 +2253,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 );
 
@@ -2379,7 +2387,8 @@
  *      (including handshake headers but excluding record headers)
  *   - ssl->out_msg: the record contents (handshake headers + content)
  */
-int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_write_handshake_msg_ext( mbedtls_ssl_context *ssl,
+                                         int update_checksum )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     const size_t hs_len = ssl->out_msglen - 4;
@@ -2440,9 +2449,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,
@@ -2470,8 +2479,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
@@ -2488,7 +2496,7 @@
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
         /* Update running hashes of handshake messages seen */
-        if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
+        if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0 )
             ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
     }
 
@@ -2555,8 +2563,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 )
         {
@@ -2596,8 +2603,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 );
@@ -3109,16 +3115,16 @@
         in[3] != 0 || in[4] != 0 ||
         in[19] != 0 || in[20] != 0 || in[21] != 0 )
     {
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     sid_len = in[59];
     if( sid_len > in_len - 61 )
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     cookie_len = in[60 + sid_len];
     if( cookie_len > in_len - 60 )
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
 
     if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
                         cli_id, cli_id_len ) == 0 )
@@ -3169,12 +3175,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 );
 }
@@ -4554,8 +4559,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 );
 
     return( 0 );
 }
@@ -5025,8 +5029,7 @@
             /* For TLS 1.2 or higher, an explicit IV is added
              * after the record header. */
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-            if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_3 )
-                transform_expansion += block_size;
+            transform_expansion += block_size;
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
             break;
@@ -5168,21 +5171,13 @@
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-        if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+        if( ( ret = mbedtls_ssl_send_alert_message( ssl,
+                         MBEDTLS_SSL_ALERT_LEVEL_WARNING,
+                         MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
         {
-            if( ( ret = mbedtls_ssl_send_alert_message( ssl,
-                             MBEDTLS_SSL_ALERT_LEVEL_WARNING,
-                             MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
-            {
-                return( ret );
-            }
+            return( ret );
         }
-        else
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-        }
     }
 
     return( 0 );
@@ -5598,7 +5593,6 @@
  *
  * For TLS this is the identity.
  * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
- * 1.0 <-> 3.2      (DTLS 1.0 is based on TLS 1.1)
  * 1.x <-> 3.x+1    for x != 0 (DTLS 1.2 based on TLS 1.2)
  */
 void mbedtls_ssl_write_version( int major, int minor, int transport,
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 8f13a2c..b8c4314 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -91,7 +91,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( servername_list_size + 2 != len )
@@ -99,7 +99,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     p = buf + 2;
@@ -111,7 +111,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME )
@@ -123,7 +123,7 @@
                 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                         MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME );
             }
             return( 0 );
         }
@@ -136,8 +136,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     return( 0 );
@@ -202,7 +202,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
     }
     else
@@ -213,7 +213,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
 
         ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
@@ -253,7 +253,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( sig_alg_list_size + 2 != len ||
@@ -262,7 +262,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Currently we only guarantee signing the ServerKeyExchange message according
@@ -327,7 +327,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( list_size + 2 != len ||
@@ -336,7 +336,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Should never happen unless client duplicates the extension */
@@ -344,8 +344,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     /* Don't allow our peer to make us allocate too much memory,
@@ -393,7 +393,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     list_size = buf[0];
 
@@ -407,7 +407,8 @@
             ssl->handshake->ecdh_ctx.point_format = p[0];
 #endif
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-            ssl->handshake->ecjpake_ctx.point_format = p[0];
+            mbedtls_ecjpake_set_point_format( &ssl->handshake->ecjpake_ctx,
+                                              p[0] );
 #endif
             MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
             return( 0 );
@@ -461,7 +462,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     ssl->session_negotiate->mfl_code = buf[0];
@@ -483,7 +484,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     /*
@@ -499,8 +500,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     peer_cid_len = *buf++;
@@ -510,8 +511,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Ignore CID if the user has disabled its use. */
@@ -528,7 +529,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
     }
 
     ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
@@ -542,28 +543,6 @@
 }
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
-                                         const unsigned char *buf,
-                                         size_t len )
-{
-    if( len != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
-    }
-
-    ((void) buf);
-
-    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
-        ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
-
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
 static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
                                       const unsigned char *buf,
@@ -574,7 +553,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     ((void) buf);
@@ -598,7 +577,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     ((void) buf);
@@ -711,7 +690,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     list_len = ( buf[0] << 8 ) | buf[1];
@@ -719,7 +698,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -736,7 +715,7 @@
         {
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         /* Empty strings MUST NOT be included */
@@ -744,7 +723,7 @@
         {
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
     }
 
@@ -770,7 +749,7 @@
     /* If we get there, no match was found */
     mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                             MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
-    return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    return( MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL );
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
@@ -814,8 +793,8 @@
     if( len < size_of_lengths )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
    ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
@@ -829,8 +808,8 @@
         profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
     /*
      * parse the extension list values are defined in
@@ -874,8 +853,8 @@
         mki_length + profile_length + size_of_lengths != len )
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Parse the mki only if present and mki is supported locally */
@@ -1204,7 +1183,7 @@
     if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, message len.: %d",
@@ -1222,7 +1201,7 @@
     if( major < MBEDTLS_SSL_MAJOR_VERSION_3 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
     }
 
     /* For DTLS if this is the initial handshake, remember the client sequence
@@ -1238,7 +1217,7 @@
         if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
@@ -1272,7 +1251,7 @@
         if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         if( ( ret = mbedtls_ssl_fetch_input( ssl,
@@ -1308,7 +1287,7 @@
     if( msg_len < mbedtls_ssl_hs_hdr_len( ssl ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) );
@@ -1316,7 +1295,7 @@
     if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d",
@@ -1327,7 +1306,7 @@
         msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -1349,7 +1328,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: "
                                     "%u (expected %u)", cli_msg_seq,
                                     ssl->handshake->in_msg_seq ) );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
 
             ssl->handshake->in_msg_seq++;
@@ -1403,7 +1382,7 @@
     if( msg_len < 38 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -1413,6 +1392,7 @@
 
     mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
                       ssl->conf->transport, buf );
+    ssl->session_negotiate->minor_ver = ssl->minor_ver;
 
     ssl->handshake->max_major_ver = ssl->major_ver;
     ssl->handshake->max_minor_ver = ssl->minor_ver;
@@ -1426,7 +1406,7 @@
                             ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
-        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+        return( MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION );
     }
 
     if( ssl->major_ver > ssl->conf->max_major_ver )
@@ -1455,7 +1435,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 35, sess_len );
@@ -1479,8 +1459,8 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
             mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
@@ -1514,7 +1494,7 @@
             {
                 /* This may be an attacker's probe, so don't send an alert */
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
 
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification skipped" ) );
@@ -1539,7 +1519,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
@@ -1559,7 +1539,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression",
@@ -1582,7 +1562,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
 
             ext_len = ( buf[ext_offset + 0] << 8 )
@@ -1593,7 +1573,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
         }
         else
@@ -1610,7 +1590,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
             ext_id   = ( ( ext[0] <<  8 ) | ( ext[1] ) );
             ext_size = ( ( ext[2] <<  8 ) | ( ext[3] ) );
@@ -1620,7 +1600,7 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_DECODE_ERROR );
             }
             switch( ext_id )
             {
@@ -1702,16 +1682,6 @@
                 break;
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-            case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
-                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
-
-                ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
-                if( ret != 0 )
-                    return( ret );
-                break;
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
             case MBEDTLS_TLS_EXT_CID:
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) );
@@ -1720,7 +1690,7 @@
                 if( ret != 0 )
                     return( ret );
                 break;
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
             case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
@@ -1816,7 +1786,7 @@
                                             "during renegotiation" ) );
                 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+                return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
             }
 #endif
             ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
@@ -1861,7 +1831,7 @@
     {
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
     /*
@@ -1870,29 +1840,43 @@
      * and certificate from the SNI callback triggered by the SNI extension.)
      */
     got_common_suite = 0;
-    ciphersuites = mbedtls_ssl_get_protocol_version_ciphersuites( ssl->conf, ssl->minor_ver );
+    ciphersuites = ssl->conf->ciphersuite_list;
     ciphersuite_info = NULL;
-#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
-    for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
-        for( i = 0; ciphersuites[i] != 0; i++ )
-#else
-    for( i = 0; ciphersuites[i] != 0; i++ )
+
+    if (ssl->conf->respect_cli_pref == MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT)
+    {
         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 ) )
-                continue;
+            for( i = 0; ciphersuites[i] != 0; i++ )
+            {
+                if( MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i] )
+                    continue;
 
-            got_common_suite = 1;
+                got_common_suite = 1;
 
-            if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
-                                               &ciphersuite_info ) ) != 0 )
-                return( ret );
+                if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
+                                                   &ciphersuite_info ) ) != 0 )
+                    return( ret );
 
-            if( ciphersuite_info != NULL )
-                goto have_ciphersuite;
-        }
+                if( ciphersuite_info != NULL )
+                    goto have_ciphersuite;
+            }
+    } else {
+        for( i = 0; ciphersuites[i] != 0; i++ )
+            for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
+            {
+                if( MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i] )
+                    continue;
+
+                got_common_suite = 1;
+
+                if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
+                                                   &ciphersuite_info ) ) != 0 )
+                    return( ret );
+
+                if( ciphersuite_info != NULL )
+                    goto have_ciphersuite;
+            }
+    }
 
     if( got_common_suite )
     {
@@ -1900,14 +1884,14 @@
                             "but none of them usable" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
     else
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
-        return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
 have_ciphersuite:
@@ -1950,31 +1934,6 @@
     return( 0 );
 }
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
-                                          unsigned char *buf,
-                                          size_t *olen )
-{
-    unsigned char *p = buf;
-
-    if( ssl->session_negotiate->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
-    {
-        *olen = 0;
-        return;
-    }
-
-    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 );
-
-    *p++ = 0x00;
-    *p++ = 0x00;
-
-    *olen = 4;
-}
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
 static void ssl_write_cid_ext( mbedtls_ssl_context *ssl,
                                unsigned char *buf,
@@ -2009,12 +1968,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 );
@@ -2055,8 +2013,8 @@
 
     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;
@@ -2081,8 +2039,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;
@@ -2106,8 +2064,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;
@@ -2130,8 +2088,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 )
@@ -2171,8 +2129,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;
@@ -2201,8 +2159,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;
@@ -2239,8 +2197,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,
@@ -2251,8 +2209,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;
 }
@@ -2277,18 +2235,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 );
 }
@@ -2333,15 +2288,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;
@@ -2350,8 +2303,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
     {
@@ -2533,10 +2485,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 ) );
@@ -2617,9 +2567,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 ) ) );
@@ -2637,11 +2587,6 @@
     ext_len += olen;
 #endif
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-    ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
-    ext_len += olen;
-#endif
-
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen );
     ext_len += olen;
@@ -2692,9 +2637,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;
     }
 
     ssl->out_msglen  = p - buf;
@@ -2829,8 +2773,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;
     }
@@ -2870,8 +2813,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;
 
@@ -2885,8 +2828,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 );
 
@@ -2967,6 +2909,14 @@
     (void) signature_len;
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+    size_t out_buf_len = ssl->out_buf_len - ( ssl->out_msg - ssl->out_buf );
+#else
+    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - ( ssl->out_msg - ssl->out_buf );
+#endif
+#endif
+
     ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
 
     /*
@@ -3049,7 +2999,7 @@
 
         if( ( ret = mbedtls_dhm_make_params(
                   &ssl->handshake->dhm_ctx,
-                  (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
+                  (int) mbedtls_dhm_get_len( &ssl->handshake->dhm_ctx ),
                   ssl->out_msg + ssl->out_msglen, &len,
                   ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
@@ -3099,7 +3049,7 @@
         if( curve == NULL || *curve == NULL )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) );
-            return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
+            return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
         }
 
         MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
@@ -3269,6 +3219,7 @@
         if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ),
                                      md_alg, hash, hashlen,
                                      ssl->out_msg + ssl->out_msglen + 2,
+                                     out_buf_len - ssl->out_msglen - 2,
                                      signature_len,
                                      ssl->conf->f_rng,
                                      ssl->conf->p_rng ) ) != 0 )
@@ -3355,8 +3306,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,
@@ -3434,7 +3385,7 @@
     if( *p + 2 > end )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     n = ( (*p)[0] << 8 ) | (*p)[1];
@@ -3443,13 +3394,13 @@
     if( *p + n > end )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     if( ( ret = mbedtls_dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_read_public", ret );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     *p += n;
@@ -3511,20 +3462,20 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     if ( p + 2 > end ) {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
-    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 );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 #endif
 
     if( p + len != end )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /*
@@ -3685,7 +3636,7 @@
     if( end - *p < 2 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     n = ( (*p)[0] << 8 ) | (*p)[1];
@@ -3694,7 +3645,7 @@
     if( n == 0 || n > end - *p )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     if( ssl->conf->f_psk != NULL )
@@ -3763,13 +3714,13 @@
     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
     if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
@@ -3784,7 +3735,7 @@
         if( p != end )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
@@ -3794,7 +3745,7 @@
                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
@@ -3814,7 +3765,7 @@
                                       p, end - p) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
@@ -3827,7 +3778,7 @@
                                        ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
@@ -3850,7 +3801,7 @@
         if( p != end )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -3935,7 +3886,7 @@
         if( p != end )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
@@ -3960,7 +3911,7 @@
                                        p, end - p ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -4000,7 +3951,7 @@
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
-            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
         }
 
         ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
@@ -4106,7 +4057,7 @@
         ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
     i = mbedtls_ssl_hs_hdr_len( ssl );
@@ -4134,7 +4085,7 @@
         if( i + 2 > ssl->in_hslen )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         /*
@@ -4146,7 +4097,7 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
                                 " for verify message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
 #if !defined(MBEDTLS_MD_SHA1)
@@ -4167,7 +4118,7 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
                                 " for verify message" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         /*
@@ -4176,7 +4127,7 @@
         if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+            return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
         }
 
         i++;
@@ -4191,7 +4142,7 @@
     if( i + 2 > ssl->in_hslen )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1];
@@ -4200,7 +4151,7 @@
     if( i + sig_len != ssl->in_hslen )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Calculate hash and verify signature */
@@ -4258,14 +4209,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;
 
     /*
@@ -4293,23 +4238,8 @@
 {
     int ret = 0;
 
-    if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
 
-    if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
-        return( ret );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
-        ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
-    {
-        if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
-            return( ret );
-    }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
     switch( ssl->state )
     {
         case MBEDTLS_SSL_HELLO_REQUEST:
@@ -4416,4 +4346,10 @@
 
     return( ret );
 }
+
+void mbedtls_ssl_conf_preference_order( mbedtls_ssl_config *conf, int order )
+{
+    conf->respect_cli_pref = order;
+}
+
 #endif /* MBEDTLS_SSL_SRV_C */
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 940e1a6..bce9a1c 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -245,8 +245,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/library/ssl_tls.c b/library/ssl_tls.c
index 342832f..3604192 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -655,7 +655,6 @@
  * - [in] ciphersuite
  * - [in] master
  * - [in] encrypt_then_mac
- * - [in] trunc_hmac
  * - [in] compression
  * - [in] tls_prf: pointer to PRF to use for key derivation
  * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
@@ -665,17 +664,14 @@
  *        - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
  *        - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
  */
-static int ssl_populate_transform( mbedtls_ssl_transform *transform,
+static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
                                    int ciphersuite,
                                    const unsigned char master[48],
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \
+    defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
                                    int encrypt_then_mac,
-#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-                                   int trunc_hmac,
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC &&
+          MBEDTLS_SSL_SOME_SUITES_USE_MAC */
                                    ssl_tls_prf_t tls_prf,
                                    const unsigned char randbytes[64],
                                    int minor_ver,
@@ -717,6 +713,15 @@
     memcpy( transform->randbytes, randbytes, sizeof( transform->randbytes ) );
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+    {
+        /* At the moment, we keep TLS <= 1.2 and TLS 1.3 transform
+         * generation separate. This should never happen. */
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
     /*
      * Get various info structures
      */
@@ -809,19 +814,10 @@
          *   sequence number).
          */
         transform->ivlen = 12;
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
-        if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
-        {
+        if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
             transform->fixed_ivlen = 12;
-        }
         else
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
-        {
-            if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
-                transform->fixed_ivlen = 12;
-            else
-                transform->fixed_ivlen = 4;
-        }
+            transform->fixed_ivlen = 4;
 
         /* Minimum length of encrypted record */
         explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
@@ -845,18 +841,6 @@
         mac_key_len = mbedtls_md_get_size( md_info );
         transform->maclen = mac_key_len;
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-        /*
-         * If HMAC is to be truncated, we shall keep the leftmost bytes,
-         * (rfc 6066 page 13 or rfc 2104 section 4),
-         * so we only need to adjust the length here.
-         */
-        if( trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
-        {
-            transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
-        }
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
         /* IV length */
         transform->ivlen = cipher_info->iv_size;
 
@@ -869,7 +853,7 @@
              * GenericBlockCipher:
              * 1. if EtM is in use: one block plus MAC
              *    otherwise: * first multiple of blocklen greater than maclen
-             * 2. IV except for TLS 1.0
+             * 2. IV
              */
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
             if( encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
@@ -963,46 +947,28 @@
 
 #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    if( minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+    /* For HMAC-based ciphersuites, initialize the HMAC transforms.
+       For AEAD-based ciphersuites, there is nothing to do here. */
+    if( mac_key_len != 0 )
     {
-        /* For HMAC-based ciphersuites, initialize the HMAC transforms.
-           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 );
-        }
+        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 );
     }
-    else
 #endif
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
-        goto end;
-    }
 #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
 
     ((void) mac_dec);
     ((void) mac_enc);
 
 #if defined(MBEDTLS_SSL_EXPORT_KEYS)
-    if( ssl->conf->f_export_keys != NULL )
+    if( ssl->f_export_keys != NULL )
     {
-        ssl->conf->f_export_keys( ssl->conf->p_export_keys,
-                                  master, keyblk,
-                                  mac_key_len, keylen,
-                                  iv_copy_len );
-    }
-
-    if( ssl->conf->f_export_keys_ext != NULL )
-    {
-        ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys,
-                                      master, keyblk,
-                                      mac_key_len, keylen,
-                                      iv_copy_len,
-                                      randbytes + 32,
-                                      randbytes,
-                                      tls_prf_get_type( tls_prf ) );
+        ssl->f_export_keys( ssl->p_export_keys,
+                            MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET,
+                            master, 48,
+                            randbytes + 32,
+                            randbytes,
+                            tls_prf_get_type( tls_prf ) );
     }
 #endif
 
@@ -1361,25 +1327,22 @@
     }
 
     /* Populate transform structure */
-    ret = ssl_populate_transform( ssl->transform_negotiate,
-                                  ssl->session_negotiate->ciphersuite,
-                                  ssl->session_negotiate->master,
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-                                  ssl->session_negotiate->encrypt_then_mac,
-#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-                                  ssl->session_negotiate->trunc_hmac,
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
-                                  ssl->handshake->tls_prf,
-                                  ssl->handshake->randbytes,
-                                  ssl->minor_ver,
-                                  ssl->conf->endpoint,
-                                  ssl );
+    ret = ssl_tls12_populate_transform( ssl->transform_negotiate,
+                                        ssl->session_negotiate->ciphersuite,
+                                        ssl->session_negotiate->master,
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \
+    defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+                                        ssl->session_negotiate->encrypt_then_mac,
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC &&
+          MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+                                        ssl->handshake->tls_prf,
+                                        ssl->handshake->randbytes,
+                                        ssl->minor_ver,
+                                        ssl->conf->endpoint,
+                                        ssl );
     if( ret != 0 )
     {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_populate_transform", ret );
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls12_populate_transform", ret );
         return( ret );
     }
 
@@ -1429,7 +1392,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
 
     mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
-    mbedtls_sha256_finish_ret( &sha256, hash );
+    mbedtls_sha256_finish( &sha256, hash );
 
     *hlen = 32;
 
@@ -1478,7 +1441,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
 
     mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
-    mbedtls_sha512_finish_ret( &sha512, hash );
+    mbedtls_sha512_finish( &sha512, hash );
 
     *hlen = 48;
 
@@ -1524,8 +1487,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 );
@@ -1565,9 +1528,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  );
     }
@@ -1587,9 +1549,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 );
@@ -1605,8 +1566,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 );
@@ -1783,17 +1744,17 @@
             return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
         }
 
-        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;
@@ -1882,13 +1843,19 @@
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
-    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE ||
-        ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE  )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     i = mbedtls_ssl_hs_hdr_len( ssl );
@@ -1904,7 +1871,7 @@
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
@@ -1919,7 +1886,7 @@
             mbedtls_ssl_send_alert_message( ssl,
                               MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                               MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
         /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
          * anything beyond 2**16 ~ 64K. */
@@ -1928,8 +1895,8 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
             mbedtls_ssl_send_alert_message( ssl,
                             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+                            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT );
+            return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
         }
 
         /* Read length of the next CRT in the chain. */
@@ -1943,7 +1910,7 @@
             mbedtls_ssl_send_alert_message( ssl,
                                  MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                  MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
-            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+            return( MBEDTLS_ERR_SSL_DECODE_ERROR );
         }
 
         /* Check if we're handling the first CRT in the chain. */
@@ -1965,7 +1932,7 @@
                 mbedtls_ssl_send_alert_message( ssl,
                                                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                                 MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
-                return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+                return( MBEDTLS_ERR_SSL_BAD_CERTIFICATE );
             }
 
             /* Now we can safely free the original chain. */
@@ -2175,7 +2142,7 @@
 
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
             if( ret == 0 )
-                ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
+                ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
         }
     }
 #endif /* MBEDTLS_ECP_C */
@@ -2187,7 +2154,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
         if( ret == 0 )
-            ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
+            ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
     }
 
     /* mbedtls_x509_crt_verify_with_profile is supposed to report a
@@ -2198,7 +2165,7 @@
      * ssl_parse_certificate even if verification was optional. */
     if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
         ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
-          ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
+          ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE ) )
     {
         ret = 0;
     }
@@ -2490,7 +2457,7 @@
     psa_hash_abort( &ssl->handshake->fin_sha256_psa );
     psa_hash_setup( &ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
 #else
-    mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 );
+    mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 );
 #endif
 #endif
 #if defined(MBEDTLS_SHA384_C)
@@ -2498,7 +2465,7 @@
     psa_hash_abort( &ssl->handshake->fin_sha384_psa );
     psa_hash_setup( &ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
 #else
-    mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 );
+    mbedtls_sha512_starts( &ssl->handshake->fin_sha512, 1 );
 #endif
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@@ -2512,14 +2479,14 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
 #else
-    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
+    mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len );
 #endif
 #endif
 #if defined(MBEDTLS_SHA384_C)
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
 #else
-    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
+    mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
 #endif
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@@ -2533,7 +2500,7 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
 #else
-    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
+    mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len );
 #endif
 }
 #endif
@@ -2545,7 +2512,7 @@
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
 #else
-    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
+    mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len );
 #endif
 }
 #endif
@@ -2613,7 +2580,7 @@
                    sha256.state, sizeof( sha256.state ) );
 #endif
 
-    mbedtls_sha256_finish_ret( &sha256, padbuf );
+    mbedtls_sha256_finish( &sha256, padbuf );
     mbedtls_sha256_free( &sha256 );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
 
@@ -2688,7 +2655,7 @@
     MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
                    sha512.state, sizeof( sha512.state ) );
 #endif
-    mbedtls_sha512_finish_ret( &sha512, padbuf );
+    mbedtls_sha512_finish( &sha512, padbuf );
 
     mbedtls_sha512_free( &sha512 );
 #endif
@@ -2930,13 +2897,19 @@
 
     hash_len = 12;
 
-    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
-        ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED  )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( 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 );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
     if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
@@ -2944,8 +2917,8 @@
     {
         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 );
+                                        MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
     }
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -2988,7 +2961,7 @@
     psa_hash_setup( &handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
 #else
     mbedtls_sha256_init(   &handshake->fin_sha256    );
-    mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 );
+    mbedtls_sha256_starts( &handshake->fin_sha256, 0 );
 #endif
 #endif
 #if defined(MBEDTLS_SHA384_C)
@@ -2997,7 +2970,7 @@
     psa_hash_setup( &handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
 #else
     mbedtls_sha512_init(   &handshake->fin_sha512    );
-    mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 );
+    mbedtls_sha512_starts( &handshake->fin_sha512, 1 );
 #endif
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@@ -3167,6 +3140,53 @@
     memset( ssl, 0, sizeof( mbedtls_ssl_context ) );
 }
 
+static int ssl_conf_version_check( const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    if( mbedtls_ssl_conf_is_tls13_only( ssl->conf ) )
+    {
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        {
+             MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS 1.3 is not yet supported" ) );
+             return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "The SSL configuration is tls13 only." ) );
+        return( 0 );
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( mbedtls_ssl_conf_is_tls12_only( ssl->conf ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "The SSL configuration is tls12 only." ) );
+        return( 0 );
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    if( mbedtls_ssl_conf_is_hybrid_tls12_tls13( ssl->conf ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Hybrid TLS 1.2 + TLS 1.3 configurations are not yet supported" ) );
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "The SSL configuration is invalid." ) );
+    return( MBEDTLS_ERR_SSL_BAD_CONFIG );
+}
+
+static int ssl_conf_check(const mbedtls_ssl_context *ssl)
+{
+    int ret;
+    ret = ssl_conf_version_check( ssl );
+    if( ret != 0 )
+        return( ret );
+
+    /* Space for further checks */
+
+    return( 0 );
+}
+
 /*
  * Setup an SSL context
  */
@@ -3180,6 +3200,9 @@
 
     ssl->conf = conf;
 
+    if( ( ret = ssl_conf_check( ssl ) ) != 0 )
+        return( ret );
+
     /*
      * Prepare base structures
      */
@@ -3255,9 +3278,9 @@
  * If partial is non-zero, keep data in the input buffer and client ID.
  * (Use when a DTLS client reconnects from the same port.)
  */
-int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
+static void ssl_session_reset_msg_layer( mbedtls_ssl_context *ssl,
+                                         int partial )
 {
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
     size_t in_buf_len = ssl->in_buf_len;
     size_t out_buf_len = ssl->out_buf_len;
@@ -3266,16 +3289,65 @@
     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
 #endif
 
-#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) ||     \
-    !defined(MBEDTLS_SSL_SRV_C)
-    ((void) partial);
+#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || !defined(MBEDTLS_SSL_SRV_C)
+    partial = 0;
 #endif
 
-    ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
-
     /* Cancel any possibly running timer */
     mbedtls_ssl_set_timer( ssl, 0 );
 
+    mbedtls_ssl_reset_in_out_pointers( ssl );
+
+    /* Reset incoming message parsing */
+    ssl->in_offt    = NULL;
+    ssl->nb_zero    = 0;
+    ssl->in_msgtype = 0;
+    ssl->in_msglen  = 0;
+    ssl->in_hslen   = 0;
+    ssl->keep_current_message = 0;
+    ssl->transform_in  = NULL;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    ssl->next_record_offset = 0;
+    ssl->in_epoch = 0;
+#endif
+
+    /* Keep current datagram if partial == 1 */
+    if( partial == 0 )
+    {
+        ssl->in_left = 0;
+        memset( ssl->in_buf, 0, in_buf_len );
+    }
+
+    /* Reset outgoing message writing */
+    ssl->out_msgtype = 0;
+    ssl->out_msglen  = 0;
+    ssl->out_left    = 0;
+    memset( ssl->out_buf, 0, out_buf_len );
+    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
+    ssl->transform_out = NULL;
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    mbedtls_ssl_dtls_replay_reset( ssl );
+#endif
+
+    if( ssl->transform )
+    {
+        mbedtls_ssl_transform_free( ssl->transform );
+        mbedtls_free( ssl->transform );
+        ssl->transform = NULL;
+    }
+}
+
+int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
+
+    ssl_session_reset_msg_layer( ssl, partial );
+
+    /* Reset renegotiation state */
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
     ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
     ssl->renego_records_seen = 0;
@@ -3286,53 +3358,8 @@
 #endif
     ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
 
-    ssl->in_offt = NULL;
-    mbedtls_ssl_reset_in_out_pointers( ssl );
-
-    ssl->in_msgtype = 0;
-    ssl->in_msglen = 0;
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    ssl->next_record_offset = 0;
-    ssl->in_epoch = 0;
-#endif
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-    mbedtls_ssl_dtls_replay_reset( ssl );
-#endif
-
-    ssl->in_hslen = 0;
-    ssl->nb_zero = 0;
-
-    ssl->keep_current_message = 0;
-
-    ssl->out_msgtype = 0;
-    ssl->out_msglen = 0;
-    ssl->out_left = 0;
-
-    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
-
-    ssl->transform_in = NULL;
-    ssl->transform_out = NULL;
-
-    ssl->session_in = NULL;
+    ssl->session_in  = NULL;
     ssl->session_out = NULL;
-
-    memset( ssl->out_buf, 0, out_buf_len );
-
-#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
-    if( partial == 0 )
-#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
-    {
-        ssl->in_left = 0;
-        memset( ssl->in_buf, 0, in_buf_len );
-    }
-
-    if( ssl->transform )
-    {
-        mbedtls_ssl_transform_free( ssl->transform );
-        mbedtls_free( ssl->transform );
-        ssl->transform = NULL;
-    }
-
     if( ssl->session )
     {
         mbedtls_ssl_session_free( ssl->session );
@@ -3504,6 +3531,9 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
+    if( ssl->handshake->resume == 1 )
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+
     if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate,
                                           session ) ) != 0 )
         return( ret );
@@ -3514,74 +3544,19 @@
 }
 #endif /* MBEDTLS_SSL_CLI_C */
 
-static int protocol_version_to_ciphersuites_list_index(int prot_version)
-{
-    switch(prot_version) {
-        case MBEDTLS_SSL_MINOR_VERSION_1:
-            return 0;
-        case MBEDTLS_SSL_MINOR_VERSION_2:
-            return 1;
-        case MBEDTLS_SSL_MINOR_VERSION_3:
-            return 2;
-        default:
-            return -1;
-    };
-}
-
-static void set_protocol_version_ciphersuites( mbedtls_ssl_config *conf,
-                                               int prot_version,
-                                               const int* ciphersuites )
-{
-    int ciphersuite_list_index =
-        protocol_version_to_ciphersuites_list_index(prot_version);
-    if ( ciphersuite_list_index >= 0 &&
-         (unsigned int)ciphersuite_list_index <
-         sizeof(conf->ciphersuite_list)/sizeof(conf->ciphersuite_list[0]) )
-    {
-        conf->ciphersuite_list[ciphersuite_list_index] = ciphersuites;
-    }
-}
-
 void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
                                     const int *ciphersuites )
 {
-    set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_1,
-        ciphersuites);
-    set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_2,
-        ciphersuites);
-    set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_3,
-        ciphersuites);
+    conf->ciphersuite_list = ciphersuites;
 }
 
-const int *mbedtls_ssl_get_protocol_version_ciphersuites(
-    const mbedtls_ssl_config *conf, int prot_version )
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+void mbedtls_ssl_conf_tls13_key_exchange_modes( mbedtls_ssl_config *conf,
+                                                const int kex_modes )
 {
-    int ciphersuite_list_index =
-        protocol_version_to_ciphersuites_list_index(prot_version);
-    if ( ciphersuite_list_index >= 0 &&
-         (unsigned int)ciphersuite_list_index <
-         sizeof(conf->ciphersuite_list)/sizeof(conf->ciphersuite_list[0]) )
-    {
-        return conf->ciphersuite_list[ciphersuite_list_index];
-    }
-    else
-    {
-        return NULL;
-    }
+    conf->tls13_kex_modes = kex_modes & MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL;
 }
-
-void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
-                                       const int *ciphersuites,
-                                       int major, int minor )
-{
-    if( major != MBEDTLS_SSL_MAJOR_VERSION_3 )
-        return;
-
-    if( minor != MBEDTLS_SSL_MINOR_VERSION_3 )
-        return;
-
-    set_protocol_version_ciphersuites(conf, minor, ciphersuites);
-}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
@@ -3934,8 +3909,10 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
-        ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
+    if( ( ret = mbedtls_dhm_get_value( dhm_ctx, MBEDTLS_DHM_PARAM_P,
+                                       &conf->dhm_P ) ) != 0 ||
+        ( ret = mbedtls_dhm_get_value( dhm_ctx, MBEDTLS_DHM_PARAM_G,
+                                       &conf->dhm_G ) ) != 0 )
     {
         mbedtls_mpi_free( &conf->dhm_P );
         mbedtls_mpi_free( &conf->dhm_G );
@@ -3966,6 +3943,15 @@
 {
     conf->sig_hashes = hashes;
 }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+/* Configure allowed signature algorithms for use in TLS 1.3 */
+void mbedtls_ssl_conf_sig_algs( mbedtls_ssl_config *conf,
+                                const uint16_t* sig_algs )
+{
+    conf->tls13_sig_algs = sig_algs;
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_ECP_C)
@@ -4199,13 +4185,6 @@
 }
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate )
-{
-    conf->trunc_hmac = truncate;
-}
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
 void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy )
 {
     conf->allow_legacy_renegotiation = allow_legacy;
@@ -4251,20 +4230,12 @@
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
 #if defined(MBEDTLS_SSL_EXPORT_KEYS)
-void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
-        mbedtls_ssl_export_keys_t *f_export_keys,
-        void *p_export_keys )
+void mbedtls_ssl_set_export_keys_cb( mbedtls_ssl_context *ssl,
+                                     mbedtls_ssl_export_keys_t *f_export_keys,
+                                     void *p_export_keys )
 {
-    conf->f_export_keys = f_export_keys;
-    conf->p_export_keys = p_export_keys;
-}
-
-void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf,
-        mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
-        void *p_export_keys )
-{
-    conf->f_export_keys_ext = f_export_keys_ext;
-    conf->p_export_keys = p_export_keys;
+    ssl->f_export_keys = f_export_keys;
+    ssl->p_export_keys = p_export_keys;
 }
 #endif
 
@@ -4334,9 +4305,6 @@
     {
         switch( ssl->minor_ver )
         {
-            case MBEDTLS_SSL_MINOR_VERSION_2:
-                return( "DTLSv1.0" );
-
             case MBEDTLS_SSL_MINOR_VERSION_3:
                 return( "DTLSv1.2" );
 
@@ -4348,12 +4316,6 @@
 
     switch( ssl->minor_ver )
     {
-        case MBEDTLS_SSL_MINOR_VERSION_1:
-            return( "TLSv1.0" );
-
-        case MBEDTLS_SSL_MINOR_VERSION_2:
-            return( "TLSv1.1" );
-
         case MBEDTLS_SSL_MINOR_VERSION_3:
             return( "TLSv1.2" );
 
@@ -4490,6 +4452,24 @@
     return( (int) max_len );
 }
 
+int mbedtls_ssl_get_max_in_record_payload( const mbedtls_ssl_context *ssl )
+{
+    size_t max_len = MBEDTLS_SSL_IN_CONTENT_LEN;
+
+#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    (void) ssl;
+#endif
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    const size_t mfl = mbedtls_ssl_get_input_max_frag_len( ssl );
+
+    if( max_len > mfl )
+        max_len = mfl;
+#endif
+
+    return( (int) max_len );
+}
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl )
 {
@@ -4508,6 +4488,8 @@
 int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
                              mbedtls_ssl_session *dst )
 {
+    int ret;
+
     if( ssl == NULL ||
         dst == NULL ||
         ssl->session == NULL ||
@@ -4516,18 +4498,30 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    return( mbedtls_ssl_session_copy( dst, ssl->session ) );
+    /* Since Mbed TLS 3.0, mbedtls_ssl_get_session() is no longer
+     * idempotent: Each session can only be exported once.
+     *
+     * (This is in preparation for TLS 1.3 support where we will
+     * need the ability to export multiple sessions (aka tickets),
+     * which will be achieved by calling mbedtls_ssl_get_session()
+     * multiple times until it fails.)
+     *
+     * Check whether we have already exported the current session,
+     * and fail if so.
+     */
+    if( ssl->session->exported == 1 )
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+
+    ret = mbedtls_ssl_session_copy( dst, ssl->session );
+    if( ret != 0 )
+        return( ret );
+
+    /* Remember that we've exported the session. */
+    ssl->session->exported = 1;
+    return( 0 );
 }
 #endif /* MBEDTLS_SSL_CLI_C */
 
-const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl )
-{
-    if( ssl == NULL )
-        return( NULL );
-
-    return( ssl->session );
-}
-
 /*
  * Define ticket header determining Mbed TLS version
  * and structure of the ticket.
@@ -4562,12 +4556,6 @@
 #define SSL_SERIALIZED_SESSION_CONFIG_MFL 0
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 1
-#else
-#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 0
-#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
-
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
 #define SSL_SERIALIZED_SESSION_CONFIG_ETM 1
 #else
@@ -4584,9 +4572,8 @@
 #define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT           1
 #define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2
 #define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT           3
-#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT    4
-#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT           5
-#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT        6
+#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT           4
+#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT        5
 
 #define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG                           \
     ( (uint16_t) (                                                      \
@@ -4594,7 +4581,6 @@
         ( SSL_SERIALIZED_SESSION_CONFIG_CRT           << SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT           ) | \
         ( SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET << SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT ) | \
         ( SSL_SERIALIZED_SESSION_CONFIG_MFL           << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT           ) | \
-        ( SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC    << SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT    ) | \
         ( SSL_SERIALIZED_SESSION_CONFIG_ETM           << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT           ) | \
         ( SSL_SERIALIZED_SESSION_CONFIG_TICKET        << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT        ) ) )
 
@@ -4602,52 +4588,69 @@
     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 ),
 };
 
 /*
  * Serialize a session in the following format:
  * (in the presentation language of TLS, RFC 8446 section 3)
  *
- *  opaque mbedtls_version[3];   // major, minor, patch
- *  opaque session_format[2];    // version-specific 16-bit field determining
- *                               // the format of the remaining
- *                               // serialized data.
+ *  struct {
  *
- *  Note: When updating the format, remember to keep
- *        these version+format bytes.
+ *    opaque mbedtls_version[3];   // library version: major, minor, patch
+ *    opaque session_format[2];    // library-version specific 16-bit field
+ *                                 // determining the format of the remaining
+ *                                 // serialized data.
  *
- *                               // In this version, `session_format` determines
- *                               // the setting of those compile-time
- *                               // configuration options which influence
- *                               // the structure of mbedtls_ssl_session.
- *  uint64 start_time;
- *  uint8 ciphersuite[2];        // defined by the standard
- *  uint8 compression;           // 0 or 1
- *  uint8 session_id_len;        // at most 32
- *  opaque session_id[32];
- *  opaque master[48];           // fixed length in the standard
- *  uint32 verify_result;
- *  opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
- *  opaque ticket<0..2^24-1>;    // length 0 means no ticket
- *  uint32 ticket_lifetime;
- *  uint8 mfl_code;              // up to 255 according to standard
- *  uint8 trunc_hmac;            // 0 or 1
- *  uint8 encrypt_then_mac;      // 0 or 1
+ *          Note: When updating the format, remember to keep
+ *          these version+format bytes.
  *
- * The order is the same as in the definition of the structure, except
- * verify_result is put before peer_cert so that all mandatory fields come
- * together in one block.
+ *                                 // In this version, `session_format` determines
+ *                                 // the setting of those compile-time
+ *                                 // configuration options which influence
+ *                                 // the structure of mbedtls_ssl_session.
+ *
+ *    uint8_t minor_ver;           // Protocol-version. Possible values:
+ *                                 // - TLS 1.2 (MBEDTLS_SSL_MINOR_VERSION_3)
+ *
+ *    select (serialized_session.minor_ver) {
+ *
+ *      case MBEDTLS_SSL_MINOR_VERSION_3: // TLS 1.2
+ *        serialized_session_tls12 data;
+ *
+ *   };
+ *
+ * } serialized_session;
+ *
  */
-static int ssl_session_save( const mbedtls_ssl_session *session,
-                             unsigned char omit_header,
-                             unsigned char *buf,
-                             size_t buf_len,
-                             size_t *olen )
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+/* Serialization of TLS 1.2 sessions:
+ *
+ * struct {
+ *    uint64 start_time;
+ *    uint8 ciphersuite[2];           // defined by the standard
+ *    uint8 compression;              // 0 or 1
+ *    uint8 session_id_len;           // at most 32
+ *    opaque session_id[32];
+ *    opaque master[48];              // fixed length in the standard
+ *    uint32 verify_result;
+ *    opaque peer_cert<0..2^24-1>;    // length 0 means no peer cert
+ *    opaque ticket<0..2^24-1>;       // length 0 means no ticket
+ *    uint32 ticket_lifetime;
+ *    uint8 mfl_code;                 // up to 255 according to standard
+ *    uint8 encrypt_then_mac;         // 0 or 1
+ * } serialized_session_tls12;
+ *
+ */
+static size_t ssl_session_save_tls12( const mbedtls_ssl_session *session,
+                                      unsigned char *buf,
+                                      size_t buf_len )
 {
     unsigned char *p = buf;
     size_t used = 0;
+
 #if defined(MBEDTLS_HAVE_TIME)
     uint64_t start;
 #endif
@@ -4657,23 +4660,6 @@
 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
-
-    if( !omit_header )
-    {
-        /*
-         * Add version identifier
-         */
-
-        used += sizeof( ssl_serialized_session_header );
-
-        if( used <= buf_len )
-        {
-            memcpy( p, ssl_serialized_session_header,
-                    sizeof( ssl_serialized_session_header ) );
-            p += sizeof( ssl_serialized_session_header );
-        }
-    }
-
     /*
      * Time
      */
@@ -4684,14 +4670,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 */
 
@@ -4707,22 +4687,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;
     }
 
     /*
@@ -4739,9 +4717,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 )
         {
@@ -4782,9 +4760,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 )
         {
@@ -4792,10 +4770,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 */
 
@@ -4809,23 +4785,68 @@
         *p++ = session->mfl_code;
 #endif
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-    used += 1;
-
-    if( used <= buf_len )
-        *p++ = (unsigned char)( ( session->trunc_hmac ) & 0xFF );
-#endif
-
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
     used += 1;
 
     if( used <= buf_len )
-        *p++ = (unsigned char)( ( session->encrypt_then_mac ) & 0xFF );
+        *p++ = MBEDTLS_BYTE_0( session->encrypt_then_mac );
 #endif
 
-    /* Done */
-    *olen = used;
+    return( used );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
+static int ssl_session_save( const mbedtls_ssl_session *session,
+                             unsigned char omit_header,
+                             unsigned char *buf,
+                             size_t buf_len,
+                             size_t *olen )
+{
+    unsigned char *p = buf;
+    size_t used = 0;
+
+    if( !omit_header )
+    {
+        /*
+         * Add Mbed TLS version identifier
+         */
+
+        used += sizeof( ssl_serialized_session_header );
+
+        if( used <= buf_len )
+        {
+            memcpy( p, ssl_serialized_session_header,
+                    sizeof( ssl_serialized_session_header ) );
+            p += sizeof( ssl_serialized_session_header );
+        }
+    }
+
+    /*
+     * TLS version identifier
+     */
+    used += 1;
+    if( used <= buf_len )
+    {
+        *p++ = session->minor_ver;
+    }
+
+    /* Forward to version-specific serialization routine. */
+    switch( session->minor_ver )
+    {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    case MBEDTLS_SSL_MINOR_VERSION_3:
+    {
+        size_t remaining_len = used <= buf_len ? buf_len - used : 0;
+        used += ssl_session_save_tls12( session, p, remaining_len );
+        break;
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+    default:
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
+
+    *olen = used;
     if( used > buf_len )
         return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
 
@@ -4849,13 +4870,10 @@
  * This internal version is wrapped by a public function that cleans up in
  * case of error, and has an extra option omit_header.
  */
-static int ssl_session_load( mbedtls_ssl_session *session,
-                             unsigned char omit_header,
-                             const unsigned char *buf,
-                             size_t len )
+static int ssl_session_load_tls12( mbedtls_ssl_session *session,
+                                   const unsigned char *buf,
+                                   size_t len )
 {
-    const unsigned char *p = buf;
-    const unsigned char * const end = buf + len;
 #if defined(MBEDTLS_HAVE_TIME)
     uint64_t start;
 #endif
@@ -4865,22 +4883,8 @@
 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
-    if( !omit_header )
-    {
-        /*
-         * Check version identifier
-         */
-
-        if( (size_t)( end - p ) < sizeof( ssl_serialized_session_header ) )
-            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-        if( memcmp( p, ssl_serialized_session_header,
-                    sizeof( ssl_serialized_session_header ) ) != 0 )
-        {
-            return( MBEDTLS_ERR_SSL_VERSION_MISMATCH );
-        }
-        p += sizeof( ssl_serialized_session_header );
-    }
+    const unsigned char *p = buf;
+    const unsigned char * const end = buf + len;
 
     /*
      * Time
@@ -5051,13 +5055,6 @@
     session->mfl_code = *p++;
 #endif
 
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-    if( 1 > (size_t)( end - p ) )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    session->trunc_hmac = *p++;
-#endif
-
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
     if( 1 > (size_t)( end - p ) )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -5072,6 +5069,54 @@
     return( 0 );
 }
 
+static int ssl_session_load( mbedtls_ssl_session *session,
+                             unsigned char omit_header,
+                             const unsigned char *buf,
+                             size_t len )
+{
+    const unsigned char *p = buf;
+    const unsigned char * const end = buf + len;
+
+    if( !omit_header )
+    {
+        /*
+         * Check Mbed TLS version identifier
+         */
+
+        if( (size_t)( end - p ) < sizeof( ssl_serialized_session_header ) )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        if( memcmp( p, ssl_serialized_session_header,
+                    sizeof( ssl_serialized_session_header ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_SSL_VERSION_MISMATCH );
+        }
+        p += sizeof( ssl_serialized_session_header );
+    }
+
+    /*
+     * TLS version identifier
+     */
+    if( 1 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    session->minor_ver = *p++;
+
+    /* Dispatch according to TLS version. */
+    switch( session->minor_ver )
+    {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    case MBEDTLS_SSL_MINOR_VERSION_3: /* TLS 1.2 */
+    {
+        size_t remaining_len = ( end - p );
+        return( ssl_session_load_tls12( session, p, remaining_len ) );
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+    default:
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+}
+
 /*
  * Deserialize session: public wrapper for error cleaning
  */
@@ -5090,20 +5135,68 @@
 /*
  * Perform a single step of the SSL handshake
  */
+static int ssl_prepare_handshake_step( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+        return( ret );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+    {
+        if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+            return( ret );
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    return( ret );
+}
+
 int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
 {
-    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    if( ssl == NULL || ssl->conf == NULL )
+    if( ssl            == NULL                       ||
+        ssl->conf      == NULL                       ||
+        ssl->handshake == NULL                       ||
+        ssl->state     == MBEDTLS_SSL_HANDSHAKE_OVER )
+    {
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    ret = ssl_prepare_handshake_step( ssl );
+    if( ret != 0 )
+        return( ret );
 
 #if defined(MBEDTLS_SSL_CLI_C)
     if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
-        ret = mbedtls_ssl_handshake_client_step( ssl );
+    {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+        if( mbedtls_ssl_conf_is_tls13_only( ssl->conf ) )
+            ret = mbedtls_ssl_tls13_handshake_client_step( ssl );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( mbedtls_ssl_conf_is_tls12_only( ssl->conf ) )
+            ret = mbedtls_ssl_handshake_client_step( ssl );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    }
 #endif
 #if defined(MBEDTLS_SSL_SRV_C)
     if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
-        ret = mbedtls_ssl_handshake_server_step( ssl );
+    {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+        if( mbedtls_ssl_conf_is_tls13_only( ssl->conf ) )
+            ret = mbedtls_ssl_tls13_handshake_server_step( ssl );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( mbedtls_ssl_conf_is_tls12_only( ssl->conf ) )
+            ret = mbedtls_ssl_handshake_server_step( ssl );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    }
 #endif
 
     return( ret );
@@ -5407,6 +5500,13 @@
     handle_buffer_resizing( ssl, 1, mbedtls_ssl_get_input_buflen( ssl ),
                                     mbedtls_ssl_get_output_buflen( ssl ) );
 #endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    mbedtls_free( handshake->transform_earlydata );
+    mbedtls_free( handshake->transform_handshake );
+    handshake->transform_earlydata = NULL;
+    handshake->transform_handshake = NULL;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 }
 
 void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
@@ -5464,11 +5564,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 ),
 };
 
 /*
@@ -5609,10 +5709,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 );
@@ -5653,33 +5751,19 @@
     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;
     }
 
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
     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 */
 
@@ -5702,8 +5786,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 */
 
@@ -5867,17 +5951,14 @@
     if( (size_t)( end - p ) < sizeof( ssl->transform->randbytes ) )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-    ret = ssl_populate_transform( ssl->transform,
+    ret = ssl_tls12_populate_transform( ssl->transform,
                   ssl->session->ciphersuite,
                   ssl->session->master,
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) && \
+    defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
                   ssl->session->encrypt_then_mac,
-#endif
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-                  ssl->session->trunc_hmac,
-#endif
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC &&
+          MBEDTLS_SSL_SOME_SUITES_USE_MAC */
                   ssl_tls12prf_from_cs( ssl->session->ciphersuite ),
                   p, /* currently pointing to randbytes */
                   MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */
@@ -6108,6 +6189,11 @@
         mbedtls_free( ssl->session_negotiate );
     }
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    mbedtls_ssl_transform_free( ssl->transform_application );
+    mbedtls_free( ssl->transform_application );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
     if( ssl->session )
     {
         mbedtls_ssl_session_free( ssl->session );
@@ -6141,6 +6227,11 @@
 }
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+/* The selection should be the same as mbedtls_x509_crt_profile_default in
+ * x509_crt.c. Here, the order matters. Currently we favor stronger hashes,
+ * for no fundamental reason.
+ * See the documentation of mbedtls_ssl_conf_curves() for what we promise
+ * about this list. */
 static int ssl_preset_default_hashes[] = {
 #if defined(MBEDTLS_SHA512_C)
     MBEDTLS_MD_SHA512,
@@ -6151,16 +6242,46 @@
 #if defined(MBEDTLS_SHA256_C)
     MBEDTLS_MD_SHA256,
 #endif
-#if defined(MBEDTLS_SHA224_C)
-    MBEDTLS_MD_SHA224,
-#endif
-#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE)
-    MBEDTLS_MD_SHA1,
-#endif
     MBEDTLS_MD_NONE
 };
 #endif
 
+#if defined(MBEDTLS_ECP_C)
+/* The selection should be the same as mbedtls_x509_crt_profile_default in
+ * x509_crt.c, plus Montgomery curves for ECDHE. Here, the order matters:
+ * curves with a lower resource usage come first.
+ * See the documentation of mbedtls_ssl_conf_curves() for what we promise
+ * about this list.
+ */
+static mbedtls_ecp_group_id ssl_preset_default_curves[] = {
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+    MBEDTLS_ECP_DP_CURVE25519,
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    MBEDTLS_ECP_DP_SECP256R1,
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+    MBEDTLS_ECP_DP_SECP384R1,
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+    MBEDTLS_ECP_DP_CURVE448,
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+    MBEDTLS_ECP_DP_SECP521R1,
+#endif
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+    MBEDTLS_ECP_DP_BP256R1,
+#endif
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+    MBEDTLS_ECP_DP_BP384R1,
+#endif
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+    MBEDTLS_ECP_DP_BP512R1,
+#endif
+    MBEDTLS_ECP_DP_NONE
+};
+#endif
+
 static int ssl_preset_suiteb_ciphersuites[] = {
     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
@@ -6173,6 +6294,37 @@
     MBEDTLS_MD_SHA384,
     MBEDTLS_MD_NONE
 };
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+static uint16_t ssl_preset_default_sig_algs[] = {
+    /* ECDSA algorithms */
+#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    MBEDTLS_TLS13_SIG_ECDSA_SECP256R1_SHA256,
+#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+    MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384,
+#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+    MBEDTLS_TLS13_SIG_ECDSA_SECP521R1_SHA512,
+#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+#endif /* MBEDTLS_ECDSA_C */
+    MBEDTLS_TLS13_SIG_NONE
+};
+
+static uint16_t ssl_preset_suiteb_sig_algs[] = {
+    /* ECDSA algorithms */
+#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    MBEDTLS_TLS13_SIG_ECDSA_SECP256R1_SHA256,
+#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+    MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384,
+#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+#endif /* MBEDTLS_ECDSA_C */
+    MBEDTLS_TLS13_SIG_NONE
+};
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 #endif
 
 #if defined(MBEDTLS_ECP_C)
@@ -6234,6 +6386,7 @@
 
 #if defined(MBEDTLS_SSL_SRV_C)
     conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
+    conf->respect_cli_pref = MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER;
 #endif
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -6248,22 +6401,29 @@
 #endif
 
 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
-            if( endpoint == MBEDTLS_SSL_IS_SERVER )
-            {
-                const unsigned char dhm_p[] =
-                    MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
-                const unsigned char dhm_g[] =
-                    MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
+    if( endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        const unsigned char dhm_p[] =
+            MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
+        const unsigned char dhm_g[] =
+            MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
 
-                if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf,
-                                               dhm_p, sizeof( dhm_p ),
-                                               dhm_g, sizeof( dhm_g ) ) ) != 0 )
-                {
-                    return( ret );
-                }
-            }
+        if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf,
+                                                    dhm_p, sizeof( dhm_p ),
+                                                    dhm_g, sizeof( dhm_g ) ) ) != 0 )
+        {
+            return( ret );
+        }
+    }
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    /*
+     * Allow all TLS 1.3 key exchange modes by default.
+     */
+    conf->tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
     /*
      * Preset-specific defaults
      */
@@ -6278,12 +6438,7 @@
             conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
             conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
 
-            set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_1,
-                                              ssl_preset_suiteb_ciphersuites);
-            set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_2,
-                                              ssl_preset_suiteb_ciphersuites);
-            set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_3,
-                                              ssl_preset_suiteb_ciphersuites);
+            conf->ciphersuite_list = ssl_preset_suiteb_ciphersuites;
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
             conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
@@ -6291,6 +6446,9 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
             conf->sig_hashes = ssl_preset_suiteb_hashes;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+            conf->tls13_sig_algs = ssl_preset_suiteb_sig_algs;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 #endif
 
 #if defined(MBEDTLS_ECP_C)
@@ -6317,13 +6475,7 @@
             if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
                 conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
 #endif
-            const int* default_ciphersuites = mbedtls_ssl_list_ciphersuites();
-            set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_1,
-                                              default_ciphersuites);
-            set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_2,
-                                              default_ciphersuites);
-            set_protocol_version_ciphersuites(conf, MBEDTLS_SSL_MINOR_VERSION_3,
-                                              default_ciphersuites);
+            conf->ciphersuite_list = mbedtls_ssl_list_ciphersuites();
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
             conf->cert_profile = &mbedtls_x509_crt_profile_default;
@@ -6331,10 +6483,13 @@
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
             conf->sig_hashes = ssl_preset_default_hashes;
-#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+            conf->tls13_sig_algs = ssl_preset_default_sig_algs;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
 #if defined(MBEDTLS_ECP_C)
-            conf->curve_list = mbedtls_ecp_grp_id_list();
+            conf->curve_list = ssl_preset_default_curves;
 #endif
 
 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
@@ -6600,22 +6755,10 @@
                           uint32_t *flags )
 {
     int ret = 0;
-#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
     int usage = 0;
-#endif
-#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
     const char *ext_oid;
     size_t ext_len;
-#endif
 
-#if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) &&          \
-    !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
-    ((void) cert);
-    ((void) cert_endpoint);
-    ((void) flags);
-#endif
-
-#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
     if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
     {
         /* Server part of the key exchange */
@@ -6657,11 +6800,7 @@
         *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
         ret = -1;
     }
-#else
-    ((void) ciphersuite);
-#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
 
-#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
     if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
     {
         ext_oid = MBEDTLS_OID_SERVER_AUTH;
@@ -6678,7 +6817,6 @@
         *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
         ret = -1;
     }
-#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
 
     return( ret );
 }
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
new file mode 100644
index 0000000..41c7a4d
--- /dev/null
+++ b/library/ssl_tls13_client.c
@@ -0,0 +1,440 @@
+/*
+ *  TLS 1.3 client-side 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.
+ *
+ *  This file is part of mbed TLS ( https://tls.mbed.org )
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#if defined(MBEDTLS_SSL_CLI_C)
+
+#include <string.h>
+
+#include "ssl_misc.h"
+#include <mbedtls/debug.h>
+
+#define CLIENT_HELLO_RANDOM_LEN 32
+
+/* Write extensions */
+
+/*
+ * ssl_tls13_write_supported_versions_ext():
+ *
+ * struct {
+ *      ProtocolVersion versions<2..254>;
+ * } SupportedVersions;
+ */
+static int ssl_tls13_write_supported_versions_ext( mbedtls_ssl_context *ssl,
+                                                   unsigned char *buf,
+                                                   unsigned char *end,
+                                                   size_t *olen )
+{
+    unsigned char *p = buf;
+
+    *olen = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported versions extension" ) );
+
+    /*
+     * Check space for extension header.
+     *
+     * extension_type           2
+     * extension_data_length    2
+     * version_length           1
+     * versions                 2
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 7 );
+
+    /* Write extension_type */
+    MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, p, 0 );
+
+    /* Write extension_data_length */
+    MBEDTLS_PUT_UINT16_BE( 3, p, 2 );
+    p += 4;
+
+    /* Length of versions */
+    *p++ = 0x2;
+
+    /* Write values of supported versions.
+     *
+     * They are defined by the configuration.
+     *
+     * Currently, only one version is advertised.
+     */
+    mbedtls_ssl_write_version( ssl->conf->max_major_ver,
+                               ssl->conf->max_minor_ver,
+                               ssl->conf->transport, p );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "supported version: [%d:%d]",
+                                ssl->conf->max_major_ver,
+                                ssl->conf->max_minor_ver ) );
+
+    *olen = 7;
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+
+static int ssl_tls13_write_supported_groups_ext( mbedtls_ssl_context *ssl,
+                                                 unsigned char *buf,
+                                                 unsigned char *end,
+                                                 size_t *olen )
+{
+    ((void) ssl);
+    ((void) buf);
+    ((void) end);
+    ((void) olen);
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+
+static int ssl_tls13_write_key_shares_ext( mbedtls_ssl_context *ssl,
+                                           unsigned char *buf,
+                                           unsigned char *end,
+                                           size_t *olen )
+{
+    ((void) ssl);
+    ((void) buf);
+    ((void) end);
+    ((void) olen);
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+/*
+ * Functions for writing ClientHello message.
+ */
+/* Write cipher_suites
+ * CipherSuite cipher_suites<2..2^16-2>;
+ */
+static int ssl_tls13_write_client_hello_cipher_suites(
+            mbedtls_ssl_context *ssl,
+            unsigned char *buf,
+            unsigned char *end,
+            size_t *olen )
+{
+    unsigned char *p = buf;
+    const int *ciphersuite_list;
+    unsigned char *cipher_suites_ptr; /* Start of the cipher_suites list */
+    size_t cipher_suites_len;
+
+    *olen = 0 ;
+
+    /*
+     * Ciphersuite list
+     *
+     * This is a list of the symmetric cipher options supported by
+     * the client, specifically the record protection algorithm
+     * ( including secret key length ) and a hash to be used with
+     * HKDF, in descending order of client preference.
+     */
+    ciphersuite_list = ssl->conf->ciphersuite_list;
+
+    /* Check there is space for the cipher suite list length (2 bytes). */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+    p += 2;
+
+    /* Write cipher_suites */
+    cipher_suites_ptr = p;
+    for ( size_t i = 0; ciphersuite_list[i] != 0; i++ )
+    {
+        int cipher_suite = ciphersuite_list[i];
+        const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+
+        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( cipher_suite );
+        if( ciphersuite_info == NULL )
+            continue;
+        if( !( MBEDTLS_SSL_MINOR_VERSION_4 >= ciphersuite_info->min_minor_ver &&
+               MBEDTLS_SSL_MINOR_VERSION_4 <= ciphersuite_info->max_minor_ver ) )
+            continue;
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x, %s",
+                                    (unsigned int) cipher_suite,
+                                    ciphersuite_info->name ) );
+
+        /* Check there is space for the cipher suite identifier (2 bytes). */
+        MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+        MBEDTLS_PUT_UINT16_BE( cipher_suite, p, 0 );
+        p += 2;
+    }
+
+    /* Write the cipher_suites length in number of bytes */
+    cipher_suites_len = p - cipher_suites_ptr;
+    MBEDTLS_PUT_UINT16_BE( cipher_suites_len, buf, 0 );
+    MBEDTLS_SSL_DEBUG_MSG( 3,
+                           ( "client hello, got %" MBEDTLS_PRINTF_SIZET " cipher suites",
+                             cipher_suites_len/2 ) );
+
+    /* Output the total length of cipher_suites field. */
+    *olen = p - buf;
+
+    return( 0 );
+}
+
+/*
+ * Structure of ClientHello message:
+ *
+ *    struct {
+ *        ProtocolVersion legacy_version = 0x0303;    // TLS v1.2
+ *        Random random;
+ *        opaque legacy_session_id<0..32>;
+ *        CipherSuite cipher_suites<2..2^16-2>;
+ *        opaque legacy_compression_methods<1..2^8-1>;
+ *        Extension extensions<8..2^16-1>;
+ *    } ClientHello;
+ */
+static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl,
+                                              unsigned char *buf,
+                                              unsigned char *end,
+                                              size_t *olen )
+{
+
+    int ret;
+    unsigned char *extensions_len_ptr; /* Pointer to extensions length */
+    size_t output_len;                 /* Length of buffer used by function */
+    size_t extensions_len;             /* Length of the list of extensions*/
+
+    /* Buffer management */
+    unsigned char *p = buf;
+
+    *olen = 0;
+
+    /* No validation needed here. It has been done by ssl_conf_check() */
+    ssl->major_ver = ssl->conf->min_major_ver;
+    ssl->minor_ver = ssl->conf->min_minor_ver;
+
+    /*
+     * Write legacy_version
+     *    ProtocolVersion legacy_version = 0x0303;    // TLS v1.2
+     *
+     *  For TLS 1.3 we use the legacy version number {0x03, 0x03}
+     *  instead of the true version number.
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+    MBEDTLS_PUT_UINT16_BE( 0x0303, p, 0 );
+    p += 2;
+
+    /* Write the random bytes ( random ).*/
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, CLIENT_HELLO_RANDOM_LEN );
+    memcpy( p, ssl->handshake->randbytes, CLIENT_HELLO_RANDOM_LEN );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes",
+                           p, CLIENT_HELLO_RANDOM_LEN );
+    p += CLIENT_HELLO_RANDOM_LEN;
+
+    /*
+     * Write legacy_session_id
+     *
+     * Versions of TLS before TLS 1.3 supported a "session resumption" feature
+     * which has been merged with pre-shared keys in this version. A client
+     * which has a cached session ID set by a pre-TLS 1.3 server SHOULD set
+     * this field to that value. In compatibility mode, this field MUST be
+     * non-empty, so a client not offering a pre-TLS 1.3 session MUST generate
+     * a new 32-byte value. This value need not be random but SHOULD be
+     * unpredictable to avoid implementations fixating on a specific value
+     * ( also known as ossification ). Otherwise, it MUST be set as a zero-length
+     * vector ( i.e., a zero-valued single byte length field ).
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 1 );
+    *p++ = 0; /* session id length set to zero */
+
+    /* Write cipher_suites */
+    ret = ssl_tls13_write_client_hello_cipher_suites( ssl, p, end, &output_len );
+    if( ret != 0 )
+        return( ret );
+    p += output_len;
+
+    /* Write legacy_compression_methods
+     *
+     * For every TLS 1.3 ClientHello, this vector MUST contain exactly
+     * one byte set to zero, which corresponds to the 'null' compression
+     * method in prior versions of TLS.
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+    *p++ = 1;
+    *p++ = MBEDTLS_SSL_COMPRESS_NULL;
+
+    /* Write extensions */
+
+    /* Keeping track of the included extensions */
+    ssl->handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
+
+    /* First write extensions, then the total length */
+    MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
+    extensions_len_ptr = p;
+    p += 2;
+
+    /* Write supported_versions extension
+     *
+     * Supported Versions Extension is mandatory with TLS 1.3.
+     */
+    ret = ssl_tls13_write_supported_versions_ext( ssl, p, end, &output_len );
+    if( ret != 0 )
+        return( ret );
+    p += output_len;
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+    /* Write supported_groups extension
+     *
+     * It is REQUIRED for ECDHE cipher_suites.
+     */
+    ret = ssl_tls13_write_supported_groups_ext( ssl, p, end, &output_len );
+    if( ret != 0 )
+        return( ret );
+    p += output_len;
+
+    /* Write key_share extension
+     *
+     * We need to send the key shares under three conditions:
+     * 1) A certificate-based ciphersuite is being offered. In this case
+     *    supported_groups and supported_signature extensions have been
+     *    successfully added.
+     * 2) A PSK-based ciphersuite with ECDHE is offered. In this case the
+     *    psk_key_exchange_modes has been added as the last extension.
+     * 3) Or, in case all ciphers are supported ( which includes #1 and #2
+     *    from above )
+     */
+    ret = ssl_tls13_write_key_shares_ext( ssl, p, end, &output_len );
+    if( ret != 0 )
+        return( ret );
+    p += output_len;
+
+    /* Write signature_algorithms extension
+     *
+     * It is REQUIRED for certificate authenticated cipher_suites.
+     */
+    ret = mbedtls_ssl_tls13_write_sig_alg_ext( ssl, p, end, &output_len );
+    if( ret != 0 )
+        return( ret );
+    p += output_len;
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+    /* Add more extensions here */
+
+    /* Write the length of the list of extensions. */
+    extensions_len = p - extensions_len_ptr - 2;
+    MBEDTLS_PUT_UINT16_BE( extensions_len, extensions_len_ptr, 0 );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %" MBEDTLS_PRINTF_SIZET ,
+                                extensions_len ) );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", extensions_len_ptr, extensions_len );
+
+    *olen = p - buf;
+    return( 0 );
+}
+
+static int ssl_tls13_finalize_client_hello( mbedtls_ssl_context* ssl )
+{
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_HELLO );
+    return( 0 );
+}
+
+static int ssl_tls13_prepare_client_hello( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    if( ssl->conf->f_rng == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided" ) );
+        return( MBEDTLS_ERR_SSL_NO_RNG );
+    }
+
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng,
+                                  ssl->handshake->randbytes,
+                                  CLIENT_HELLO_RANDOM_LEN ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Write ClientHello handshake message.
+ */
+static int ssl_tls13_write_client_hello( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+    unsigned char *buf;
+    size_t buf_len, msg_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_prepare_client_hello( ssl ) );
+
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_start_handshake_msg(
+                                ssl, MBEDTLS_SSL_HS_CLIENT_HELLO,
+                                &buf, &buf_len ) );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_client_hello_body( ssl, buf,
+                                                             buf + buf_len,
+                                                             &msg_len ) );
+
+    mbedtls_ssl_tls13_add_hs_hdr_to_checksum( ssl,
+                                              MBEDTLS_SSL_HS_CLIENT_HELLO,
+                                              msg_len );
+    ssl->handshake->update_checksum( ssl, buf, msg_len );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_client_hello( ssl ) );
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_finish_handshake_msg( ssl,
+                                                                  buf_len,
+                                                                  msg_len ) );
+
+cleanup:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
+    return ret;
+}
+
+int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
+
+    switch( ssl->state )
+    {
+        /*
+         * ssl->state is initialized as HELLO_REQUEST. It is the same
+         * as CLIENT_HELLO state.
+         */
+        case MBEDTLS_SSL_HELLO_REQUEST:
+        case MBEDTLS_SSL_CLIENT_HELLO:
+            ret = ssl_tls13_write_client_hello( ssl );
+            break;
+
+        case MBEDTLS_SSL_SERVER_HELLO:
+            // Stop here : we haven't finished whole flow
+            ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+            mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS );
+            break;
+
+        default:
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SSL_CLI_C */
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
new file mode 100644
index 0000000..ca4c167
--- /dev/null
+++ b/library/ssl_tls13_generic.c
@@ -0,0 +1,119 @@
+/*
+ *  TLS 1.3 functionality shared between client and server
+ *
+ *  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.
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_TLS_C)
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#include "mbedtls/error.h"
+
+#include "ssl_misc.h"
+
+int mbedtls_ssl_tls13_start_handshake_msg( mbedtls_ssl_context *ssl,
+                                           unsigned hs_type,
+                                           unsigned char **buf,
+                                           size_t *buf_len )
+{
+    /*
+     * Reserve 4 bytes for hanshake header. ( Section 4,RFC 8446 )
+     *    ...
+     *    HandshakeType msg_type;
+     *    uint24 length;
+     *    ...
+     */
+    *buf = ssl->out_msg + 4;
+    *buf_len = MBEDTLS_SSL_OUT_CONTENT_LEN - 4;
+
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = hs_type;
+
+    return( 0 );
+}
+
+int mbedtls_ssl_tls13_finish_handshake_msg( mbedtls_ssl_context *ssl,
+                                            size_t buf_len,
+                                            size_t msg_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t msg_len_with_header;
+    ((void) buf_len);
+
+    /* Add reserved 4 bytes for handshake header */
+    msg_len_with_header = msg_len + 4;
+    ssl->out_msglen = msg_len_with_header;
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_write_handshake_msg_ext( ssl, 0 ) );
+
+cleanup:
+    return( ret );
+}
+
+void mbedtls_ssl_tls13_add_hs_hdr_to_checksum( mbedtls_ssl_context *ssl,
+                                               unsigned hs_type,
+                                               size_t total_hs_len )
+{
+    unsigned char hs_hdr[4];
+
+    /* Build HS header for checksum update. */
+    hs_hdr[0] = MBEDTLS_BYTE_0( hs_type );
+    hs_hdr[1] = MBEDTLS_BYTE_2( total_hs_len );
+    hs_hdr[2] = MBEDTLS_BYTE_1( total_hs_len );
+    hs_hdr[3] = MBEDTLS_BYTE_0( total_hs_len );
+
+    ssl->handshake->update_checksum( ssl, hs_hdr, sizeof( hs_hdr ) );
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+
+/*
+ * mbedtls_ssl_tls13_write_sig_alg_ext( )
+ *
+ * enum {
+ *    ....
+ *   ecdsa_secp256r1_sha256( 0x0403 ),
+ *   ecdsa_secp384r1_sha384( 0x0503 ),
+ *   ecdsa_secp521r1_sha512( 0x0603 ),
+ *    ....
+ * } SignatureScheme;
+ *
+ * struct {
+ *    SignatureScheme supported_signature_algorithms<2..2^16-2>;
+ * } SignatureSchemeList;
+ *
+ * Only if we handle at least one key exchange that needs signatures.
+ */
+
+int mbedtls_ssl_tls13_write_sig_alg_ext( mbedtls_ssl_context *ssl,
+                                         unsigned char *buf,
+                                         unsigned char *end,
+                                         size_t *olen )
+{
+    ((void) ssl);
+    ((void) buf);
+    ((void) end);
+    ((void) olen);
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index 4e8fb43..7aec21d 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -24,6 +24,7 @@
 #include "mbedtls/hkdf.h"
 #include "ssl_misc.h"
 #include "ssl_tls13_keys.h"
+#include "mbedtls/debug.h"
 
 #include <stdint.h>
 #include <string.h>
@@ -112,17 +113,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 );
 
@@ -346,4 +347,477 @@
     return( ret );
 }
 
+int mbedtls_ssl_tls1_3_derive_early_secrets(
+          mbedtls_md_type_t md_type,
+          unsigned char const *early_secret,
+          unsigned char const *transcript, size_t transcript_len,
+          mbedtls_ssl_tls1_3_early_secrets *derived )
+{
+    int ret;
+    mbedtls_md_info_t const * const md_info = mbedtls_md_info_from_type( md_type );
+    size_t const md_size = mbedtls_md_get_size( md_info );
+
+    /* We should never call this function with an unknown hash,
+     * but add an assertion anyway. */
+    if( md_info == 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    /*
+     *            0
+     *            |
+     *            v
+     *  PSK ->  HKDF-Extract = Early Secret
+     *            |
+     *            +-----> Derive-Secret(., "c e traffic", ClientHello)
+     *            |                     = client_early_traffic_secret
+     *            |
+     *            +-----> Derive-Secret(., "e exp master", ClientHello)
+     *            |                     = early_exporter_master_secret
+     *            v
+     */
+
+    /* Create client_early_traffic_secret */
+    ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+                         early_secret, md_size,
+                         MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( c_e_traffic ),
+                         transcript, transcript_len,
+                         MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
+                         derived->client_early_traffic_secret,
+                         md_size );
+    if( ret != 0 )
+        return( ret );
+
+    /* Create early exporter */
+    ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+                         early_secret, md_size,
+                         MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( e_exp_master ),
+                         transcript, transcript_len,
+                         MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
+                         derived->early_exporter_master_secret,
+                         md_size );
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+int mbedtls_ssl_tls1_3_derive_handshake_secrets(
+          mbedtls_md_type_t md_type,
+          unsigned char const *handshake_secret,
+          unsigned char const *transcript, size_t transcript_len,
+          mbedtls_ssl_tls1_3_handshake_secrets *derived )
+{
+    int ret;
+    mbedtls_md_info_t const * const md_info = mbedtls_md_info_from_type( md_type );
+    size_t const md_size = mbedtls_md_get_size( md_info );
+
+    /* We should never call this function with an unknown hash,
+     * but add an assertion anyway. */
+    if( md_info == 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    /*
+     *
+     * Handshake Secret
+     * |
+     * +-----> Derive-Secret( ., "c hs traffic",
+     * |                     ClientHello...ServerHello )
+     * |                     = client_handshake_traffic_secret
+     * |
+     * +-----> Derive-Secret( ., "s hs traffic",
+     * |                     ClientHello...ServerHello )
+     * |                     = server_handshake_traffic_secret
+     *
+     */
+
+    /*
+     * Compute client_handshake_traffic_secret with
+     * Derive-Secret( ., "c hs traffic", ClientHello...ServerHello )
+     */
+
+    ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+             handshake_secret, md_size,
+             MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( c_hs_traffic ),
+             transcript, transcript_len,
+             MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
+             derived->client_handshake_traffic_secret,
+             md_size );
+    if( ret != 0 )
+        return( ret );
+
+    /*
+     * Compute server_handshake_traffic_secret with
+     * Derive-Secret( ., "s hs traffic", ClientHello...ServerHello )
+     */
+
+    ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+             handshake_secret, md_size,
+             MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( s_hs_traffic ),
+             transcript, transcript_len,
+             MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
+             derived->server_handshake_traffic_secret,
+             md_size );
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+int mbedtls_ssl_tls1_3_derive_application_secrets(
+          mbedtls_md_type_t md_type,
+          unsigned char const *application_secret,
+          unsigned char const *transcript, size_t transcript_len,
+          mbedtls_ssl_tls1_3_application_secrets *derived )
+{
+    int ret;
+    mbedtls_md_info_t const * const md_info = mbedtls_md_info_from_type( md_type );
+    size_t const md_size = mbedtls_md_get_size( md_info );
+
+    /* We should never call this function with an unknown hash,
+     * but add an assertion anyway. */
+    if( md_info == 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    /* Generate {client,server}_application_traffic_secret_0
+     *
+     * Master Secret
+     * |
+     * +-----> Derive-Secret( ., "c ap traffic",
+     * |                      ClientHello...server Finished )
+     * |                      = client_application_traffic_secret_0
+     * |
+     * +-----> Derive-Secret( ., "s ap traffic",
+     * |                      ClientHello...Server Finished )
+     * |                      = server_application_traffic_secret_0
+     * |
+     * +-----> Derive-Secret( ., "exp master",
+     * |                      ClientHello...server Finished)
+     * |                      = exporter_master_secret
+     *
+     */
+
+    ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+              application_secret, md_size,
+              MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( c_ap_traffic ),
+              transcript, transcript_len,
+              MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
+              derived->client_application_traffic_secret_N,
+              md_size );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+              application_secret, md_size,
+              MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( s_ap_traffic ),
+              transcript, transcript_len,
+              MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
+              derived->server_application_traffic_secret_N,
+              md_size );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+              application_secret, md_size,
+              MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( exp_master ),
+              transcript, transcript_len,
+              MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
+              derived->exporter_master_secret,
+              md_size );
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+/* Generate resumption_master_secret for use with the ticket exchange.
+ *
+ * This is not integrated with mbedtls_ssl_tls1_3_derive_application_secrets()
+ * because it uses the transcript hash up to and including ClientFinished. */
+int mbedtls_ssl_tls1_3_derive_resumption_master_secret(
+          mbedtls_md_type_t md_type,
+          unsigned char const *application_secret,
+          unsigned char const *transcript, size_t transcript_len,
+          mbedtls_ssl_tls1_3_application_secrets *derived )
+{
+    int ret;
+    mbedtls_md_info_t const * const md_info = mbedtls_md_info_from_type( md_type );
+    size_t const md_size = mbedtls_md_get_size( md_info );
+
+    /* We should never call this function with an unknown hash,
+     * but add an assertion anyway. */
+    if( md_info == 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+              application_secret, md_size,
+              MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( res_master ),
+              transcript, transcript_len,
+              MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
+              derived->resumption_master_secret,
+              md_size );
+
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+static int ssl_tls1_3_calc_finished_core( mbedtls_md_type_t md_type,
+                                          unsigned char const *base_key,
+                                          unsigned char const *transcript,
+                                          unsigned char *dst )
+{
+    const mbedtls_md_info_t* const md_info = mbedtls_md_info_from_type( md_type );
+    size_t const md_size = mbedtls_md_get_size( md_info );
+    unsigned char finished_key[MBEDTLS_MD_MAX_SIZE];
+    int ret;
+
+    /* We should never call this function with an unknown hash,
+     * but add an assertion anyway. */
+    if( md_info == 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    /* TLS 1.3 Finished message
+     *
+     * struct {
+     *     opaque verify_data[Hash.length];
+     * } Finished;
+     *
+     * verify_data =
+     *     HMAC( finished_key,
+     *            Hash( Handshake Context +
+     *                  Certificate*      +
+     *                  CertificateVerify* )
+     *    )
+     *
+     * finished_key =
+     *    HKDF-Expand-Label( BaseKey, "finished", "", Hash.length )
+     */
+
+    ret = mbedtls_ssl_tls1_3_hkdf_expand_label(
+                                 md_type, base_key, md_size,
+                                 MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( finished ),
+                                 NULL, 0,
+                                 finished_key, md_size );
+    if( ret != 0 )
+        goto exit;
+
+    ret = mbedtls_md_hmac( md_info, finished_key, md_size, transcript, md_size, dst );
+    if( ret != 0 )
+        goto exit;
+
+exit:
+
+    mbedtls_platform_zeroize( finished_key, sizeof( finished_key ) );
+    return( ret );
+}
+
+int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl,
+                               const mbedtls_md_type_t md_type,
+                               unsigned char const *psk, size_t psk_len,
+                               int psk_type,
+                               unsigned char const *transcript,
+                               unsigned char *result )
+{
+    int ret = 0;
+    unsigned char binder_key[MBEDTLS_MD_MAX_SIZE];
+    unsigned char early_secret[MBEDTLS_MD_MAX_SIZE];
+    mbedtls_md_info_t const *md_info = mbedtls_md_info_from_type( md_type );
+    size_t const md_size = mbedtls_md_get_size( md_info );
+
+#if !defined(MBEDTLS_DEBUG_C)
+    ssl = NULL; /* make sure we don't use it except for debug */
+    ((void) ssl);
+#endif
+
+    /* We should never call this function with an unknown hash,
+     * but add an assertion anyway. */
+    if( md_info == 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    /*
+     *            0
+     *            |
+     *            v
+     *  PSK ->  HKDF-Extract = Early Secret
+     *            |
+     *            +-----> Derive-Secret(., "ext binder" | "res binder", "")
+     *            |                     = binder_key
+     *            v
+     */
+
+    ret = mbedtls_ssl_tls1_3_evolve_secret( md_type,
+                                            NULL,          /* Old secret */
+                                            psk, psk_len,  /* Input      */
+                                            early_secret );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_evolve_secret", ret );
+        goto exit;
+    }
+
+    if( psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION )
+    {
+        ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+                            early_secret, md_size,
+                            MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( res_binder ),
+                            NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
+                            binder_key, md_size );
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "Derive Early Secret with 'res binder'" ) );
+    }
+    else
+    {
+        ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
+                            early_secret, md_size,
+                            MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( ext_binder ),
+                            NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
+                            binder_key, md_size );
+        MBEDTLS_SSL_DEBUG_MSG( 4, ( "Derive Early Secret with 'ext binder'" ) );
+    }
+
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_derive_secret", ret );
+        goto exit;
+    }
+
+    /*
+     * The binding_value is computed in the same way as the Finished message
+     * but with the BaseKey being the binder_key.
+     */
+
+    ret = ssl_tls1_3_calc_finished_core( md_type, binder_key, transcript, result );
+    if( ret != 0 )
+        goto exit;
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "psk binder", result, md_size );
+
+exit:
+
+    mbedtls_platform_zeroize( early_secret, sizeof( early_secret ) );
+    mbedtls_platform_zeroize( binder_key,   sizeof( binder_key ) );
+    return( ret );
+}
+
+int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform,
+                                          int endpoint,
+                                          int ciphersuite,
+                                          mbedtls_ssl_key_set const *traffic_keys,
+                                          mbedtls_ssl_context *ssl /* DEBUG ONLY */ )
+{
+    int ret;
+    mbedtls_cipher_info_t const *cipher_info;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+    unsigned char const *key_enc;
+    unsigned char const *iv_enc;
+    unsigned char const *key_dec;
+    unsigned char const *iv_dec;
+
+#if !defined(MBEDTLS_DEBUG_C)
+    ssl = NULL; /* make sure we don't use it except for those cases */
+    (void) ssl;
+#endif
+
+    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
+    if( ciphersuite_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %d not found",
+                                    ciphersuite ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
+    if( cipher_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %u not found",
+                                    ciphersuite_info->cipher ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    /*
+     * Setup cipher contexts in target transform
+     */
+
+    if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
+                                      cipher_info ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
+                                      cipher_info ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        key_enc = traffic_keys->server_write_key;
+        key_dec = traffic_keys->client_write_key;
+        iv_enc = traffic_keys->server_write_iv;
+        iv_dec = traffic_keys->client_write_iv;
+    }
+    else
+#endif /* MBEDTLS_SSL_SRV_C */
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        key_enc = traffic_keys->client_write_key;
+        key_dec = traffic_keys->server_write_key;
+        iv_enc = traffic_keys->client_write_iv;
+        iv_dec = traffic_keys->server_write_iv;
+    }
+    else
+#endif /* MBEDTLS_SSL_CLI_C */
+    {
+        /* should not happen */
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    memcpy( transform->iv_enc, iv_enc, traffic_keys->iv_len );
+    memcpy( transform->iv_dec, iv_dec, traffic_keys->iv_len );
+
+    if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc,
+                                       key_enc, cipher_info->key_bitlen,
+                                       MBEDTLS_ENCRYPT ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec,
+                                       key_dec, cipher_info->key_bitlen,
+                                       MBEDTLS_DECRYPT ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
+        return( ret );
+    }
+
+    /*
+     * Setup other fields in SSL transform
+     */
+
+    if( ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ) != 0 )
+        transform->taglen  = 8;
+    else
+        transform->taglen  = 16;
+
+    transform->ivlen       = traffic_keys->iv_len;
+    transform->maclen      = 0;
+    transform->fixed_ivlen = transform->ivlen;
+    transform->minor_ver   = MBEDTLS_SSL_MINOR_VERSION_4;
+
+    /* We add the true record content type (1 Byte) to the plaintext and
+     * then pad to the configured granularity. The mimimum length of the
+     * type-extended and padded plaintext is therefore the padding
+     * granularity. */
+    transform->minlen =
+        transform->taglen + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY;
+
+    return( 0 );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h
index 7089049..ca892b1 100644
--- a/library/ssl_tls13_keys.h
+++ b/library/ssl_tls13_keys.h
@@ -70,6 +70,27 @@
 #define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN  \
     MBEDTLS_MD_MAX_SIZE
 
+typedef struct
+{
+    unsigned char binder_key                  [ MBEDTLS_MD_MAX_SIZE ];
+    unsigned char client_early_traffic_secret [ MBEDTLS_MD_MAX_SIZE ];
+    unsigned char early_exporter_master_secret[ MBEDTLS_MD_MAX_SIZE ];
+} mbedtls_ssl_tls1_3_early_secrets;
+
+typedef struct
+{
+    unsigned char client_handshake_traffic_secret[ MBEDTLS_MD_MAX_SIZE ];
+    unsigned char server_handshake_traffic_secret[ MBEDTLS_MD_MAX_SIZE ];
+} mbedtls_ssl_tls1_3_handshake_secrets;
+
+typedef struct
+{
+    unsigned char client_application_traffic_secret_N[ MBEDTLS_MD_MAX_SIZE ];
+    unsigned char server_application_traffic_secret_N[ MBEDTLS_MD_MAX_SIZE ];
+    unsigned char exporter_master_secret             [ MBEDTLS_MD_MAX_SIZE ];
+    unsigned char resumption_master_secret           [ MBEDTLS_MD_MAX_SIZE ];
+} mbedtls_ssl_tls1_3_application_secrets;
+
 /* Maximum desired length for expanded key material generated
  * by HKDF-Expand-Label.
  *
@@ -199,6 +220,179 @@
                    unsigned char *dstbuf, size_t buflen );
 
 /**
+ * \brief Derive TLS 1.3 early data key material from early secret.
+ *
+ *        This is a small wrapper invoking mbedtls_ssl_tls1_3_derive_secret()
+ *        with the appropriate labels.
+ *
+ * <tt>
+ *        Early Secret
+ *             |
+ *             +-----> Derive-Secret(., "c e traffic", ClientHello)
+ *             |                      = client_early_traffic_secret
+ *             |
+ *             +-----> Derive-Secret(., "e exp master", ClientHello)
+ *             .                      = early_exporter_master_secret
+ *             .
+ *             .
+ * </tt>
+ *
+ * \note  To obtain the actual key and IV for the early data traffic,
+ *        the client secret derived by this function need to be
+ *        further processed by mbedtls_ssl_tls1_3_make_traffic_keys().
+ *
+ * \note  The binder key, which is also generated from the early secret,
+ *        is omitted here. Its calculation is part of the separate routine
+ *        mbedtls_ssl_tls1_3_create_psk_binder().
+ *
+ * \param md_type      The hash algorithm associated with the PSK for which
+ *                     early data key material is being derived.
+ * \param early_secret The early secret from which the early data key material
+ *                     should be derived. This must be a readable buffer whose
+ *                     length is the digest size of the hash algorithm
+ *                     represented by \p md_size.
+ * \param transcript   The transcript of the handshake so far, calculated with
+ *                     respect to \p md_type. This must be a readable buffer
+ *                     whose length is the digest size of the hash algorithm
+ *                     represented by \p md_size.
+ * \param derived      The address of the structure in which to store
+ *                     the early data key material.
+ *
+ * \returns        \c 0 on success.
+ * \returns        A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_derive_early_secrets(
+          mbedtls_md_type_t md_type,
+          unsigned char const *early_secret,
+          unsigned char const *transcript, size_t transcript_len,
+          mbedtls_ssl_tls1_3_early_secrets *derived );
+
+/**
+ * \brief Derive TLS 1.3 handshake key material from the handshake secret.
+ *
+ *        This is a small wrapper invoking mbedtls_ssl_tls1_3_derive_secret()
+ *        with the appropriate labels from the standard.
+ *
+ * <tt>
+ *        Handshake Secret
+ *              |
+ *              +-----> Derive-Secret( ., "c hs traffic",
+ *              |                      ClientHello...ServerHello )
+ *              |                      = client_handshake_traffic_secret
+ *              |
+ *              +-----> Derive-Secret( ., "s hs traffic",
+ *              .                      ClientHello...ServerHello )
+ *              .                      = server_handshake_traffic_secret
+ *              .
+ * </tt>
+ *
+ * \note  To obtain the actual key and IV for the encrypted handshake traffic,
+ *        the client and server secret derived by this function need to be
+ *        further processed by mbedtls_ssl_tls1_3_make_traffic_keys().
+ *
+ * \param md_type           The hash algorithm associated with the ciphersuite
+ *                          that's being used for the connection.
+ * \param handshake_secret  The handshake secret from which the handshake key
+ *                          material should be derived. This must be a readable
+ *                          buffer whose length is the digest size of the hash
+ *                          algorithm represented by \p md_size.
+ * \param transcript        The transcript of the handshake so far, calculated
+ *                          with respect to \p md_type. This must be a readable
+ *                          buffer whose length is the digest size of the hash
+ *                          algorithm represented by \p md_size.
+ * \param derived           The address of the structure in which to
+ *                          store the handshake key material.
+ *
+ * \returns        \c 0 on success.
+ * \returns        A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_derive_handshake_secrets(
+          mbedtls_md_type_t md_type,
+          unsigned char const *handshake_secret,
+          unsigned char const *transcript, size_t transcript_len,
+          mbedtls_ssl_tls1_3_handshake_secrets *derived );
+
+/**
+ * \brief Derive TLS 1.3 application key material from the master secret.
+ *
+ *        This is a small wrapper invoking mbedtls_ssl_tls1_3_derive_secret()
+ *        with the appropriate labels from the standard.
+ *
+ * <tt>
+ *        Master Secret
+ *              |
+ *              +-----> Derive-Secret( ., "c ap traffic",
+ *              |                      ClientHello...server Finished )
+ *              |                      = client_application_traffic_secret_0
+ *              |
+ *              +-----> Derive-Secret( ., "s ap traffic",
+ *              |                      ClientHello...Server Finished )
+ *              |                      = server_application_traffic_secret_0
+ *              |
+ *              +-----> Derive-Secret( ., "exp master",
+ *              .                      ClientHello...server Finished)
+ *              .                      = exporter_master_secret
+ *              .
+ * </tt>
+ *
+ * \note  To obtain the actual key and IV for the (0-th) application traffic,
+ *        the client and server secret derived by this function need to be
+ *        further processed by mbedtls_ssl_tls1_3_make_traffic_keys().
+ *
+ * \param md_type           The hash algorithm associated with the ciphersuite
+ *                          that's being used for the connection.
+ * \param master_secret     The master secret from which the application key
+ *                          material should be derived. This must be a readable
+ *                          buffer whose length is the digest size of the hash
+ *                          algorithm represented by \p md_size.
+ * \param transcript        The transcript of the handshake up to and including
+ *                          the ServerFinished message, calculated with respect
+ *                          to \p md_type. This must be a readable buffer whose
+ *                          length is the digest size of the hash algorithm
+ *                          represented by \p md_type.
+ * \param derived           The address of the structure in which to
+ *                          store the application key material.
+ *
+ * \returns        \c 0 on success.
+ * \returns        A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_derive_application_secrets(
+          mbedtls_md_type_t md_type,
+          unsigned char const *master_secret,
+          unsigned char const *transcript, size_t transcript_len,
+          mbedtls_ssl_tls1_3_application_secrets *derived );
+
+/**
+ * \brief Derive TLS 1.3 resumption master secret from the master secret.
+ *
+ *        This is a small wrapper invoking mbedtls_ssl_tls1_3_derive_secret()
+ *        with the appropriate labels from the standard.
+ *
+ * \param md_type           The hash algorithm used in the application for which
+ *                          key material is being derived.
+ * \param application_secret The application secret from which the resumption master
+ *                          secret should be derived. This must be a readable
+ *                          buffer whose length is the digest size of the hash
+ *                          algorithm represented by \p md_size.
+ * \param transcript        The transcript of the handshake up to and including
+ *                          the ClientFinished message, calculated with respect
+ *                          to \p md_type. This must be a readable buffer whose
+ *                          length is the digest size of the hash algorithm
+ *                          represented by \p md_type.
+ * \param transcript_len    The length of \p transcript in Bytes.
+ * \param derived           The address of the structure in which to
+ *                          store the resumption master secret.
+ *
+ * \returns        \c 0 on success.
+ * \returns        A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_derive_resumption_master_secret(
+          mbedtls_md_type_t md_type,
+          unsigned char const *application_secret,
+          unsigned char const *transcript, size_t transcript_len,
+          mbedtls_ssl_tls1_3_application_secrets *derived );
+
+/**
  * \brief Compute the next secret in the TLS 1.3 key schedule
  *
  * The TLS 1.3 key schedule proceeds as follows to compute
@@ -271,4 +465,70 @@
                    const unsigned char *input, size_t input_len,
                    unsigned char *secret_new );
 
+#define MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL   0
+#define MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION 1
+
+/**
+ * \brief             Calculate a TLS 1.3 PSK binder.
+ *
+ * \param ssl         The SSL context. This is used for debugging only and may
+ *                    be \c NULL if MBEDTLS_DEBUG_C is disabled.
+ * \param md_type     The hash algorithm associated to the PSK \p psk.
+ * \param psk         The buffer holding the PSK for which to create a binder.
+ * \param psk_len     The size of \p psk in bytes.
+ * \param psk_type    This indicates whether the PSK \p psk is externally
+ *                    provisioned (#MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL) or a
+ *                    resumption PSK (#MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION).
+ * \param transcript  The handshake transcript up to the point where the
+ *                    PSK binder calculation happens. This must be readable,
+ *                    and its size must be equal to the digest size of
+ *                    the hash algorithm represented by \p md_type.
+ * \param result      The address at which to store the PSK binder on success.
+ *                    This must be writable, and its size must be equal to the
+ *                    digest size of  the hash algorithm represented by
+ *                    \p md_type.
+ *
+ * \returns           \c 0 on success.
+ * \returns           A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl,
+                               const mbedtls_md_type_t md_type,
+                               unsigned char const *psk, size_t psk_len,
+                               int psk_type,
+                               unsigned char const *transcript,
+                               unsigned char *result );
+
+/**
+ * \bref Setup an SSL transform structure representing the
+ *       record protection mechanism used by TLS 1.3
+ *
+ * \param transform    The SSL transform structure to be created. This must have
+ *                     been initialized through mbedtls_ssl_transform_init() and
+ *                     not used in any other way prior to calling this function.
+ *                     In particular, this function does not clean up the
+ *                     transform structure prior to installing the new keys.
+ * \param endpoint     Indicates whether the transform is for the client
+ *                     (value #MBEDTLS_SSL_IS_CLIENT) or the server
+ *                     (value #MBEDTLS_SSL_IS_SERVER).
+ * \param ciphersuite  The numerical identifier for the ciphersuite to use.
+ *                     This must be one of the identifiers listed in
+ *                     ssl_ciphersuites.h.
+ * \param traffic_keys The key material to use. No reference is stored in
+ *                     the SSL transform being generated, and the caller
+ *                     should destroy the key material afterwards.
+ * \param ssl          (Debug-only) The SSL context to use for debug output
+ *                     in case of failure. This parameter is only needed if
+ *                     #MBEDTLS_DEBUG_C is set, and is ignored otherwise.
+ *
+ * \return             \c 0 on success. In this case, \p transform is ready to
+ *                     be used with mbedtls_ssl_transform_decrypt() and
+ *                     mbedtls_ssl_transform_encrypt().
+ * \return             A negative error code on failure.
+ */
+int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform,
+                                          int endpoint,
+                                          int ciphersuite,
+                                          mbedtls_ssl_key_set const *traffic_keys,
+                                          mbedtls_ssl_context *ssl );
+
 #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
new file mode 100644
index 0000000..0dcd7ed
--- /dev/null
+++ b/library/ssl_tls13_server.c
@@ -0,0 +1,36 @@
+/*
+ *  TLS 1.3 server-side 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.
+*/
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#if defined(MBEDTLS_SSL_SRV_C)
+
+#include "ssl_misc.h"
+
+int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl )
+{
+    ((void) ssl);
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/threading.c b/library/threading.c
index 2de117f..bae6644 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -19,7 +19,7 @@
 
 /*
  * Ensure gmtime_r is available even with -std=c99; must be defined before
- * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ * mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms.
  */
 #if !defined(_POSIX_C_SOURCE)
 #define _POSIX_C_SOURCE 200112L
diff --git a/library/timing.c b/library/timing.c
index eb41461..8a02c00 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -19,13 +19,6 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf     printf
-#endif
-
 #if defined(MBEDTLS_TIMING_C)
 
 #include "mbedtls/timing.h"
@@ -35,11 +28,7 @@
 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
     !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
     !defined(__HAIKU__) && !defined(__midipix__)
-#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h"
-#endif
-
-#ifndef asm
-#define asm __asm
+#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in mbedtls_config.h"
 #endif
 
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
@@ -67,174 +56,25 @@
 
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long tsc;
-    __asm   rdtsc
-    __asm   mov  [tsc], eax
-    return( tsc );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */
-
-/* some versions of mingw-64 have 32-bit longs even on x84_64 */
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && ( defined(__i386__) || (                       \
-    ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) )
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long lo, hi;
-    asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
-    return( lo );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __i386__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) )
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long lo, hi;
-    asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
-    return( lo | ( hi << 32 ) );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && ( __amd64__ || __x86_64__ ) */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) )
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long tbl, tbu0, tbu1;
-
-    do
-    {
-        asm volatile( "mftbu %0" : "=r" (tbu0) );
-        asm volatile( "mftb  %0" : "=r" (tbl ) );
-        asm volatile( "mftbu %0" : "=r" (tbu1) );
-    }
-    while( tbu0 != tbu1 );
-
-    return( tbl );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && ( __powerpc__ || __ppc__ ) */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && defined(__sparc64__)
-
-#if defined(__OpenBSD__)
-#warning OpenBSD does not allow access to tick register using software version instead
-#else
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long tick;
-    asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) );
-    return( tick );
-}
-#endif /* __OpenBSD__ */
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __sparc64__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long tick;
-    asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" );
-    asm volatile( "mov   %%g1, %0" : "=r" (tick) );
-    return( tick );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __sparc__ && !__sparc64__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
-    defined(__GNUC__) && defined(__alpha__)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long cc;
-    asm volatile( "rpcc %0" : "=r" (cc) );
-    return( cc & 0xFFFFFFFF );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __alpha__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
-    defined(__GNUC__) && defined(__ia64__)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long itc;
-    asm volatile( "mov %0 = ar.itc" : "=r" (itc) );
-    return( itc );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __ia64__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \
-    !defined(EFIX64) && !defined(EFI32)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    LARGE_INTEGER offset;
-
-    QueryPerformanceCounter( &offset );
-
-    return( (unsigned long)( offset.QuadPart ) );
-}
-#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */
-
-#if !defined(HAVE_HARDCLOCK)
-
-#define HAVE_HARDCLOCK
-
-static int hardclock_init = 0;
-static struct timeval tv_init;
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    struct timeval tv_cur;
-
-    if( hardclock_init == 0 )
-    {
-        gettimeofday( &tv_init, NULL );
-        hardclock_init = 1;
-    }
-
-    gettimeofday( &tv_cur, NULL );
-    return( ( tv_cur.tv_sec  - tv_init.tv_sec  ) * 1000000
-          + ( tv_cur.tv_usec - tv_init.tv_usec ) );
-}
-#endif /* !HAVE_HARDCLOCK */
-
-volatile int mbedtls_timing_alarmed = 0;
-
+/**
+ * \brief          Return the elapsed time in milliseconds
+ *
+ * \warning        May change without notice
+ *
+ * \param val      points to a timer structure
+ * \param reset    If 0, query the elapsed time. Otherwise (re)start the timer.
+ *
+ * \return         Elapsed time since the previous reset in ms. When
+ *                 restarting, this is always 0.
+ *
+ * \note           To initialize a timer, call this function with reset=1.
+ *
+ *                 Determining the elapsed time and resetting the timer is not
+ *                 atomic on all platforms, so after the sequence
+ *                 `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
+ *                 get_timer(0) }` the value time1+time2 is only approximately
+ *                 the delay since the first reset.
+ */
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 
 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
@@ -258,33 +98,6 @@
     }
 }
 
-/* It's OK to use a global because alarm() is supposed to be global anyway */
-static DWORD alarmMs;
-
-static void TimerProc( void *TimerContext )
-{
-    (void) TimerContext;
-    Sleep( alarmMs );
-    mbedtls_timing_alarmed = 1;
-    /* _endthread will be called implicitly on return
-     * That ensures execution of thread funcition's epilogue */
-}
-
-void mbedtls_set_alarm( int seconds )
-{
-    if( seconds == 0 )
-    {
-        /* No need to create a thread for this simple case.
-         * Also, this shorcut is more reliable at least on MinGW32 */
-        mbedtls_timing_alarmed = 1;
-        return;
-    }
-
-    mbedtls_timing_alarmed = 0;
-    alarmMs = seconds * 1000;
-    (void) _beginthread( TimerProc, 0, NULL );
-}
-
 #else /* _WIN32 && !EFIX64 && !EFI32 */
 
 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
@@ -307,25 +120,6 @@
     }
 }
 
-static void sighandler( int signum )
-{
-    mbedtls_timing_alarmed = 1;
-    signal( signum, sighandler );
-}
-
-void mbedtls_set_alarm( int seconds )
-{
-    mbedtls_timing_alarmed = 0;
-    signal( SIGALRM, sighandler );
-    alarm( seconds );
-    if( seconds == 0 )
-    {
-        /* alarm(0) cancelled any previous pending alarm, but the
-           handler won't fire, so raise the flag straight away. */
-        mbedtls_timing_alarmed = 1;
-    }
-}
-
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 
 /*
@@ -365,166 +159,4 @@
 }
 
 #endif /* !MBEDTLS_TIMING_ALT */
-
-#if defined(MBEDTLS_SELF_TEST)
-
-/*
- * Busy-waits for the given number of milliseconds.
- * Used for testing mbedtls_timing_hardclock.
- */
-static void busy_msleep( unsigned long msec )
-{
-    struct mbedtls_timing_hr_time hires;
-    unsigned long i = 0; /* for busy-waiting */
-    volatile unsigned long j; /* to prevent optimisation */
-
-    (void) mbedtls_timing_get_timer( &hires, 1 );
-
-    while( mbedtls_timing_get_timer( &hires, 0 ) < msec )
-        i++;
-
-    j = i;
-    (void) j;
-}
-
-#define FAIL    do                                                      \
-    {                                                                   \
-        if( verbose != 0 )                                              \
-        {                                                               \
-            mbedtls_printf( "failed at line %d\n", __LINE__ );          \
-            mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \
-                            cycles, ratio, millisecs, secs, hardfail,   \
-                            (unsigned long) a, (unsigned long) b );     \
-            mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n", \
-                            mbedtls_timing_get_timer( &hires, 0 ),      \
-                            mbedtls_timing_get_timer( &ctx.timer, 0 ),  \
-                            mbedtls_timing_get_delay( &ctx ) );         \
-        }                                                               \
-        return( 1 );                                                    \
-    } while( 0 )
-
-/*
- * Checkup routine
- *
- * Warning: this is work in progress, some tests may not be reliable enough
- * yet! False positives may happen.
- */
-int mbedtls_timing_self_test( int verbose )
-{
-    unsigned long cycles = 0, ratio = 0;
-    unsigned long millisecs = 0, secs = 0;
-    int hardfail = 0;
-    struct mbedtls_timing_hr_time hires;
-    uint32_t a = 0, b = 0;
-    mbedtls_timing_delay_context ctx;
-
-    if( verbose != 0 )
-        mbedtls_printf( "  TIMING tests note: will take some time!\n" );
-
-    if( verbose != 0 )
-        mbedtls_printf( "  TIMING test #1 (set_alarm / get_timer): " );
-
-    {
-        secs = 1;
-
-        (void) mbedtls_timing_get_timer( &hires, 1 );
-
-        mbedtls_set_alarm( (int) secs );
-        while( !mbedtls_timing_alarmed )
-            ;
-
-        millisecs = mbedtls_timing_get_timer( &hires, 0 );
-
-        /* For some reason on Windows it looks like alarm has an extra delay
-         * (maybe related to creating a new thread). Allow some room here. */
-        if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
-            FAIL;
-    }
-
-    if( verbose != 0 )
-        mbedtls_printf( "passed\n" );
-
-    if( verbose != 0 )
-        mbedtls_printf( "  TIMING test #2 (set/get_delay        ): " );
-
-    {
-        a = 800;
-        b = 400;
-        mbedtls_timing_set_delay( &ctx, a, a + b );          /* T = 0 */
-
-        busy_msleep( a - a / 4 );                      /* T = a - a/4 */
-        if( mbedtls_timing_get_delay( &ctx ) != 0 )
-            FAIL;
-
-        busy_msleep( a / 4 + b / 4 );                  /* T = a + b/4 */
-        if( mbedtls_timing_get_delay( &ctx ) != 1 )
-            FAIL;
-
-        busy_msleep( b );                          /* T = a + b + b/4 */
-        if( mbedtls_timing_get_delay( &ctx ) != 2 )
-            FAIL;
-    }
-
-    mbedtls_timing_set_delay( &ctx, 0, 0 );
-    busy_msleep( 200 );
-    if( mbedtls_timing_get_delay( &ctx ) != -1 )
-        FAIL;
-
-    if( verbose != 0 )
-        mbedtls_printf( "passed\n" );
-
-    if( verbose != 0 )
-        mbedtls_printf( "  TIMING test #3 (hardclock / get_timer): " );
-
-    /*
-     * Allow one failure for possible counter wrapping.
-     * On a 4Ghz 32-bit machine the cycle counter wraps about once per second;
-     * since the whole test is about 10ms, it shouldn't happen twice in a row.
-     */
-
-hard_test:
-    if( hardfail > 1 )
-    {
-        if( verbose != 0 )
-            mbedtls_printf( "failed (ignored)\n" );
-
-        goto hard_test_done;
-    }
-
-    /* Get a reference ratio cycles/ms */
-    millisecs = 1;
-    cycles = mbedtls_timing_hardclock();
-    busy_msleep( millisecs );
-    cycles = mbedtls_timing_hardclock() - cycles;
-    ratio = cycles / millisecs;
-
-    /* Check that the ratio is mostly constant */
-    for( millisecs = 2; millisecs <= 4; millisecs++ )
-    {
-        cycles = mbedtls_timing_hardclock();
-        busy_msleep( millisecs );
-        cycles = mbedtls_timing_hardclock() - cycles;
-
-        /* Allow variation up to 20% */
-        if( cycles / millisecs < ratio - ratio / 5 ||
-            cycles / millisecs > ratio + ratio / 5 )
-        {
-            hardfail++;
-            goto hard_test;
-        }
-    }
-
-    if( verbose != 0 )
-        mbedtls_printf( "passed\n" );
-
-hard_test_done:
-
-    if( verbose != 0 )
-        mbedtls_printf( "\n" );
-
-    return( 0 );
-}
-
-#endif /* MBEDTLS_SELF_TEST */
-
 #endif /* MBEDTLS_TIMING_C */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index b4fe886..c865444 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -95,33 +95,43 @@
  */
 #define X509_MAX_VERIFY_CHAIN_SIZE    ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
 
-/*
- * Default profile
- */
+/* Default profile. Do not remove items unless there are serious security
+ * concerns. */
 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
 {
-    /* Only SHA-2 hashes */
-    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
-    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
-    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
-    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
-    0xFFFFFFF, /* Any PK alg    */
-    0xFFFFFFF, /* Any curve     */
-    2048,
-};
-
-/*
- * Next-default profile
- */
-const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
-{
-    /* Hashes from SHA-256 and above */
+    /* Hashes from SHA-256 and above. Note that this selection
+     * should be aligned with ssl_preset_default_hashes in ssl_tls.c. */
     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
     0xFFFFFFF, /* Any PK alg    */
 #if defined(MBEDTLS_ECP_C)
-    /* Curves at or above 128-bit security level */
+    /* Curves at or above 128-bit security level. Note that this selection
+     * should be aligned with ssl_preset_default_curves in ssl_tls.c. */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) |
+    0,
+#else
+    0,
+#endif
+    2048,
+};
+
+/* Next-generation profile. Currently identical to the default, but may
+ * be tightened at any time. */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
+{
+    /* Hashes from SHA-256 and above. */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
+    0xFFFFFFF, /* Any PK alg    */
+#if defined(MBEDTLS_ECP_C)
+    /* Curves at or above 128-bit security level. */
     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
@@ -157,6 +167,17 @@
 };
 
 /*
+ * Empty / all-forbidden profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_none =
+{
+    0,
+    0,
+    0,
+    (uint32_t) -1,
+};
+
+/*
  * Check md_alg against profile
  * Return 0 if md_alg is acceptable for this profile, -1 otherwise
  */
@@ -818,8 +839,7 @@
         {
             /*
              * Set the parsing return code but continue parsing, in case this
-             * extension is critical and MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
-             * is configured.
+             * extension is critical.
              */
             parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
         }
@@ -961,14 +981,12 @@
             /* No parser found, skip extension */
             *p = end_ext_octet;
 
-#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
             if( is_critical )
             {
                 /* Data is marked as critical: fail */
                 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
                         MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
             }
-#endif
             continue;
         }
 
@@ -1027,11 +1045,9 @@
                         start_ext_octet, end_ext_octet ) == 0 )
                     break;
 
-#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
                 if( is_critical )
                     return( ret );
                 else
-#endif
                 /*
                  * If MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE is returned, then we
                  * cannot interpret or enforce the policy. However, it is up to
@@ -1049,11 +1065,9 @@
              * supports, but there isn't an x509 parser for it,
              * skip the extension.
              */
-#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
             if( is_critical )
                 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
             else
-#endif
                 *p = end_ext_octet;
         }
     }
@@ -1268,9 +1282,7 @@
         }
     }
 
-#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
     if( crt->version == 3 )
-#endif
     {
         ret = x509_get_crt_ext( &p, end, crt, cb, p_ctx );
         if( ret != 0 )
@@ -2240,7 +2252,6 @@
 }
 #endif /* MBEDTLS_X509_REMOVE_INFO */
 
-#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
 int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
                                       unsigned int usage )
 {
@@ -2263,9 +2274,7 @@
 
     return( 0 );
 }
-#endif
 
-#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
 int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
                                        const char *usage_oid,
                                        size_t usage_len )
@@ -2295,7 +2304,6 @@
 
     return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
 }
-#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
 
 #if defined(MBEDTLS_X509_CRL_PARSE_C)
 /*
@@ -2346,14 +2354,12 @@
         /*
          * Check if the CA is configured to sign CRLs
          */
-#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
         if( mbedtls_x509_crt_check_key_usage( ca,
                                               MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
         {
             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
             break;
         }
-#endif
 
         /*
          * Check if CRL is correctly signed by the trusted CA
@@ -2490,13 +2496,11 @@
     if( need_ca_bit && ! parent->ca_istrue )
         return( -1 );
 
-#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
     if( need_ca_bit &&
         mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
     {
         return( -1 );
     }
-#endif
 
     return( 0 );
 }
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 8f4a4f5..17b3e79 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -178,7 +178,7 @@
     MBEDTLS_ASN1_CHK_ADD( len,
                 mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
 
-    ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
+    ret = mbedtls_sha1( buf + sizeof( buf ) - len, len,
                             buf + sizeof( buf ) - 20 );
     if( ret != 0 )
         return( ret );
@@ -206,7 +206,7 @@
     MBEDTLS_ASN1_CHK_ADD( len,
                           mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
 
-    ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
+    ret = mbedtls_sha1( buf + sizeof( buf ) - len, len,
                             buf + sizeof( buf ) - 20 );
     if( ret != 0 )
         return( ret );
@@ -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 )
@@ -474,7 +473,7 @@
     }
 
     if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg,
-                                 hash, 0, sig, &sig_len,
+                                 hash, 0, sig, sizeof( sig ), &sig_len,
                                  f_rng, p_rng ) ) != 0 )
     {
         return( ret );
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index 9f0ad93..555f296 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -136,7 +136,7 @@
 static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
                                  unsigned char *buf,
                                  size_t size,
-                                 unsigned char *sig,
+                                 unsigned char *sig, size_t sig_size,
                                  int (*f_rng)(void *, unsigned char *, size_t),
                                  void *p_rng )
 {
@@ -235,7 +235,8 @@
     if( ret != 0 )
         return( ret );
 #endif
-    if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
+    if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0,
+                                 sig, sig_size, &sig_len,
                                  f_rng, p_rng ) ) != 0 )
     {
         return( ret );
@@ -304,7 +305,9 @@
         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
     }
 
-    ret = x509write_csr_der_internal( ctx, buf, size, sig, f_rng, p_rng );
+    ret = x509write_csr_der_internal( ctx, buf, size,
+                                      sig, MBEDTLS_PK_SIGNATURE_MAX_SIZE,
+                                      f_rng, p_rng );
 
     mbedtls_free( sig );
 
diff --git a/library/xtea.c b/library/xtea.c
deleted file mode 100644
index 4b8c9c0..0000000
--- a/library/xtea.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- *  An 32-bit implementation of the XTEA algorithm
- *
- *  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.
- */
-
-#include "common.h"
-
-#if defined(MBEDTLS_XTEA_C)
-
-#include "mbedtls/xtea.h"
-#include "mbedtls/platform_util.h"
-
-#include <string.h>
-
-#if defined(MBEDTLS_SELF_TEST)
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST */
-
-#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 ) );
-}
-
-void mbedtls_xtea_free( mbedtls_xtea_context *ctx )
-{
-    if( ctx == NULL )
-        return;
-
-    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_xtea_context ) );
-}
-
-/*
- * XTEA key schedule
- */
-void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] )
-{
-    int i;
-
-    memset( ctx, 0, sizeof(mbedtls_xtea_context) );
-
-    for( i = 0; i < 4; i++ )
-    {
-        GET_UINT32_BE( ctx->k[i], key, i << 2 );
-    }
-}
-
-/*
- * XTEA encrypt function
- */
-int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode,
-                    const unsigned char input[8], unsigned char output[8])
-{
-    uint32_t *k, v0, v1, i;
-
-    k = ctx->k;
-
-    GET_UINT32_BE( v0, input, 0 );
-    GET_UINT32_BE( v1, input, 4 );
-
-    if( mode == MBEDTLS_XTEA_ENCRYPT )
-    {
-        uint32_t sum = 0, delta = 0x9E3779B9;
-
-        for( i = 0; i < 32; i++ )
-        {
-            v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
-            sum += delta;
-            v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
-        }
-    }
-    else /* MBEDTLS_XTEA_DECRYPT */
-    {
-        uint32_t delta = 0x9E3779B9, sum = delta * 32;
-
-        for( i = 0; i < 32; i++ )
-        {
-            v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
-            sum -= delta;
-            v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
-        }
-    }
-
-    PUT_UINT32_BE( v0, output, 0 );
-    PUT_UINT32_BE( v1, output, 4 );
-
-    return( 0 );
-}
-
-#if defined(MBEDTLS_CIPHER_MODE_CBC)
-/*
- * XTEA-CBC buffer encryption/decryption
- */
-int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length,
-                    unsigned char iv[8], const unsigned char *input,
-                    unsigned char *output)
-{
-    int i;
-    unsigned char temp[8];
-
-    if( length % 8 )
-        return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH );
-
-    if( mode == MBEDTLS_XTEA_DECRYPT )
-    {
-        while( length > 0 )
-        {
-            memcpy( temp, input, 8 );
-            mbedtls_xtea_crypt_ecb( ctx, mode, input, output );
-
-            for( i = 0; i < 8; i++ )
-                output[i] = (unsigned char)( output[i] ^ iv[i] );
-
-            memcpy( iv, temp, 8 );
-
-            input  += 8;
-            output += 8;
-            length -= 8;
-        }
-    }
-    else
-    {
-        while( length > 0 )
-        {
-            for( i = 0; i < 8; i++ )
-                output[i] = (unsigned char)( input[i] ^ iv[i] );
-
-            mbedtls_xtea_crypt_ecb( ctx, mode, output, output );
-            memcpy( iv, output, 8 );
-
-            input  += 8;
-            output += 8;
-            length -= 8;
-        }
-    }
-
-    return( 0 );
-}
-#endif /* MBEDTLS_CIPHER_MODE_CBC */
-#endif /* !MBEDTLS_XTEA_ALT */
-
-#if defined(MBEDTLS_SELF_TEST)
-
-/*
- * XTEA tests vectors (non-official)
- */
-
-static const unsigned char xtea_test_key[6][16] =
-{
-   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
-     0x0c, 0x0d, 0x0e, 0x0f },
-   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
-     0x0c, 0x0d, 0x0e, 0x0f },
-   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
-     0x0c, 0x0d, 0x0e, 0x0f },
-   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-     0x00, 0x00, 0x00, 0x00 },
-   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-     0x00, 0x00, 0x00, 0x00 },
-   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-     0x00, 0x00, 0x00, 0x00 }
-};
-
-static const unsigned char xtea_test_pt[6][8] =
-{
-    { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
-    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
-    { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
-    { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
-    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
-    { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
-};
-
-static const unsigned char xtea_test_ct[6][8] =
-{
-    { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
-    { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
-    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
-    { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
-    { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
-    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
-};
-
-/*
- * Checkup routine
- */
-int mbedtls_xtea_self_test( int verbose )
-{
-    int i, ret = 0;
-    unsigned char buf[8];
-    mbedtls_xtea_context ctx;
-
-    mbedtls_xtea_init( &ctx );
-    for( i = 0; i < 6; i++ )
-    {
-        if( verbose != 0 )
-            mbedtls_printf( "  XTEA test #%d: ", i + 1 );
-
-        memcpy( buf, xtea_test_pt[i], 8 );
-
-        mbedtls_xtea_setup( &ctx, xtea_test_key[i] );
-        mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf );
-
-        if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
-        {
-            if( verbose != 0 )
-                mbedtls_printf( "failed\n" );
-
-            ret = 1;
-            goto exit;
-        }
-
-        if( verbose != 0 )
-            mbedtls_printf( "passed\n" );
-    }
-
-    if( verbose != 0 )
-        mbedtls_printf( "\n" );
-
-exit:
-    mbedtls_xtea_free( &ctx );
-
-    return( ret );
-}
-
-#endif /* MBEDTLS_SELF_TEST */
-
-#endif /* MBEDTLS_XTEA_C */