Merge remote-tracking branch 'origin/pr/648' into baremetal
diff --git a/configs/baremetal_test.h b/configs/baremetal_test.h
index 82c0ed1..b107bd7 100644
--- a/configs/baremetal_test.h
+++ b/configs/baremetal_test.h
@@ -37,21 +37,6 @@
 /* Debug output */
 #define MBEDTLS_DEBUG_C
 
-/* We don't have DER-encoded test CRTs yet. */
-#define MBEDTLS_PEM_PARSE_C
-#define MBEDTLS_BASE64_C
-/* We don't have Secp256r1 test CRTs at the moment. */
-#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
-
-/* Correct ECP configuration values */
-#undef MBEDTLS_ECP_MAX_BITS
-#undef MBEDTLS_MPI_MAX_SIZE
-#define MBEDTLS_ECP_MAX_BITS 384
-#define MBEDTLS_MPI_MAX_SIZE 48
-
-/* ssl_client2 and ssl_server2 use CTR-DRBG so far. */
-#define MBEDTLS_CTR_DRBG_C
-
 /* The ticket implementation hardcodes AES-GCM */
 #define MBEDTLS_GCM_C
 
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 32f5939..df221fe 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -58,6 +58,14 @@
 #include "tinycrypt/ecc_dh.h"
 #endif
 
+#if defined(__GNUC__) || defined(__arm__)
+#define MBEDTLS_ALWAYS_INLINE __attribute__((always_inline))
+#define MBEDTLS_NO_INLINE __attribute__((noinline))
+#else
+#define MBEDTLS_ALWAYS_INLINE
+#define MBEDTLS_NO_INLINE
+#endif
+
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
 #define inline __inline
@@ -499,13 +507,6 @@
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
-    void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
-    void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *);
-    void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
-    int  (*tls_prf)(const unsigned char *, size_t, const char *,
-                    const unsigned char *, size_t,
-                    unsigned char *, size_t);
-
 #if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE)
     mbedtls_ssl_ciphersuite_handle_t ciphersuite_info;
 #endif /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */
@@ -1011,7 +1012,6 @@
 
 mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash );
 unsigned char mbedtls_ssl_hash_from_md_alg( int md );
-int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md );
 
 #if defined(MBEDTLS_ECP_C)
 int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
@@ -1185,9 +1185,8 @@
  * 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)
  */
-static inline void mbedtls_ssl_write_version( int major, int minor,
-                                              int transport,
-                                              unsigned char ver[2] )
+MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_write_version(
+    int major, int minor, int transport, unsigned char ver[2] )
 {
 #if !defined(MBEDTLS_SSL_TRANSPORT__BOTH)
     ((void) transport);
@@ -1212,9 +1211,8 @@
 #endif
 }
 
-static inline void mbedtls_ssl_read_version( int *major, int *minor,
-                                             int transport,
-                                             const unsigned char ver[2] )
+MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_read_version(
+    int *major, int *minor, int transport, const unsigned char ver[2] )
 {
 #if !defined(MBEDTLS_SSL_TRANSPORT__BOTH)
     ((void) transport);
@@ -1803,12 +1801,6 @@
 
 #endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */
 
-#if defined(__GNUC__) || defined(__arm__)
-#define MBEDTLS_ALWAYS_INLINE __attribute__((always_inline))
-#else
-#define MBEDTLS_ALWAYS_INLINE
-#endif
-
 /* This internal function can be used to pend a fatal alert for
  * later delivery.
  *
@@ -1842,6 +1834,31 @@
 #endif
 }
 
+MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_update_checksum(
+    mbedtls_ssl_context *ssl,
+    const unsigned char *buf, size_t len )
+{
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+     mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
+    mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+}
+
+int mbedtls_ssl_calc_verify( int minor_ver,
+                             mbedtls_md_type_t hash,
+                             mbedtls_ssl_context const *ssl,
+                             unsigned char *dst,
+                             size_t *hlen );
+
 #define MBEDTLS_SSL_CHK(f) do { if( ( ret = f ) < 0 ) goto cleanup; } while( 0 )
 
 #if defined(MBEDTLS_USE_TINYCRYPT)
diff --git a/library/certs.c b/library/certs.c
index 80ab0b9..327a772 100644
--- a/library/certs.c
+++ b/library/certs.c
@@ -42,6 +42,101 @@
  *
  */
 
+/* Use CRTs with Secp256r1-only if Secp384r1 is disabled.
+ * Otherwise, fall back to previous test CRTs using both
+ * Secp256r1 and Secp384r1. */
+#if !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+
+/* This is taken from tests/data_files/test-ca3.crt.pem */
+/* BEGIN FILE string macro TEST_CA_CRT_EC_PEM tests/data_files/test-ca3.crt.pem */
+#define TEST_CA_CRT_EC_PEM                                                 \
+    "-----BEGIN CERTIFICATE-----\r\n"                                      \
+    "MIIBuTCCAV2gAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg\r\n" \
+    "Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w\r\n" \
+    "MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMDsxGjAYBgNVBAMMEVRlc3QgQ0Eg\r\n" \
+    "U2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzBZMBMGByqG\r\n" \
+    "SM49AgEGCCqGSM49AwEHA0IABLZIHgilzw/iCx1r09kyZsZfarzztX4y1km0S5Mx\r\n" \
+    "rsFB67NjUhXE6/YY3W38oxeY4eIvEb516BOR/g3e3OL7Q8WjUDBOMAwGA1UdEwQF\r\n" \
+    "MAMBAf8wHQYDVR0OBBYEFEpepGEzSxZIDDF4IjXW+85Q5yASMB8GA1UdIwQYMBaA\r\n" \
+    "FEpepGEzSxZIDDF4IjXW+85Q5yASMAwGCCqGSM49BAMCBQADSAAwRQIhAKejV1jK\r\n" \
+    "vPH1vIsZAr6/VmSvjXkxmT2rpzEP9iJvJAteAiBhCPtV7LdSF1ZUqphAK3DYh2m7\r\n" \
+    "l1eSxSKXB29adbF96g==\r\n"                                             \
+    "-----END CERTIFICATE-----\r\n"
+/* END FILE */
+
+/* This is generated from tests/data_files/test-ca3.crt.der using `xxd -i`. */
+/* BEGIN FILE binary macro TEST_CA_CRT_EC_DER tests/data_files/test-ca3.crt.der */
+#define TEST_CA_CRT_EC_DER {                                                 \
+    0x30, 0x82, 0x01, 0xb9, 0x30, 0x82, 0x01, 0x5d, 0xa0, 0x03, 0x02, 0x01,  \
+    0x02, 0x02, 0x01, 0x01, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,  \
+    0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x1a, 0x30, 0x18,  \
+    0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20,  \
+    0x43, 0x41, 0x20, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31,  \
+    0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d,  \
+    0x62, 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,  \
+    0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x1e, 0x17, 0x0d, 0x30,  \
+    0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,  \
+    0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39,  \
+    0x35, 0x39, 0x5a, 0x30, 0x3b, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55,  \
+    0x04, 0x03, 0x0c, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x20,  \
+    0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, 0x31, 0x10, 0x30,  \
+    0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x62, 0x65, 0x64,  \
+    0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,  \
+    0x13, 0x02, 0x55, 0x4b, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,  \
+    0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,  \
+    0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xb6, 0x48, 0x1e, 0x08, 0xa5,  \
+    0xcf, 0x0f, 0xe2, 0x0b, 0x1d, 0x6b, 0xd3, 0xd9, 0x32, 0x66, 0xc6, 0x5f,  \
+    0x6a, 0xbc, 0xf3, 0xb5, 0x7e, 0x32, 0xd6, 0x49, 0xb4, 0x4b, 0x93, 0x31,  \
+    0xae, 0xc1, 0x41, 0xeb, 0xb3, 0x63, 0x52, 0x15, 0xc4, 0xeb, 0xf6, 0x18,  \
+    0xdd, 0x6d, 0xfc, 0xa3, 0x17, 0x98, 0xe1, 0xe2, 0x2f, 0x11, 0xbe, 0x75,  \
+    0xe8, 0x13, 0x91, 0xfe, 0x0d, 0xde, 0xdc, 0xe2, 0xfb, 0x43, 0xc5, 0xa3,  \
+    0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05,  \
+    0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,  \
+    0x04, 0x16, 0x04, 0x14, 0x4a, 0x5e, 0xa4, 0x61, 0x33, 0x4b, 0x16, 0x48,  \
+    0x0c, 0x31, 0x78, 0x22, 0x35, 0xd6, 0xfb, 0xce, 0x50, 0xe7, 0x20, 0x12,  \
+    0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,  \
+    0x14, 0x4a, 0x5e, 0xa4, 0x61, 0x33, 0x4b, 0x16, 0x48, 0x0c, 0x31, 0x78,  \
+    0x22, 0x35, 0xd6, 0xfb, 0xce, 0x50, 0xe7, 0x20, 0x12, 0x30, 0x0c, 0x06,  \
+    0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03,  \
+    0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xa7, 0xa3, 0x57, 0x58, 0xca,  \
+    0xbc, 0xf1, 0xf5, 0xbc, 0x8b, 0x19, 0x02, 0xbe, 0xbf, 0x56, 0x64, 0xaf,  \
+    0x8d, 0x79, 0x31, 0x99, 0x3d, 0xab, 0xa7, 0x31, 0x0f, 0xf6, 0x22, 0x6f,  \
+    0x24, 0x0b, 0x5e, 0x02, 0x20, 0x61, 0x08, 0xfb, 0x55, 0xec, 0xb7, 0x52,  \
+    0x17, 0x56, 0x54, 0xaa, 0x98, 0x40, 0x2b, 0x70, 0xd8, 0x87, 0x69, 0xbb,  \
+    0x97, 0x57, 0x92, 0xc5, 0x22, 0x97, 0x07, 0x6f, 0x5a, 0x75, 0xb1, 0x7d,  \
+    0xea                                                                     \
+}
+/* END FILE */
+
+/* This is taken from tests/data_files/test-ca3.key.pem */
+/* BEGIN FILE string macro TEST_CA_KEY_EC_PEM tests/data_files/test-ca3.key.pem */
+#define TEST_CA_KEY_EC_PEM                                                 \
+    "-----BEGIN EC PRIVATE KEY-----\r\n"                                   \
+    "MHcCAQEEIDlfIVA04pd23r9UJhLf0kt6SkROecrhPbNWtawigBCkoAoGCCqGSM49\r\n" \
+    "AwEHoUQDQgAEtkgeCKXPD+ILHWvT2TJmxl9qvPO1fjLWSbRLkzGuwUHrs2NSFcTr\r\n" \
+    "9hjdbfyjF5jh4i8RvnXoE5H+Dd7c4vtDxQ==\r\n"                             \
+    "-----END EC PRIVATE KEY-----\r\n"
+/* END FILE */
+
+/* This is generated from tests/data_files/test-ca3.key.der using `xxd -i`. */
+/* BEGIN FILE binary macro TEST_CA_KEY_EC_DER tests/data_files/test-ca3.key.der */
+#define TEST_CA_KEY_EC_DER {                                                 \
+    0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x39, 0x5f, 0x21, 0x50, 0x34,  \
+    0xe2, 0x97, 0x76, 0xde, 0xbf, 0x54, 0x26, 0x12, 0xdf, 0xd2, 0x4b, 0x7a,  \
+    0x4a, 0x44, 0x4e, 0x79, 0xca, 0xe1, 0x3d, 0xb3, 0x56, 0xb5, 0xac, 0x22,  \
+    0x80, 0x10, 0xa4, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,  \
+    0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xb6, 0x48, 0x1e,  \
+    0x08, 0xa5, 0xcf, 0x0f, 0xe2, 0x0b, 0x1d, 0x6b, 0xd3, 0xd9, 0x32, 0x66,  \
+    0xc6, 0x5f, 0x6a, 0xbc, 0xf3, 0xb5, 0x7e, 0x32, 0xd6, 0x49, 0xb4, 0x4b,  \
+    0x93, 0x31, 0xae, 0xc1, 0x41, 0xeb, 0xb3, 0x63, 0x52, 0x15, 0xc4, 0xeb,  \
+    0xf6, 0x18, 0xdd, 0x6d, 0xfc, 0xa3, 0x17, 0x98, 0xe1, 0xe2, 0x2f, 0x11,  \
+    0xbe, 0x75, 0xe8, 0x13, 0x91, 0xfe, 0x0d, 0xde, 0xdc, 0xe2, 0xfb, 0x43,  \
+    0xc5                                                                     \
+}
+/* END FILE */
+
+#else /* !MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
 /* This is taken from tests/data_files/test-ca2.crt */
 /* BEGIN FILE string macro TEST_CA_CRT_EC_PEM tests/data_files/test-ca2.crt */
 #define TEST_CA_CRT_EC_PEM                                                 \
@@ -146,6 +241,10 @@
 }
 /* END FILE */
 
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
+#define TEST_CA_PWD_EC_PEM "PolarSSLTest"
+
 /* This is taken from tests/data_files/test-ca-sha256.crt. */
 /* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA256_PEM tests/data_files/test-ca-sha256.crt */
 #define TEST_CA_CRT_RSA_SHA256_PEM                                         \
@@ -505,6 +604,100 @@
  * - multiple EC curve types
  */
 
+/* Use CRTs with Secp256r1-only if Secp384r1 is disabled.
+ * Otherwise, fall back to previous test CRTs using both
+ * Secp256r1 and Secp384r1. */
+#if !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+
+/* This is taken from tests/data_files/server11.crt.pem. */
+/* BEGIN FILE string macro TEST_SRV_CRT_EC_PEM tests/data_files/server11.crt.pem */
+#define TEST_SRV_CRT_EC_PEM                                                \
+    "-----BEGIN CERTIFICATE-----\r\n"                                      \
+    "MIIBrzCCAVKgAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg\r\n" \
+    "Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w\r\n" \
+    "MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMDMxEjAQBgNVBAMMCWxvY2FsaG9z\r\n" \
+    "dDEQMA4GA1UECgwHTWJlZFRMUzELMAkGA1UEBhMCVUswWTATBgcqhkjOPQIBBggq\r\n" \
+    "hkjOPQMBBwNCAATH4k2I+9HG/2AM4cN0pPkfO62ddKWwtDsdFezZoKxwXYm0ClZe\r\n" \
+    "zZYmfpl8x5Q7+V2oGg3TXoC8TOmXjAtabfDNo00wSzAJBgNVHRMEAjAAMB0GA1Ud\r\n" \
+    "DgQWBBQjXj0e2wlEVpSCbySpu2oDJgn7sjAfBgNVHSMEGDAWgBRKXqRhM0sWSAwx\r\n" \
+    "eCI11vvOUOcgEjAMBggqhkjOPQQDAgUAA0kAMEYCIQCN7/F5DbM4Ug5NcKHeKFbb\r\n" \
+    "3EHpsBjg0//gXa9mJ7Q4jAIhAIzio6vwCYnzrslzsTbPpmtU+6Op6SlzdGO/iR77\r\n" \
+    "bcfp\r\n"                                                             \
+    "-----END CERTIFICATE-----\r\n"
+/* END FILE */
+
+/* This is generated from tests/data_files/server11.crt.der using `xxd -i`. */
+/* BEGIN FILE binary macro TEST_SRV_CRT_EC_DER tests/data_files/server11.crt.der */
+#define TEST_SRV_CRT_EC_DER {                                                \
+    0x30, 0x82, 0x01, 0xaf, 0x30, 0x82, 0x01, 0x52, 0xa0, 0x03, 0x02, 0x01,  \
+    0x02, 0x02, 0x01, 0x01, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,  \
+    0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x1a, 0x30, 0x18,  \
+    0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20,  \
+    0x43, 0x41, 0x20, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31,  \
+    0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d,  \
+    0x62, 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,  \
+    0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x1e, 0x17, 0x0d, 0x30,  \
+    0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,  \
+    0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39,  \
+    0x35, 0x39, 0x5a, 0x30, 0x33, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,  \
+    0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,  \
+    0x74, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07,  \
+    0x4d, 0x62, 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06,  \
+    0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x59, 0x30, 0x13,  \
+    0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,  \
+    0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xc7,  \
+    0xe2, 0x4d, 0x88, 0xfb, 0xd1, 0xc6, 0xff, 0x60, 0x0c, 0xe1, 0xc3, 0x74,  \
+    0xa4, 0xf9, 0x1f, 0x3b, 0xad, 0x9d, 0x74, 0xa5, 0xb0, 0xb4, 0x3b, 0x1d,  \
+    0x15, 0xec, 0xd9, 0xa0, 0xac, 0x70, 0x5d, 0x89, 0xb4, 0x0a, 0x56, 0x5e,  \
+    0xcd, 0x96, 0x26, 0x7e, 0x99, 0x7c, 0xc7, 0x94, 0x3b, 0xf9, 0x5d, 0xa8,  \
+    0x1a, 0x0d, 0xd3, 0x5e, 0x80, 0xbc, 0x4c, 0xe9, 0x97, 0x8c, 0x0b, 0x5a,  \
+    0x6d, 0xf0, 0xcd, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55,  \
+    0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,  \
+    0x0e, 0x04, 0x16, 0x04, 0x14, 0x23, 0x5e, 0x3d, 0x1e, 0xdb, 0x09, 0x44,  \
+    0x56, 0x94, 0x82, 0x6f, 0x24, 0xa9, 0xbb, 0x6a, 0x03, 0x26, 0x09, 0xfb,  \
+    0xb2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,  \
+    0x80, 0x14, 0x4a, 0x5e, 0xa4, 0x61, 0x33, 0x4b, 0x16, 0x48, 0x0c, 0x31,  \
+    0x78, 0x22, 0x35, 0xd6, 0xfb, 0xce, 0x50, 0xe7, 0x20, 0x12, 0x30, 0x0c,  \
+    0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00,  \
+    0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x8d, 0xef, 0xf1, 0x79,  \
+    0x0d, 0xb3, 0x38, 0x52, 0x0e, 0x4d, 0x70, 0xa1, 0xde, 0x28, 0x56, 0xdb,  \
+    0xdc, 0x41, 0xe9, 0xb0, 0x18, 0xe0, 0xd3, 0xff, 0xe0, 0x5d, 0xaf, 0x66,  \
+    0x27, 0xb4, 0x38, 0x8c, 0x02, 0x21, 0x00, 0x8c, 0xe2, 0xa3, 0xab, 0xf0,  \
+    0x09, 0x89, 0xf3, 0xae, 0xc9, 0x73, 0xb1, 0x36, 0xcf, 0xa6, 0x6b, 0x54,  \
+    0xfb, 0xa3, 0xa9, 0xe9, 0x29, 0x73, 0x74, 0x63, 0xbf, 0x89, 0x1e, 0xfb,  \
+    0x6d, 0xc7, 0xe9                                                         \
+}
+/* END FILE */
+
+/* This is taken from tests/data_files/server11.key.pem. */
+/* BEGIN FILE string macro TEST_SRV_KEY_EC_PEM tests/data_files/server11.key.pem */
+#define TEST_SRV_KEY_EC_PEM                                                \
+    "-----BEGIN EC PRIVATE KEY-----\r\n"                                   \
+    "MHcCAQEEIGEWs7/9cQHgEI5v2qeQRGLoFhjrNK4lul6tmcqDACKuoAoGCCqGSM49\r\n" \
+    "AwEHoUQDQgAEx+JNiPvRxv9gDOHDdKT5HzutnXSlsLQ7HRXs2aCscF2JtApWXs2W\r\n" \
+    "Jn6ZfMeUO/ldqBoN016AvEzpl4wLWm3wzQ==\r\n"                             \
+    "-----END EC PRIVATE KEY-----\r\n"
+/* END FILE */
+
+/* This is generated from tests/data_files/server11.key.der using `xxd -i`. */
+/* BEGIN FILE binary macro TEST_SRV_KEY_EC_DER tests/data_files/server11.key.der */
+#define TEST_SRV_KEY_EC_DER {                                                \
+    0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x61, 0x16, 0xb3, 0xbf, 0xfd,  \
+    0x71, 0x01, 0xe0, 0x10, 0x8e, 0x6f, 0xda, 0xa7, 0x90, 0x44, 0x62, 0xe8,  \
+    0x16, 0x18, 0xeb, 0x34, 0xae, 0x25, 0xba, 0x5e, 0xad, 0x99, 0xca, 0x83,  \
+    0x00, 0x22, 0xae, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,  \
+    0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xc7, 0xe2, 0x4d,  \
+    0x88, 0xfb, 0xd1, 0xc6, 0xff, 0x60, 0x0c, 0xe1, 0xc3, 0x74, 0xa4, 0xf9,  \
+    0x1f, 0x3b, 0xad, 0x9d, 0x74, 0xa5, 0xb0, 0xb4, 0x3b, 0x1d, 0x15, 0xec,  \
+    0xd9, 0xa0, 0xac, 0x70, 0x5d, 0x89, 0xb4, 0x0a, 0x56, 0x5e, 0xcd, 0x96,  \
+    0x26, 0x7e, 0x99, 0x7c, 0xc7, 0x94, 0x3b, 0xf9, 0x5d, 0xa8, 0x1a, 0x0d,  \
+    0xd3, 0x5e, 0x80, 0xbc, 0x4c, 0xe9, 0x97, 0x8c, 0x0b, 0x5a, 0x6d, 0xf0,  \
+    0xcd                                                                     \
+}
+/* END FILE */
+
+#else /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
 /* This is taken from tests/data_files/server5.crt. */
 /* BEGIN FILE string macro TEST_SRV_CRT_EC_PEM tests/data_files/server5.crt */
 #define TEST_SRV_CRT_EC_PEM                                                \
@@ -603,6 +796,8 @@
 }
 /* END FILE */
 
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
 /* This is taken from tests/data_files/server2-sha256.crt. */
 /* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA256_PEM tests/data_files/server2-sha256.crt */
 #define TEST_SRV_CRT_RSA_SHA256_PEM                                        \
@@ -954,6 +1149,101 @@
  * - multiple EC curve types
  */
 
+/* Use CRTs with Secp256r1-only if Secp384r1 is disabled.
+ * Otherwise, fall back to previous test CRTs using both
+ * Secp256r1 and Secp384r1. */
+#if !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+
+/* This is taken from tests/data_files/cli3.crt. */
+/* BEGIN FILE string macro TEST_CLI_CRT_EC_PEM tests/data_files/cli3.crt.pem */
+#define TEST_CLI_CRT_EC_PEM                                                \
+    "-----BEGIN CERTIFICATE-----\r\n"                                      \
+    "MIIBuTCCAVygAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg\r\n" \
+    "Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w\r\n" \
+    "MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMD0xHDAaBgNVBAMME1Rlc3QgQ1JU\r\n" \
+    "MiBTZWNwMjU2cjExEDAOBgNVBAoMB01iZWRUTFMxCzAJBgNVBAYTAlVLMFkwEwYH\r\n" \
+    "KoZIzj0CAQYIKoZIzj0DAQcDQgAEEm+TJ4LBB85IBjWNcNIodr2L06CZqLbVClmH\r\n" \
+    "uxPqiZafsAZDl0lqgL6cCigF/ML2EqFyKW+Oext3uAmNkemj6aNNMEswCQYDVR0T\r\n" \
+    "BAIwADAdBgNVHQ4EFgQUF9Yq9UkoSClnXwrdghuhrokH/hIwHwYDVR0jBBgwFoAU\r\n" \
+    "Sl6kYTNLFkgMMXgiNdb7zlDnIBIwDAYIKoZIzj0EAwIFAANJADBGAiEAg3UsTyLd\r\n" \
+    "vCPRG13gbf1R8gb85g4K1VbZ+CKl58HW2VgCIQDXk/8WFrt7vA+m3L1xJxj8iln9\r\n" \
+    "wMR16i9Fqykw7cqsRw==\r\n"                                             \
+    "-----END CERTIFICATE-----\r\n"
+/* END FILE */
+
+/* This is generated from tests/data_files/cli3.crt.der using `xxd -i`. */
+/* BEGIN FILE binary macro TEST_CLI_CRT_EC_DER tests/data_files/cli3.crt.der */
+#define TEST_CLI_CRT_EC_DER {                                                \
+    0x30, 0x82, 0x01, 0xb9, 0x30, 0x82, 0x01, 0x5c, 0xa0, 0x03, 0x02, 0x01,  \
+    0x02, 0x02, 0x01, 0x01, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,  \
+    0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x1a, 0x30, 0x18,  \
+    0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20,  \
+    0x43, 0x41, 0x20, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31,  \
+    0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d,  \
+    0x62, 0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,  \
+    0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x1e, 0x17, 0x0d, 0x30,  \
+    0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,  \
+    0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39,  \
+    0x35, 0x39, 0x5a, 0x30, 0x3d, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55,  \
+    0x04, 0x03, 0x0c, 0x13, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x52, 0x54,  \
+    0x32, 0x20, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x72, 0x31, 0x31,  \
+    0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x62,  \
+    0x65, 0x64, 0x54, 0x4c, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,  \
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x4b, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,  \
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48,  \
+    0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x12, 0x6f, 0x93,  \
+    0x27, 0x82, 0xc1, 0x07, 0xce, 0x48, 0x06, 0x35, 0x8d, 0x70, 0xd2, 0x28,  \
+    0x76, 0xbd, 0x8b, 0xd3, 0xa0, 0x99, 0xa8, 0xb6, 0xd5, 0x0a, 0x59, 0x87,  \
+    0xbb, 0x13, 0xea, 0x89, 0x96, 0x9f, 0xb0, 0x06, 0x43, 0x97, 0x49, 0x6a,  \
+    0x80, 0xbe, 0x9c, 0x0a, 0x28, 0x05, 0xfc, 0xc2, 0xf6, 0x12, 0xa1, 0x72,  \
+    0x29, 0x6f, 0x8e, 0x7b, 0x1b, 0x77, 0xb8, 0x09, 0x8d, 0x91, 0xe9, 0xa3,  \
+    0xe9, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13,  \
+    0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,  \
+    0x16, 0x04, 0x14, 0x17, 0xd6, 0x2a, 0xf5, 0x49, 0x28, 0x48, 0x29, 0x67,  \
+    0x5f, 0x0a, 0xdd, 0x82, 0x1b, 0xa1, 0xae, 0x89, 0x07, 0xfe, 0x12, 0x30,  \
+    0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,  \
+    0x4a, 0x5e, 0xa4, 0x61, 0x33, 0x4b, 0x16, 0x48, 0x0c, 0x31, 0x78, 0x22,  \
+    0x35, 0xd6, 0xfb, 0xce, 0x50, 0xe7, 0x20, 0x12, 0x30, 0x0c, 0x06, 0x08,  \
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x49,  \
+    0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x83, 0x75, 0x2c, 0x4f, 0x22, 0xdd,  \
+    0xbc, 0x23, 0xd1, 0x1b, 0x5d, 0xe0, 0x6d, 0xfd, 0x51, 0xf2, 0x06, 0xfc,  \
+    0xe6, 0x0e, 0x0a, 0xd5, 0x56, 0xd9, 0xf8, 0x22, 0xa5, 0xe7, 0xc1, 0xd6,  \
+    0xd9, 0x58, 0x02, 0x21, 0x00, 0xd7, 0x93, 0xff, 0x16, 0x16, 0xbb, 0x7b,  \
+    0xbc, 0x0f, 0xa6, 0xdc, 0xbd, 0x71, 0x27, 0x18, 0xfc, 0x8a, 0x59, 0xfd,  \
+    0xc0, 0xc4, 0x75, 0xea, 0x2f, 0x45, 0xab, 0x29, 0x30, 0xed, 0xca, 0xac,  \
+    0x47                                                                     \
+}
+/* END FILE */
+
+/* This is taken from tests/data_files/cli3.key.pem. */
+/* BEGIN FILE string macro TEST_CLI_KEY_EC_PEM tests/data_files/cli3.key.pem */
+#define TEST_CLI_KEY_EC_PEM                                                \
+    "-----BEGIN EC PRIVATE KEY-----\r\n"                                   \
+    "MHcCAQEEIGFE8JJMBKeo1BnPGgzGae1stIrWdEaUvjo9xO8OTC5QoAoGCCqGSM49\r\n" \
+    "AwEHoUQDQgAEEm+TJ4LBB85IBjWNcNIodr2L06CZqLbVClmHuxPqiZafsAZDl0lq\r\n" \
+    "gL6cCigF/ML2EqFyKW+Oext3uAmNkemj6Q==\r\n"                             \
+    "-----END EC PRIVATE KEY-----\r\n"
+/* END FILE */
+
+/* This is generated from tests/data_files/cli3.key.der using `xxd -i`. */
+/* BEGIN FILE binary macro TEST_CLI_KEY_EC_DER tests/data_files/cli3.key.der */
+#define TEST_CLI_KEY_EC_DER {                                                \
+    0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x61, 0x44, 0xf0, 0x92, 0x4c,  \
+    0x04, 0xa7, 0xa8, 0xd4, 0x19, 0xcf, 0x1a, 0x0c, 0xc6, 0x69, 0xed, 0x6c,  \
+    0xb4, 0x8a, 0xd6, 0x74, 0x46, 0x94, 0xbe, 0x3a, 0x3d, 0xc4, 0xef, 0x0e,  \
+    0x4c, 0x2e, 0x50, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,  \
+    0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x12, 0x6f, 0x93,  \
+    0x27, 0x82, 0xc1, 0x07, 0xce, 0x48, 0x06, 0x35, 0x8d, 0x70, 0xd2, 0x28,  \
+    0x76, 0xbd, 0x8b, 0xd3, 0xa0, 0x99, 0xa8, 0xb6, 0xd5, 0x0a, 0x59, 0x87,  \
+    0xbb, 0x13, 0xea, 0x89, 0x96, 0x9f, 0xb0, 0x06, 0x43, 0x97, 0x49, 0x6a,  \
+    0x80, 0xbe, 0x9c, 0x0a, 0x28, 0x05, 0xfc, 0xc2, 0xf6, 0x12, 0xa1, 0x72,  \
+    0x29, 0x6f, 0x8e, 0x7b, 0x1b, 0x77, 0xb8, 0x09, 0x8d, 0x91, 0xe9, 0xa3,  \
+    0xe9                                                                     \
+}
+/* END FILE */
+
+#else /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
 /* This is taken from tests/data_files/cli2.crt. */
 /* BEGIN FILE string macro TEST_CLI_CRT_EC_PEM tests/data_files/cli2.crt */
 #define TEST_CLI_CRT_EC_PEM                                                \
@@ -1046,6 +1336,8 @@
 }
 /* END FILE */
 
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
 /* This is taken from tests/data_files/cli-rsa-sha256.crt. */
 /* BEGIN FILE string macro TEST_CLI_CRT_RSA_PEM tests/data_files/cli-rsa-sha256.crt */
 #define TEST_CLI_CRT_RSA_PEM                                               \
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a90303d..4e99a80 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1823,7 +1823,6 @@
                                       MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
-    mbedtls_ssl_optimize_checksum( ssl, server_suite_info );
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
     MBEDTLS_SSL_DEBUG_BUF( 3,   "server hello, session id", buf + 35, n );
@@ -3890,7 +3889,10 @@
 sign:
 #endif
 
-    ssl->handshake->calc_verify( ssl, hash, &hashlen );
+    mbedtls_ssl_calc_verify(
+            mbedtls_ssl_get_minor_ver( ssl ),
+            mbedtls_ssl_suite_get_mac( ciphersuite_info ),
+            ssl, hash, &hashlen );
 
 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index c25482d..b058e7c 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1138,7 +1138,7 @@
         return( ret );
     }
 
-    ssl->handshake->update_checksum( ssl, buf + 2, n );
+    mbedtls_ssl_update_checksum( ssl, buf + 2, n );
 
     buf = ssl->in_msg;
     n = ssl->in_left - 5;
@@ -1523,7 +1523,7 @@
 
     MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len );
 
-    ssl->handshake->update_checksum( ssl, buf, msg_len );
+    mbedtls_ssl_update_checksum( ssl, buf, msg_len );
 
     /*
      * Handshake layer:
@@ -4524,7 +4524,14 @@
          */
         md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] );
 
-        if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) )
+        if(
+#if defined(MBEDTLS_SHA512_C)
+            md_alg != MBEDTLS_MD_SHA384 &&
+#endif
+#if defined(MBEDTLS_SHA256_C)
+            md_alg != MBEDTLS_MD_SHA256 &&
+#endif
+            1 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
                                 " for verify message" ) );
@@ -4532,11 +4539,6 @@
             goto exit;
         }
 
-#if !defined(MBEDTLS_MD_SHA1)
-        if( MBEDTLS_MD_SHA1 == md_alg )
-            hash_start += 16;
-#endif
-
         /* Info from md_alg will be used instead */
         hashlen = 0;
 
@@ -4593,7 +4595,9 @@
     /* Calculate hash and verify signature */
     {
         size_t dummy_hlen;
-        ssl->handshake->calc_verify( ssl, hash, &dummy_hlen );
+        mbedtls_ssl_calc_verify(
+            mbedtls_ssl_get_minor_ver( ssl ),
+            md_alg, ssl, hash, &dummy_hlen );
     }
 
     if( ( ret = mbedtls_pk_verify( peer_pk,
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 96276c2..200268d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -589,7 +589,7 @@
  * Key material generation
  */
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
-static int ssl3_prf( const unsigned char *secret, size_t slen,
+MBEDTLS_NO_INLINE static int ssl3_prf( const unsigned char *secret, size_t slen,
                      const char *label,
                      const unsigned char *random, size_t rlen,
                      unsigned char *dstbuf, size_t dlen )
@@ -650,7 +650,7 @@
 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-static int tls1_prf( const unsigned char *secret, size_t slen,
+MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen,
                      const char *label,
                      const unsigned char *random, size_t rlen,
                      unsigned char *dstbuf, size_t dlen )
@@ -748,7 +748,12 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-static int tls_prf_generic( mbedtls_md_type_t md_type,
+#if !( defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA512_C) )
+MBEDTLS_ALWAYS_INLINE static inline
+#else
+static
+#endif
+int tls_prf_generic( mbedtls_md_type_t md_type,
                             const unsigned char *secret, size_t slen,
                             const char *label,
                             const unsigned char *random, size_t rlen,
@@ -812,7 +817,8 @@
 }
 
 #if defined(MBEDTLS_SHA256_C)
-static int tls_prf_sha256( const unsigned char *secret, size_t slen,
+MBEDTLS_NO_INLINE static int tls_prf_sha256(
+                           const unsigned char *secret, size_t slen,
                            const char *label,
                            const unsigned char *random, size_t rlen,
                            unsigned char *dstbuf, size_t dlen )
@@ -823,7 +829,8 @@
 #endif /* MBEDTLS_SHA256_C */
 
 #if defined(MBEDTLS_SHA512_C)
-static int tls_prf_sha384( const unsigned char *secret, size_t slen,
+MBEDTLS_NO_INLINE static int tls_prf_sha384(
+                           const unsigned char *secret, size_t slen,
                            const char *label,
                            const unsigned char *random, size_t rlen,
                            unsigned char *dstbuf, size_t dlen )
@@ -834,41 +841,348 @@
 #endif /* MBEDTLS_SHA512_C */
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
-static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t );
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
-    defined(MBEDTLS_SSL_PROTO_TLS1_1)
-static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t );
+/*
+ * Call the appropriate PRF function
+ */
+MBEDTLS_ALWAYS_INLINE static inline int ssl_prf( int minor_ver,
+                    mbedtls_md_type_t hash,
+                    const unsigned char *secret, size_t slen,
+                    const char *label,
+                    const unsigned char *random, size_t rlen,
+                    unsigned char *dstbuf, size_t dlen )
+{
+#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C)
+    (void) hash;
 #endif
 
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
-static void ssl_calc_verify_ssl( const mbedtls_ssl_context *, unsigned char *, size_t * );
-static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int );
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        return( ssl3_prf( secret, slen, label, random, rlen, dstbuf, dlen ) );
+    else
 #endif
-
 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-static void ssl_calc_verify_tls( const mbedtls_ssl_context *, unsigned char *, size_t * );
-static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int );
+    if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+        return( tls1_prf( secret, slen, label, random, rlen, dstbuf, dlen ) );
+    else
 #endif
-
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA256_C)
-static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char *, size_t * );
-static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
-#endif
-
 #if defined(MBEDTLS_SHA512_C)
-static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char *, size_t * );
-static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        hash == MBEDTLS_MD_SHA384 )
+    {
+        return( tls_prf_sha384( secret, slen, label, random, rlen,
+                                dstbuf, dlen ) );
+    }
+    else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        return( tls_prf_sha256( secret, slen, label, random, rlen,
+                                dstbuf, dlen ) );
+    }
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
-/* Type for the TLS PRF */
-typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
-                          const unsigned char *, size_t,
-                          unsigned char *, size_t);
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+MBEDTLS_NO_INLINE static void ssl_calc_finished_ssl(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    const char *sender;
+    mbedtls_md5_context  md5;
+    mbedtls_sha1_context sha1;
+
+    unsigned char padbuf[48];
+    unsigned char md5sum[16];
+    unsigned char sha1sum[20];
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished ssl" ) );
+
+    mbedtls_md5_init( &md5 );
+    mbedtls_sha1_init( &sha1 );
+
+    mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
+    mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
+
+    /*
+     * SSLv3:
+     *   hash =
+     *      MD5( master + pad2 +
+     *          MD5( handshake + sender + master + pad1 ) )
+     *   + SHA1( master + pad2 +
+     *         SHA1( handshake + sender + master + pad1 ) )
+     */
+
+#if !defined(MBEDTLS_MD5_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *)
+                    md5.state, sizeof(  md5.state ) );
+#endif
+
+#if !defined(MBEDTLS_SHA1_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
+                   sha1.state, sizeof( sha1.state ) );
+#endif
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT"
+                                       : "SRVR";
+
+    memset( padbuf, 0x36, 48 );
+
+    mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 );
+    mbedtls_md5_update_ret( &md5, session->master, 48 );
+    mbedtls_md5_update_ret( &md5, padbuf, 48 );
+    mbedtls_md5_finish_ret( &md5, md5sum );
+
+    mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 );
+    mbedtls_sha1_update_ret( &sha1, session->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, padbuf, 40 );
+    mbedtls_sha1_finish_ret( &sha1, sha1sum );
+
+    memset( padbuf, 0x5C, 48 );
+
+    mbedtls_md5_starts_ret( &md5 );
+    mbedtls_md5_update_ret( &md5, session->master, 48 );
+    mbedtls_md5_update_ret( &md5, padbuf, 48 );
+    mbedtls_md5_update_ret( &md5, md5sum, 16 );
+    mbedtls_md5_finish_ret( &md5, buf );
+
+    mbedtls_sha1_starts_ret( &sha1 );
+    mbedtls_sha1_update_ret( &sha1, session->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, padbuf , 40 );
+    mbedtls_sha1_update_ret( &sha1, sha1sum, 20 );
+    mbedtls_sha1_finish_ret( &sha1, buf + 16 );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
+
+    mbedtls_md5_free(  &md5  );
+    mbedtls_sha1_free( &sha1 );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
+    mbedtls_platform_zeroize(  md5sum, sizeof(  md5sum ) );
+    mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+MBEDTLS_NO_INLINE static void ssl_calc_finished_tls(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    int len = 12;
+    const char *sender;
+    mbedtls_md5_context  md5;
+    mbedtls_sha1_context sha1;
+    unsigned char padbuf[36];
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls" ) );
+
+    mbedtls_md5_init( &md5 );
+    mbedtls_sha1_init( &sha1 );
+
+    mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
+    mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
+
+    /*
+     * TLSv1:
+     *   hash = PRF( master, finished_label,
+     *               MD5( handshake ) + SHA1( handshake ) )[0..11]
+     */
+
+#if !defined(MBEDTLS_MD5_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *)
+                    md5.state, sizeof(  md5.state ) );
+#endif
+
+#if !defined(MBEDTLS_SHA1_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
+                   sha1.state, sizeof( sha1.state ) );
+#endif
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+             ? "client finished"
+             : "server finished";
+
+    mbedtls_md5_finish_ret(  &md5, padbuf );
+    mbedtls_sha1_finish_ret( &sha1, padbuf + 16 );
+
+    ssl_prf( mbedtls_ssl_get_minor_ver( ssl ),
+             mbedtls_ssl_suite_get_mac(
+                 mbedtls_ssl_ciphersuite_from_id(
+                     mbedtls_ssl_session_get_ciphersuite( session ) ) ),
+             session->master, 48, sender,
+             padbuf, 36, buf, len );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
+
+    mbedtls_md5_free(  &md5  );
+    mbedtls_sha1_free( &sha1 );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+MBEDTLS_NO_INLINE static void ssl_calc_finished_tls_sha256(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    int len = 12;
+    const char *sender;
+    mbedtls_sha256_context sha256;
+    unsigned char padbuf[32];
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    mbedtls_sha256_init( &sha256 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha256" ) );
+
+    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
+
+    /*
+     * TLSv1.2:
+     *   hash = PRF( master, finished_label,
+     *               Hash( handshake ) )[0.11]
+     */
+
+#if !defined(MBEDTLS_SHA256_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
+                   sha256.state, sizeof( sha256.state ) );
+#endif
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+             ? "client finished"
+             : "server finished";
+
+    mbedtls_sha256_finish_ret( &sha256, padbuf );
+
+    ssl_prf( mbedtls_ssl_get_minor_ver( ssl ),
+             mbedtls_ssl_suite_get_mac(
+                 mbedtls_ssl_ciphersuite_from_id(
+                     mbedtls_ssl_session_get_ciphersuite( session ) ) ),
+             session->master, 48, sender,
+             padbuf, 32, buf, len );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
+
+    mbedtls_sha256_free( &sha256 );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+MBEDTLS_NO_INLINE static void ssl_calc_finished_tls_sha384(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    int len = 12;
+    const char *sender;
+    mbedtls_sha512_context sha512;
+    unsigned char padbuf[48];
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    mbedtls_sha512_init( &sha512 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha384" ) );
+
+    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
+
+    /*
+     * TLSv1.2:
+     *   hash = PRF( master, finished_label,
+     *               Hash( handshake ) )[0.11]
+     */
+
+#if !defined(MBEDTLS_SHA512_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
+                   sha512.state, sizeof( sha512.state ) );
+#endif
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+             ? "client finished"
+             : "server finished";
+
+    mbedtls_sha512_finish_ret( &sha512, padbuf );
+
+    ssl_prf( mbedtls_ssl_get_minor_ver( ssl ),
+             mbedtls_ssl_suite_get_mac(
+                 mbedtls_ssl_ciphersuite_from_id(
+                     mbedtls_ssl_session_get_ciphersuite( session ) ) ),
+             session->master, 48, sender,
+             padbuf, 48, buf, len );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
+
+    mbedtls_sha512_free( &sha512 );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof( padbuf ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+MBEDTLS_ALWAYS_INLINE static inline int ssl_calc_finished(
+                                     int minor_ver,
+                                     mbedtls_md_type_t hash,
+                                     mbedtls_ssl_context *ssl,
+                                     unsigned char *buf,
+                                     int from )
+{
+#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C)
+    (void) hash;
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        ssl_calc_finished_ssl( ssl, buf, from );
+    else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+    if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+        ssl_calc_finished_tls( ssl, buf, from );
+    else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA512_C)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        hash == MBEDTLS_MD_SHA384 )
+    {
+        ssl_calc_finished_tls_sha384( ssl, buf, from );
+    }
+    else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+        ssl_calc_finished_tls_sha256( ssl, buf, from );
+    else
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    return( 0 );
+}
 
 /*
  * Populate a transform structure with session keys and all the other
@@ -892,7 +1206,15 @@
  *        - 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,
+/* Force compilers to inline this function if it's used only
+ * from one place, because at least ARMC5 doesn't do that
+ * automatically. */
+#if !defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+MBEDTLS_ALWAYS_INLINE static inline
+#else
+static
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
+int ssl_populate_transform( mbedtls_ssl_transform *transform,
                                    int ciphersuite,
                                    const unsigned char master[48],
 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
@@ -906,7 +1228,6 @@
 #if defined(MBEDTLS_ZLIB_SUPPORT)
                                    int compression,
 #endif
-                                   ssl_tls_prf_t tls_prf,
                                    const unsigned char randbytes[64],
                                    int minor_ver,
                                    unsigned endpoint,
@@ -1002,7 +1323,10 @@
     /*
      * Compute key block using the PRF
      */
-    ret = tls_prf( master, 48, "key expansion", randbytes, 64, keyblk, 256 );
+    ret = ssl_prf( minor_ver,
+                   mbedtls_ssl_suite_get_mac( ciphersuite_info ),
+                   master, 48, "key expansion", randbytes, 64,
+                   keyblk, 256 );
     if( ret != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
@@ -1283,233 +1607,10 @@
     return( 0 );
 }
 
-/*
- * Set appropriate PRF function and other SSL / TLS 1.0/1.1 / TLS1.2 functions
- *
- * Inputs:
- * - SSL/TLS minor version
- * - hash associated with the ciphersuite (only used by TLS 1.2)
- *
- * Outputs:
- * - the tls_prf, calc_verify and calc_finished members of handshake structure
- */
-static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake,
-                                   int minor_ver,
-                                   mbedtls_md_type_t hash )
-{
-#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C)
-    (void) hash;
-#endif
-
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
-    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
-    {
-        handshake->tls_prf = ssl3_prf;
-        handshake->calc_verify = ssl_calc_verify_ssl;
-        handshake->calc_finished = ssl_calc_finished_ssl;
-    }
-    else
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-    if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
-    {
-        handshake->tls_prf = tls1_prf;
-        handshake->calc_verify = ssl_calc_verify_tls;
-        handshake->calc_finished = ssl_calc_finished_tls;
-    }
-    else
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA512_C)
-    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
-        hash == MBEDTLS_MD_SHA384 )
-    {
-        handshake->tls_prf = tls_prf_sha384;
-        handshake->calc_verify = ssl_calc_verify_tls_sha384;
-        handshake->calc_finished = ssl_calc_finished_tls_sha384;
-    }
-    else
-#endif
-#if defined(MBEDTLS_SHA256_C)
-    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
-    {
-        handshake->tls_prf = tls_prf_sha256;
-        handshake->calc_verify = ssl_calc_verify_tls_sha256;
-        handshake->calc_finished = ssl_calc_finished_tls_sha256;
-    }
-    else
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-    {
-        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
-    }
-
-    return( 0 );
-}
-
-/*
- * Compute master secret if needed
- *
- * Parameters:
- * [in/out] handshake
- *          [in] resume, premaster, extended_ms, calc_verify, tls_prf
- *          [out] premaster (cleared)
- * [out] master
- * [in] ssl: optionally used for debugging and calc_verify
- */
-static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
-                               unsigned char *master,
-                               const mbedtls_ssl_context *ssl )
-{
-    int ret;
-
-#if !defined(MBEDTLS_DEBUG_C) && !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    ssl = NULL; /* make sure we don't use it except for debug and EMS */
-    (void) ssl;
-#endif
-
-#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION)
-    if( handshake->resume != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
-        return( 0 );
-    }
-#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
-                                                  handshake->pmslen );
-
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    if( mbedtls_ssl_hs_get_extended_ms( handshake )
-          == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
-    {
-        unsigned char session_hash[48];
-        size_t hash_len;
-
-        handshake->calc_verify( ssl, session_hash, &hash_len );
-
-        MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret",
-                                  session_hash, hash_len );
-
-        ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
-                                  "extended master secret",
-                                  session_hash, hash_len,
-                                  master, 48 );
-    }
-    else
-#endif
-    {
-        ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
-                                  "master secret",
-                                  handshake->randbytes, 64,
-                                  master, 48 );
-    }
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
-        return( ret );
-    }
-
-    mbedtls_platform_zeroize( handshake->premaster,
-                              sizeof(handshake->premaster) );
-
-    return( 0 );
-}
-
-int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
-{
-    int ret;
-    mbedtls_ssl_ciphersuite_handle_t const ciphersuite_info =
-        mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
-
-    /* Set PRF, calc_verify and calc_finished function pointers */
-    ret = ssl_set_handshake_prfs( ssl->handshake,
-                            mbedtls_ssl_get_minor_ver( ssl ),
-                            mbedtls_ssl_suite_get_mac( ciphersuite_info ) );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_set_handshake_prfs", ret );
-        return( ret );
-    }
-
-    /* Compute master secret if needed */
-    ret = ssl_compute_master( ssl->handshake,
-                              ssl->session_negotiate->master,
-                              ssl );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compute_master", ret );
-        return( ret );
-    }
-
-    /* Swap the client and server random values:
-     * - MS derivation wanted client+server (RFC 5246 8.1)
-     * - key derivation wants server+client (RFC 5246 6.3) */
-    {
-        unsigned char tmp[64];
-        memcpy( tmp, ssl->handshake->randbytes, 64 );
-        memcpy( ssl->handshake->randbytes, tmp + 32, 32 );
-        memcpy( ssl->handshake->randbytes + 32, tmp, 32 );
-        mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
-    }
-
-    /* Populate transform structure */
-    ret = ssl_populate_transform( ssl->transform_negotiate,
-                  mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ),
-                  ssl->session_negotiate->master,
-#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-                  ssl->session_negotiate->encrypt_then_mac,
-#endif
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-                  ssl->session_negotiate->trunc_hmac,
-#endif
-#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
-#if defined(MBEDTLS_ZLIB_SUPPORT)
-                  ssl->session_negotiate->compression,
-#endif
-                  ssl->handshake->tls_prf,
-                  ssl->handshake->randbytes,
-                  mbedtls_ssl_get_minor_ver( ssl ),
-                  mbedtls_ssl_conf_get_endpoint( ssl->conf ),
-                  ssl );
-    if( ret != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_populate_transform", ret );
-        return( ret );
-    }
-
-    /* We no longer need Server/ClientHello.random values */
-    mbedtls_platform_zeroize( ssl->handshake->randbytes,
-                      sizeof( ssl->handshake->randbytes ) );
-
-    /* Allocate compression buffer */
-#if defined(MBEDTLS_ZLIB_SUPPORT)
-    if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE &&
-        ssl->compress_buf == NULL )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
-        ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
-        if( ssl->compress_buf == NULL )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
-                                        MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
-            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
-        }
-    }
-#endif
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
-
-    return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
-void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl,
-                          unsigned char hash[36],
-                          size_t *hlen )
+static inline void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl,
+                                        unsigned char hash[36],
+                                        size_t *hlen )
 {
     mbedtls_md5_context md5;
     mbedtls_sha1_context sha1;
@@ -1560,9 +1661,9 @@
 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl,
-                          unsigned char hash[36],
-                          size_t *hlen )
+static inline void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl,
+                                        unsigned char hash[36],
+                                        size_t *hlen )
 {
     mbedtls_md5_context md5;
     mbedtls_sha1_context sha1;
@@ -1592,9 +1693,9 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
-void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl,
-                                 unsigned char hash[32],
-                                 size_t *hlen )
+static inline void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl,
+                                               unsigned char hash[32],
+                                               size_t *hlen )
 {
     mbedtls_sha256_context sha256;
 
@@ -1617,9 +1718,9 @@
 #endif /* MBEDTLS_SHA256_C */
 
 #if defined(MBEDTLS_SHA512_C)
-void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl,
-                                 unsigned char hash[48],
-                                 size_t *hlen )
+static inline void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl,
+                                               unsigned char hash[48],
+                                               size_t *hlen )
 {
     mbedtls_sha512_context sha512;
 
@@ -1642,6 +1743,206 @@
 #endif /* MBEDTLS_SHA512_C */
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
+int mbedtls_ssl_calc_verify( int minor_ver,
+                             mbedtls_md_type_t hash,
+                             mbedtls_ssl_context const *ssl,
+                             unsigned char *dst,
+                             size_t *hlen )
+{
+#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || !defined(MBEDTLS_SHA512_C)
+    (void) hash;
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        ssl_calc_verify_ssl( ssl, dst, hlen );
+    else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+    if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+        ssl_calc_verify_tls( ssl, dst, hlen );
+    else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA512_C)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        hash == MBEDTLS_MD_SHA384 )
+    {
+        ssl_calc_verify_tls_sha384( ssl, dst, hlen );
+    }
+    else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        ssl_calc_verify_tls_sha256( ssl, dst, hlen );
+    }
+    else
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    {
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Compute master secret if needed
+ *
+ * Parameters:
+ * [in/out] handshake
+ *          [in] resume, premaster, extended_ms, calc_verify, tls_prf
+ *          [out] premaster (cleared)
+ * [out] master
+ * [in] ssl: optionally used for debugging and calc_verify
+ */
+static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
+                               unsigned char *master,
+                               const mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+/* #if !defined(MBEDTLS_DEBUG_C) && !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) */
+/*     ssl = NULL; /\* make sure we don't use it except for debug and EMS *\/ */
+/*     (void) ssl; */
+/* #endif */
+
+    mbedtls_ssl_ciphersuite_handle_t const ciphersuite =
+        mbedtls_ssl_handshake_get_ciphersuite( handshake );
+
+#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION)
+    if( handshake->resume != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
+        return( 0 );
+    }
+#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
+                                                  handshake->pmslen );
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    if( mbedtls_ssl_hs_get_extended_ms( handshake )
+          == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
+    {
+        unsigned char session_hash[48];
+        size_t hash_len;
+
+        mbedtls_ssl_calc_verify(
+            mbedtls_ssl_get_minor_ver( ssl ),
+            mbedtls_ssl_suite_get_mac( ciphersuite ),
+            ssl, session_hash, &hash_len );
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret",
+                                  session_hash, hash_len );
+
+        ret = ssl_prf( mbedtls_ssl_get_minor_ver( ssl ),
+                       mbedtls_ssl_suite_get_mac( ciphersuite ),
+                       handshake->premaster, handshake->pmslen,
+                       "extended master secret",
+                       session_hash, hash_len,
+                       master, 48 );
+    }
+    else
+#endif
+    {
+        ret = ssl_prf( mbedtls_ssl_get_minor_ver( ssl ),
+                       mbedtls_ssl_suite_get_mac( ciphersuite ),
+                       handshake->premaster, handshake->pmslen,
+                       "master secret",
+                       handshake->randbytes, 64,
+                       master, 48 );
+    }
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
+        return( ret );
+    }
+
+    mbedtls_platform_zeroize( handshake->premaster,
+                              sizeof(handshake->premaster) );
+
+    return( 0 );
+}
+
+int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
+
+    /* Compute master secret if needed */
+    ret = ssl_compute_master( ssl->handshake,
+                              ssl->session_negotiate->master,
+                              ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compute_master", ret );
+        return( ret );
+    }
+
+    /* Swap the client and server random values:
+     * - MS derivation wanted client+server (RFC 5246 8.1)
+     * - key derivation wants server+client (RFC 5246 6.3) */
+    {
+        unsigned char tmp[64];
+        memcpy( tmp, ssl->handshake->randbytes, 64 );
+        memcpy( ssl->handshake->randbytes, tmp + 32, 32 );
+        memcpy( ssl->handshake->randbytes + 32, tmp, 32 );
+        mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    }
+
+    /* Populate transform structure */
+    ret = ssl_populate_transform( ssl->transform_negotiate,
+                  mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ),
+                  ssl->session_negotiate->master,
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+                  ssl->session_negotiate->encrypt_then_mac,
+#endif
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+                  ssl->session_negotiate->trunc_hmac,
+#endif
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+                  ssl->session_negotiate->compression,
+#endif
+                  ssl->handshake->randbytes,
+                  mbedtls_ssl_get_minor_ver( ssl ),
+                  mbedtls_ssl_conf_get_endpoint( ssl->conf ),
+                  ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_populate_transform", ret );
+        return( ret );
+    }
+
+    /* We no longer need Server/ClientHello.random values */
+    mbedtls_platform_zeroize( ssl->handshake->randbytes,
+                      sizeof( ssl->handshake->randbytes ) );
+
+    /* Allocate compression buffer */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE &&
+        ssl->compress_buf == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
+        ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
+        if( ssl->compress_buf == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+                                        MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+        }
+    }
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
+
+    return( 0 );
+}
+
 int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl )
 {
     int ret;
@@ -4081,7 +4382,7 @@
 
         /* Update running hashes of handshake messages seen */
         if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
-            ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
+            mbedtls_ssl_update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
     }
 
     /* Either send now, or just save to be sent (and resent) later */
@@ -4538,9 +4839,7 @@
     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
 
     if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
-    {
-        ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
-    }
+        mbedtls_ssl_update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
 
     /* Handshake message is complete, increment counter */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -7295,40 +7594,11 @@
     return( 0 );
 }
 
-void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
-                            mbedtls_ssl_ciphersuite_handle_t ciphersuite_info )
-{
-    ((void) ciphersuite_info);
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
-    defined(MBEDTLS_SSL_PROTO_TLS1_1)
-    if( mbedtls_ssl_get_minor_ver( ssl ) < MBEDTLS_SSL_MINOR_VERSION_3 )
-        ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
-    else
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA512_C)
-    if( mbedtls_ssl_suite_get_mac( ciphersuite_info ) == MBEDTLS_MD_SHA384 )
-        ssl->handshake->update_checksum = ssl_update_checksum_sha384;
-    else
-#endif
-#if defined(MBEDTLS_SHA256_C)
-    if( mbedtls_ssl_suite_get_mac( ciphersuite_info ) != MBEDTLS_MD_SHA384 )
-        ssl->handshake->update_checksum = ssl_update_checksum_sha256;
-    else
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
-        return;
-    }
-}
-
 void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
 {
 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
-     mbedtls_md5_starts_ret( &ssl->handshake->fin_md5  );
+    mbedtls_md5_starts_ret( &ssl->handshake->fin_md5  );
     mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 );
 #endif
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -7341,296 +7611,6 @@
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 }
 
-static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
-                                       const unsigned char *buf, size_t len )
-{
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
-    defined(MBEDTLS_SSL_PROTO_TLS1_1)
-     mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
-    mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA256_C)
-    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
-#endif
-#if defined(MBEDTLS_SHA512_C)
-    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-}
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
-    defined(MBEDTLS_SSL_PROTO_TLS1_1)
-static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
-                                         const unsigned char *buf, size_t len )
-{
-     mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
-    mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
-}
-#endif
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA256_C)
-static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
-                                        const unsigned char *buf, size_t len )
-{
-    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
-}
-#endif
-
-#if defined(MBEDTLS_SHA512_C)
-static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
-                                        const unsigned char *buf, size_t len )
-{
-    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
-}
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
-static void ssl_calc_finished_ssl(
-                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
-{
-    const char *sender;
-    mbedtls_md5_context  md5;
-    mbedtls_sha1_context sha1;
-
-    unsigned char padbuf[48];
-    unsigned char md5sum[16];
-    unsigned char sha1sum[20];
-
-    mbedtls_ssl_session *session = ssl->session_negotiate;
-    if( !session )
-        session = ssl->session;
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished ssl" ) );
-
-    mbedtls_md5_init( &md5 );
-    mbedtls_sha1_init( &sha1 );
-
-    mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
-    mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
-
-    /*
-     * SSLv3:
-     *   hash =
-     *      MD5( master + pad2 +
-     *          MD5( handshake + sender + master + pad1 ) )
-     *   + SHA1( master + pad2 +
-     *         SHA1( handshake + sender + master + pad1 ) )
-     */
-
-#if !defined(MBEDTLS_MD5_ALT)
-    MBEDTLS_SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *)
-                    md5.state, sizeof(  md5.state ) );
-#endif
-
-#if !defined(MBEDTLS_SHA1_ALT)
-    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
-                   sha1.state, sizeof( sha1.state ) );
-#endif
-
-    sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT"
-                                       : "SRVR";
-
-    memset( padbuf, 0x36, 48 );
-
-    mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 );
-    mbedtls_md5_update_ret( &md5, session->master, 48 );
-    mbedtls_md5_update_ret( &md5, padbuf, 48 );
-    mbedtls_md5_finish_ret( &md5, md5sum );
-
-    mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 );
-    mbedtls_sha1_update_ret( &sha1, session->master, 48 );
-    mbedtls_sha1_update_ret( &sha1, padbuf, 40 );
-    mbedtls_sha1_finish_ret( &sha1, sha1sum );
-
-    memset( padbuf, 0x5C, 48 );
-
-    mbedtls_md5_starts_ret( &md5 );
-    mbedtls_md5_update_ret( &md5, session->master, 48 );
-    mbedtls_md5_update_ret( &md5, padbuf, 48 );
-    mbedtls_md5_update_ret( &md5, md5sum, 16 );
-    mbedtls_md5_finish_ret( &md5, buf );
-
-    mbedtls_sha1_starts_ret( &sha1 );
-    mbedtls_sha1_update_ret( &sha1, session->master, 48 );
-    mbedtls_sha1_update_ret( &sha1, padbuf , 40 );
-    mbedtls_sha1_update_ret( &sha1, sha1sum, 20 );
-    mbedtls_sha1_finish_ret( &sha1, buf + 16 );
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
-
-    mbedtls_md5_free(  &md5  );
-    mbedtls_sha1_free( &sha1 );
-
-    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
-    mbedtls_platform_zeroize(  md5sum, sizeof(  md5sum ) );
-    mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
-}
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-static void ssl_calc_finished_tls(
-                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
-{
-    int len = 12;
-    const char *sender;
-    mbedtls_md5_context  md5;
-    mbedtls_sha1_context sha1;
-    unsigned char padbuf[36];
-
-    mbedtls_ssl_session *session = ssl->session_negotiate;
-    if( !session )
-        session = ssl->session;
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls" ) );
-
-    mbedtls_md5_init( &md5 );
-    mbedtls_sha1_init( &sha1 );
-
-    mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
-    mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
-
-    /*
-     * TLSv1:
-     *   hash = PRF( master, finished_label,
-     *               MD5( handshake ) + SHA1( handshake ) )[0..11]
-     */
-
-#if !defined(MBEDTLS_MD5_ALT)
-    MBEDTLS_SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *)
-                    md5.state, sizeof(  md5.state ) );
-#endif
-
-#if !defined(MBEDTLS_SHA1_ALT)
-    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
-                   sha1.state, sizeof( sha1.state ) );
-#endif
-
-    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
-             ? "client finished"
-             : "server finished";
-
-    mbedtls_md5_finish_ret(  &md5, padbuf );
-    mbedtls_sha1_finish_ret( &sha1, padbuf + 16 );
-
-    ssl->handshake->tls_prf( session->master, 48, sender,
-                             padbuf, 36, buf, len );
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
-
-    mbedtls_md5_free(  &md5  );
-    mbedtls_sha1_free( &sha1 );
-
-    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
-}
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA256_C)
-static void ssl_calc_finished_tls_sha256(
-                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
-{
-    int len = 12;
-    const char *sender;
-    mbedtls_sha256_context sha256;
-    unsigned char padbuf[32];
-
-    mbedtls_ssl_session *session = ssl->session_negotiate;
-    if( !session )
-        session = ssl->session;
-
-    mbedtls_sha256_init( &sha256 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha256" ) );
-
-    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
-
-    /*
-     * TLSv1.2:
-     *   hash = PRF( master, finished_label,
-     *               Hash( handshake ) )[0.11]
-     */
-
-#if !defined(MBEDTLS_SHA256_ALT)
-    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
-                   sha256.state, sizeof( sha256.state ) );
-#endif
-
-    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
-             ? "client finished"
-             : "server finished";
-
-    mbedtls_sha256_finish_ret( &sha256, padbuf );
-
-    ssl->handshake->tls_prf( session->master, 48, sender,
-                             padbuf, 32, buf, len );
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
-
-    mbedtls_sha256_free( &sha256 );
-
-    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
-}
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA512_C)
-static void ssl_calc_finished_tls_sha384(
-                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
-{
-    int len = 12;
-    const char *sender;
-    mbedtls_sha512_context sha512;
-    unsigned char padbuf[48];
-
-    mbedtls_ssl_session *session = ssl->session_negotiate;
-    if( !session )
-        session = ssl->session;
-
-    mbedtls_sha512_init( &sha512 );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha384" ) );
-
-    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
-
-    /*
-     * TLSv1.2:
-     *   hash = PRF( master, finished_label,
-     *               Hash( handshake ) )[0.11]
-     */
-
-#if !defined(MBEDTLS_SHA512_ALT)
-    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
-                   sha512.state, sizeof( sha512.state ) );
-#endif
-
-    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
-             ? "client finished"
-             : "server finished";
-
-    mbedtls_sha512_finish_ret( &sha512, padbuf );
-
-    ssl->handshake->tls_prf( session->master, 48, sender,
-                             padbuf, 48, buf, len );
-
-    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
-
-    mbedtls_sha512_free( &sha512 );
-
-    mbedtls_platform_zeroize(  padbuf, sizeof( padbuf ) );
-
-    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
-}
-#endif /* MBEDTLS_SHA512_C */
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
 static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
 {
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
@@ -7726,8 +7706,13 @@
 
     ssl_update_out_pointers( ssl, ssl->transform_negotiate );
 
-    ssl->handshake->calc_finished( ssl, ssl->out_msg + 4,
-                                   mbedtls_ssl_conf_get_endpoint( ssl->conf ) );
+    ssl_calc_finished( mbedtls_ssl_get_minor_ver( ssl ),
+                       mbedtls_ssl_suite_get_mac(
+                           mbedtls_ssl_ciphersuite_from_id(
+                               mbedtls_ssl_session_get_ciphersuite(
+                                   ssl->session_negotiate ) ) ),
+                       ssl, ssl->out_msg + 4,
+                       mbedtls_ssl_conf_get_endpoint( ssl->conf ) );
 
     /*
      * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
@@ -7863,8 +7848,13 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
 
-    ssl->handshake->calc_finished( ssl, buf,
-                             mbedtls_ssl_conf_get_endpoint( ssl->conf ) ^ 1 );
+    ssl_calc_finished( mbedtls_ssl_get_minor_ver( ssl ),
+                       mbedtls_ssl_suite_get_mac(
+                           mbedtls_ssl_ciphersuite_from_id(
+                               mbedtls_ssl_session_get_ciphersuite(
+                                   ssl->session_negotiate ) ) ),
+                       ssl, buf,
+                       mbedtls_ssl_conf_get_endpoint( ssl->conf ) ^ 1 );
 
     if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
     {
@@ -7959,8 +7949,6 @@
 #endif
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
-    handshake->update_checksum = ssl_update_checksum_start;
-
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
     defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
     mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs );
@@ -11387,29 +11375,6 @@
 }
 
 /*
- * Helper to get TLS 1.2 PRF from ciphersuite
- * (Duplicates bits of logic from ssl_set_handshake_prfs().)
- */
-typedef int (*tls_prf_fn)( const unsigned char *secret, size_t slen,
-                           const char *label,
-                           const unsigned char *random, size_t rlen,
-                           unsigned char *dstbuf, size_t dlen );
-static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id )
-{
-    mbedtls_ssl_ciphersuite_handle_t const info =
-        mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
-    const mbedtls_md_type_t hash = mbedtls_ssl_suite_get_mac( info );
-
-#if defined(MBEDTLS_SHA512_C)
-    if( hash == MBEDTLS_MD_SHA384 )
-        return( tls_prf_sha384 );
-#else
-    (void) hash;
-#endif
-    return( tls_prf_sha256 );
-}
-
-/*
  * Deserialize context, see mbedtls_ssl_context_save() for format.
  *
  * This internal version is wrapped by a public function that cleans up in
@@ -11529,8 +11494,6 @@
 #if defined(MBEDTLS_ZLIB_SUPPORT)
                   ssl->session->compression,
 #endif
-                  ssl_tls12prf_from_cs(
-                      mbedtls_ssl_session_get_ciphersuite( ssl->session) ),
                   p, /* currently pointing to randbytes */
                   MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */
                   mbedtls_ssl_conf_get_endpoint( ssl->conf ),
@@ -12377,30 +12340,6 @@
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
-{
-    switch( md )
-    {
-#if defined(MBEDTLS_SHA512_C)
-        case MBEDTLS_SSL_HASH_SHA384:
-            ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
-            break;
-#endif
-#if defined(MBEDTLS_SHA256_C)
-        case MBEDTLS_SSL_HASH_SHA256:
-            ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256;
-            break;
-#endif
-
-        default:
-            return( MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH );
-    }
-
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
 int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 2aa4950..788793a 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -43,13 +43,16 @@
 #endif
 
 #if !defined(MBEDTLS_ENTROPY_C) || \
-    !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
-    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C)
+    !defined(MBEDTLS_SSL_TLS_C) || \
+    !defined(MBEDTLS_SSL_CLI_C) || \
+    !defined(MBEDTLS_NET_C)     || \
+    !( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) )
 int main( void )
 {
     mbedtls_printf("MBEDTLS_ENTROPY_C and/or "
            "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
-           "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined.\n");
+           "MBEDTLS_NET_C not defined, or "
+           "neither MBEDTLS_CTR_DRBG_C nor MBEDTLS_HMAC_DRBG_C defined.\n");
     return( 0 );
 }
 #else
@@ -59,6 +62,7 @@
 #include "mbedtls/ssl_ciphersuites.h"
 #include "mbedtls/entropy.h"
 #include "mbedtls/ctr_drbg.h"
+#include "mbedtls/hmac_drbg.h"
 #include "mbedtls/certs.h"
 #include "mbedtls/x509.h"
 #include "mbedtls/error.h"
@@ -701,8 +705,12 @@
     return( 0 );
 }
 
-#if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH)
-static int ssl_sig_hashes_for_test[] = {
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if ( defined(MBEDTLS_X509_CRT_PARSE_C) &&        \
+      !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) ) || \
+    !defined(MBEDTLS_CTR_DRBG_C)
+static int available_hashes[] = {
 #if defined(MBEDTLS_SHA512_C)
     MBEDTLS_MD_SHA512,
     MBEDTLS_MD_SHA384,
@@ -717,8 +725,8 @@
 #endif
     MBEDTLS_MD_NONE
 };
-#endif /* !MBEDTLS_SSL_CONF_SINGLE_HASH */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#endif /* ( MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_CONF_SINGLE_HASH ) ||
+          !MBEDTLS_CTR_DRBG_C */
 
 /*
  * Wait for an event from the underlying transport or the timer
@@ -892,14 +900,23 @@
 #if defined(MBEDTLS_SSL_CONF_RNG)
 int rng_wrap( void *ctx, unsigned char *dst, size_t len );
 
+#if defined(MBEDTLS_CTR_DRBG_C)
 mbedtls_ctr_drbg_context *rng_ctx_global = NULL;
+#else
+mbedtls_hmac_drbg_context *rng_ctx_global = NULL;
+#endif /* MBEDTLS_CTR_DRBG_C */
+
 int rng_wrap( void *ctx, unsigned char *dst, size_t len )
 {
     /* We expect the NULL parameter here. */
     if( ctx != NULL )
         return( -1 );
 
+#if defined(MBEDTLS_CTR_DRBG_C)
     return( mbedtls_ctr_drbg_random( rng_ctx_global, dst, len ) );
+#else
+    return( mbedtls_hmac_drbg_random( rng_ctx_global, dst, len ) );
+#endif
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
@@ -941,7 +958,11 @@
     mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
 #endif
     mbedtls_entropy_context entropy;
+#if defined(MBEDTLS_CTR_DRBG_C)
     mbedtls_ctr_drbg_context ctr_drbg;
+#else
+    mbedtls_hmac_drbg_context hmac_drbg;
+#endif
     mbedtls_ssl_context ssl;
     mbedtls_ssl_config conf;
     mbedtls_ssl_session saved_session;
@@ -970,7 +991,11 @@
     mbedtls_ssl_init( &ssl );
     mbedtls_ssl_config_init( &conf );
     memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) );
+#if defined(MBEDTLS_CTR_DRBG_C)
     mbedtls_ctr_drbg_init( &ctr_drbg );
+#else
+    mbedtls_hmac_drbg_init( &hmac_drbg );
+#endif /* MBEDTLS_CTR_DRBG_C */
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_init( &cacert );
     mbedtls_x509_crt_init( &clicert );
@@ -1664,6 +1689,7 @@
     fflush( stdout );
 
     mbedtls_entropy_init( &entropy );
+#if defined(MBEDTLS_CTR_DRBG_C)
     if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
                                        &entropy, (const unsigned char *) pers,
                                        strlen( pers ) ) ) != 0 )
@@ -1672,6 +1698,19 @@
                         -ret );
         goto exit;
     }
+#else /* MBEDTLS_CTR_DRBG_C */
+    if( ( ret = mbedtls_hmac_drbg_seed( &hmac_drbg,
+                                        mbedtls_md_info_from_type(
+                                            available_hashes[0] ),
+                                        mbedtls_entropy_func,
+                                        &entropy, (const unsigned char *) pers,
+                                        strlen( pers ) ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
+                        -ret );
+        goto exit;
+    }
+#endif /* MBEDTLS_CTR_DRBG */
 
     mbedtls_printf( " ok\n" );
 
@@ -1851,7 +1890,7 @@
         crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 );
         mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test );
 #if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH)
-        mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );
+        mbedtls_ssl_conf_sig_hashes( &conf, available_hashes );
 #endif
     }
 
@@ -1953,11 +1992,19 @@
         }
 #endif
 
+#if defined(MBEDTLS_CTR_DRBG_C)
 #if !defined(MBEDTLS_SSL_CONF_RNG)
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
 #else
     rng_ctx_global = &ctr_drbg;
 #endif
+#else /* MBEDTLS_CTR_DRBG_C */
+#if !defined(MBEDTLS_SSL_CONF_RNG)
+    mbedtls_ssl_conf_rng( &conf, mbedtls_hmac_drbg_random, &hmac_drbg );
+#else
+    rng_ctx_global = &hmac_drbg;
+#endif
+#endif /* MBEDTLS_CTR_DRBG_C */
 
 #if defined(MBEDTLS_DEBUG_C)
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
@@ -2871,7 +2918,11 @@
     mbedtls_ssl_session_free( &saved_session );
     mbedtls_ssl_free( &ssl );
     mbedtls_ssl_config_free( &conf );
+#if defined(MBEDTLS_CTR_DRBG_C)
     mbedtls_ctr_drbg_free( &ctr_drbg );
+#else
+    mbedtls_hmac_drbg_free( &hmac_drbg );
+#endif
     mbedtls_entropy_free( &entropy );
     if( session_data != NULL )
         mbedtls_platform_zeroize( session_data, session_data_len );
@@ -2895,4 +2946,4 @@
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
           MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
-          MBEDTLS_CTR_DRBG_C MBEDTLS_TIMING_C */
+          ( MBEDTLS_CTR_DRBG_C || MBEDTLS_HMAC_DRBG_C ) && MBEDTLS_TIMING_C */
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index e0e4337..890725e 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -42,13 +42,16 @@
 #endif
 
 #if !defined(MBEDTLS_ENTROPY_C) || \
-    !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \
-    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C)
+    !defined(MBEDTLS_SSL_TLS_C) || \
+    !defined(MBEDTLS_SSL_SRV_C) || \
+    !defined(MBEDTLS_NET_C)     || \
+    !( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) )
 int main( void )
 {
     mbedtls_printf("MBEDTLS_ENTROPY_C and/or "
            "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
-           "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined.\n");
+           "MBEDTLS_NET_C not defined, or "
+           "neither MBEDTLS_CTR_DRBG_C nor MBEDTLS_HMAC_DRBG_C defined.\n");
     return( 0 );
 }
 #else
@@ -58,6 +61,7 @@
 #include "mbedtls/ssl_ciphersuites.h"
 #include "mbedtls/entropy.h"
 #include "mbedtls/ctr_drbg.h"
+#include "mbedtls/hmac_drbg.h"
 #include "mbedtls/certs.h"
 #include "mbedtls/x509.h"
 #include "mbedtls/error.h"
@@ -1133,9 +1137,10 @@
 }
 #endif
 
-#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
-    !defined(MBEDTLS_SSL_CONF_SINGLE_HASH)
-static int ssl_sig_hashes_for_test[] = {
+#if ( defined(MBEDTLS_X509_CRT_PARSE_C) &&        \
+      !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) ) || \
+    !defined(MBEDTLS_CTR_DRBG_C)
+static int available_hashes[] = {
 #if defined(MBEDTLS_SHA512_C)
     MBEDTLS_MD_SHA512,
     MBEDTLS_MD_SHA384,
@@ -1150,7 +1155,8 @@
 #endif
     MBEDTLS_MD_NONE
 };
-#endif /* MBEDTLS_X509_CRT_PARSE_C && !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) */
+#endif /* ( MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_CONF_SINGLE_HASH ) ||
+          !MBEDTLS_CTR_DRBG_C */
 
 /** Return true if \p ret is a status code indicating that there is an
  * operation in progress on an SSL connection, and false if it indicates
@@ -1508,14 +1514,23 @@
 #if defined(MBEDTLS_SSL_CONF_RNG)
 int rng_wrap( void *ctx, unsigned char *dst, size_t len );
 
+#if defined(MBEDTLS_CTR_DRBG_C)
 mbedtls_ctr_drbg_context *rng_ctx_global = NULL;
+#else
+mbedtls_hmac_drbg_context *rng_ctx_global = NULL;
+#endif /* MBEDTLS_CTR_DRBG_C */
+
 int rng_wrap( void *ctx, unsigned char *dst, size_t len )
 {
     /* We expect the NULL parameter here. */
     if( ctx != NULL )
         return( -1 );
 
+#if defined(MBEDTLS_CTR_DRBG_C)
     return( mbedtls_ctr_drbg_random( rng_ctx_global, dst, len ) );
+#else
+    return( mbedtls_hmac_drbg_random( rng_ctx_global, dst, len ) );
+#endif
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
@@ -1545,7 +1560,11 @@
     mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
 #endif
     mbedtls_entropy_context entropy;
+#if defined(MBEDTLS_CTR_DRBG_C)
     mbedtls_ctr_drbg_context ctr_drbg;
+#else
+    mbedtls_hmac_drbg_context hmac_drbg;
+#endif
     mbedtls_ssl_context ssl;
     mbedtls_ssl_config conf;
 #if defined(MBEDTLS_TIMING_C)
@@ -1615,7 +1634,11 @@
     mbedtls_net_init( &listen_fd );
     mbedtls_ssl_init( &ssl );
     mbedtls_ssl_config_init( &conf );
+#if defined(MBEDTLS_CTR_DRBG_C)
     mbedtls_ctr_drbg_init( &ctr_drbg );
+#else
+    mbedtls_hmac_drbg_init( &hmac_drbg );
+#endif /* MBEDTLS_CTR_DRBG_C */
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_init( &cacert );
     mbedtls_x509_crt_init( &srvcert );
@@ -2418,6 +2441,7 @@
     fflush( stdout );
 
     mbedtls_entropy_init( &entropy );
+#if defined(MBEDTLS_CTR_DRBG_C)
     if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
                                        &entropy, (const unsigned char *) pers,
                                        strlen( pers ) ) ) != 0 )
@@ -2426,6 +2450,19 @@
                         -ret );
         goto exit;
     }
+#else /* MBEDTLS_CTR_DRBG_C */
+    if( ( ret = mbedtls_hmac_drbg_seed( &hmac_drbg,
+                                        mbedtls_md_info_from_type(
+                                            available_hashes[0] ),
+                                        mbedtls_entropy_func,
+                                        &entropy, (const unsigned char *) pers,
+                                        strlen( pers ) ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
+                        -ret );
+        goto exit;
+    }
+#endif /* MBEDTLS_CTR_DRBG */
 
     mbedtls_printf( " ok\n" );
 
@@ -2674,7 +2711,7 @@
         crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 );
         mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test );
 #if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH)
-        mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );
+        mbedtls_ssl_conf_sig_hashes( &conf, available_hashes );
 #endif
     }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
@@ -2765,11 +2802,19 @@
         }
 #endif
 
+#if defined(MBEDTLS_CTR_DRBG_C)
 #if !defined(MBEDTLS_SSL_CONF_RNG)
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
 #else
     rng_ctx_global = &ctr_drbg;
 #endif
+#else /* MBEDTLS_CTR_DRBG_C */
+#if !defined(MBEDTLS_SSL_CONF_RNG)
+    mbedtls_ssl_conf_rng( &conf, mbedtls_hmac_drbg_random, &hmac_drbg );
+#else
+    rng_ctx_global = &hmac_drbg;
+#endif
+#endif /* MBEDTLS_CTR_DRBG_C */
 
 #if defined(MBEDTLS_DEBUG_C)
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
@@ -2793,7 +2838,11 @@
     if( opt.tickets == MBEDTLS_SSL_SESSION_TICKETS_ENABLED )
     {
         if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx,
+#if defined(MBEDTLS_CTR_DRBG_C)
                         mbedtls_ctr_drbg_random, &ctr_drbg,
+#else
+                        mbedtls_hmac_drbg_random, &hmac_drbg,
+#endif
                         MBEDTLS_CIPHER_AES_256_GCM,
                         opt.ticket_timeout ) ) != 0 )
         {
@@ -2815,7 +2864,12 @@
         if( opt.cookies > 0 )
         {
             if( ( ret = mbedtls_ssl_cookie_setup( &cookie_ctx,
-                                          mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
+#if defined(MBEDTLS_CTR_DRBG_C)
+                                          mbedtls_ctr_drbg_random, &ctr_drbg
+#else
+                                          mbedtls_hmac_drbg_random, &hmac_drbg
+#endif /* MBEDTLS_CTR_DRBG_C */
+                                          ) ) != 0 )
             {
                 mbedtls_printf( " failed\n  ! mbedtls_ssl_cookie_setup returned %d\n\n", ret );
                 goto exit;
@@ -3852,7 +3906,11 @@
 
     mbedtls_ssl_free( &ssl );
     mbedtls_ssl_config_free( &conf );
+#if defined(MBEDTLS_CTR_DRBG_C)
     mbedtls_ctr_drbg_free( &ctr_drbg );
+#else
+    mbedtls_hmac_drbg_free( &hmac_drbg );
+#endif
     mbedtls_entropy_free( &entropy );
 
 #if defined(MBEDTLS_SSL_CACHE_C)
@@ -3895,4 +3953,4 @@
 }
 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
           MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
-          MBEDTLS_CTR_DRBG_C */
+          ( MBEDTLS_CTR_DRBG_C || MBEDTLS_HMAC_DRBG_C ) */
diff --git a/scripts/generate_certs.sh b/scripts/generate_certs.sh
new file mode 100755
index 0000000..4de4a53
--- /dev/null
+++ b/scripts/generate_certs.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+if [ -d include/mbedtls ]; then :; else
+    echo "$0: must be run from root" >&2
+    exit 1
+fi
+
+CERTS="library/certs.c"
+CERTS_TMP="${CERTS}.tmp"
+CERTS_NEW="${CERTS}.new"
+
+# Remove bodies of BEGIN FILE ... END FILE blocks
+SED_RM_FILE_BODIES=":o; /BEGIN FILE/!{p;n;bo}; /BEGIN FILE/{p; n; :i; /END FILE/{n; bo}; n; bi}"
+sed -n "${SED_RM_FILE_BODIES}" $CERTS > ${CERTS_TMP}
+while IFS= read -r line; do
+    echo "$line"
+    CMD=`echo "$line" | sed -n 's/^\/\* BEGIN FILE \([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\)*.*$/\1 \2 \3 \4/p'`
+    if [ -n "$CMD" ]; then
+        enc=$(echo "$CMD" | cut -f1 -d' ' )
+        type=$(echo "$CMD" | cut -f2 -d' ' )
+        name=$(echo "$CMD" | cut -f3 -d' ' )
+        file=$(echo "$CMD" | cut -f4 -d' ' )
+
+        if [ "$type" != "variable" ] && [ "$type" != "macro" ]; then
+            exit 1
+        fi
+
+        if [ "$enc" != "string" ] && [ "$enc" != "binary" ]; then
+            exit 1
+        fi
+
+        # Support 'binary' and 'string' encoding
+        # Support 'variable' and 'macro' types
+
+        if [ "$enc" = "binary" ]; then
+            DATA=`xxd -i "$file" | tail -n +2 | head -n -2 | sed 's/^[ ]*/    /'`
+        elif [ "$enc" = "string" ]; then
+            DATA=`cat "$file" | sed 's/^/    \"/;s/$/\\r\\n\"/'`
+        fi
+
+        if [ "$type" = "variable" ]; then
+            if [ "$enc" = "binary" ]; then
+                echo "const unsigned char ${name}[] = {"
+                xxd -i "$file" | sed 's/^[ ]*/    /' | tail -n +2 | head -n -2
+                echo "};"
+            elif [ "$enc" = "string" ]; then
+                echo "const char ${name}[] ="
+                cat "$file" | head -n -1 | sed 's/^/    \"/;s/$/\\r\\n\"/'
+                cat "$file" | tail -n 1  | sed 's/^/    \"/;s/$/\\r\\n\";/'
+            fi
+        elif [ "$type" = "macro" ]; then
+            if [ "$enc" = "binary" ]; then
+                printf '%-77s\\\n' "#define ${name} {"
+                xxd -i "$file" | sed 's/^[ ]*/    /' | tail -n +2 | head -n -2 |
+                    xargs -d'\n' printf '%-77s\\\n'
+                echo "}"
+            elif [ "$enc" = "string" ]; then
+                printf '%-75s\\\n' "#define ${name}"
+                cat "$file" | head -n -1 | sed 's/^/    \"/; s/$/\\r\\n\"/' | xargs -d'\n' printf '%-75s\\\n'
+                cat "$file" | tail -n 1  | sed 's/^/    \"/; s/$/\\r\\n\"/'
+            fi
+        fi
+
+        echo "/* END FILE */"
+    fi
+done < ${CERTS_TMP} > ${CERTS}
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index c2daf86..484c22b 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -15,6 +15,7 @@
 FAKETIME ?= faketime
 MBEDTLS_CERT_WRITE ?= $(PWD)/../../programs/x509/cert_write
 MBEDTLS_CERT_REQ ?= $(PWD)/../../programs/x509/cert_req
+MBEDTLS_GEN_KEY ?= $(PWD)/../../programs/pkey/gen_key
 
 ## Build the generated test data. Note that since the final outputs
 ## are committed to the repository, this target should do nothing on a
@@ -159,6 +160,42 @@
 	$(OPENSSL) pkey -in $< -out $@ -inform PEM -outform DER
 all_final += cli-rsa.key.der
 
+test-ca3.key.pem:
+	$(MBEDTLS_GEN_KEY) type=ec ec_curve=secp256r1 format=pem filename=$@
+test-ca3.key.der: test-ca3.key.pem
+	$(OPENSSL) ec -inform PEM -outform DER -in $< -out $@
+test-ca3.csr: test-ca3.key.der
+	$(MBEDTLS_CERT_REQ) filename=$< output_file=$@ subject_name="CN=Test CA Secp256r1, O=MbedTLS, C=UK" md=SHA256
+test-ca3.crt.pem: test-ca3.csr test-ca3.key.der
+	$(MBEDTLS_CERT_WRITE) request_file=test-ca3.csr selfsign=1 issuer_name="CN=Test CA Secp256r1, O=MbedTLS, C=UK" is_ca=1 md=SHA256 issuer_key=test-ca3.key.der output_file=$@
+test-ca3.crt.der: test-ca3.crt.pem
+	$(OPENSSL) x509 -inform PEM -outform DER -in $< -out $@
+all_final += test-ca3.key.pem test-ca3.key.der test-ca3.csr test-ca3.crt.pem test-ca3.crt.der
+
+cli3.key.pem:
+	$(MBEDTLS_GEN_KEY) type=ec ec_curve=secp256r1 format=pem filename=$@
+cli3.key.der: cli3.key.pem
+	$(OPENSSL) ec -inform PEM -outform DER -in $< -out $@
+cli3.csr: cli3.key.der
+	$(MBEDTLS_CERT_REQ) filename=$< output_file=$@ subject_name="CN=Test CRT2 Secp256r1, O=MbedTLS, C=UK" md=SHA256
+cli3.crt.pem: cli3.csr test-ca3.key.der
+	$(MBEDTLS_CERT_WRITE) request_file=cli3.csr  issuer_name="CN=Test CA Secp256r1, O=MbedTLS, C=UK" md=SHA256 issuer_key=test-ca3.key.der output_file=$@
+cli3.crt.der: cli3.crt.pem
+	$(OPENSSL) x509 -inform PEM -outform DER -in $< -out $@
+all_final += cli3.key.pem cli3.key.der cli3.csr cli3.crt.pem cli3.crt.der
+
+server11.key.pem:
+	$(MBEDTLS_GEN_KEY) type=ec ec_curve=secp256r1 format=pem filename=$@
+server11.key.der: server11.key.pem
+	$(OPENSSL) ec -inform PEM -outform DER -in $< -out $@
+server11.csr: server11.key.der
+	$(MBEDTLS_CERT_REQ) filename=$< output_file=$@ subject_name="CN=localhost, O=MbedTLS, C=UK" md=SHA256
+server11.crt.pem: server11.csr test-ca3.key.der
+	$(MBEDTLS_CERT_WRITE) request_file=server11.csr  issuer_name="CN=Test CA Secp256r1, O=MbedTLS, C=UK" md=SHA256 issuer_key=test-ca3.key.der output_file=$@
+server11.crt.der: server11.crt.pem
+	$(OPENSSL) x509 -inform PEM -outform DER -in $< -out $@
+all_final += server11.key.pem server11.key.der server11.csr server11.crt.pem server11.crt.der
+
 test_ca_int_rsa1 = test-int-ca.crt
 
 server7.csr: server7.key
diff --git a/tests/data_files/Readme-x509.txt b/tests/data_files/Readme-x509.txt
index 6f54ed0..388865b 100644
--- a/tests/data_files/Readme-x509.txt
+++ b/tests/data_files/Readme-x509.txt
@@ -11,6 +11,8 @@
 - test-ca2*.crt aka "C=NL, O=PolarSSL, CN=Polarssl Test EC CA"
   uses an EC key with NIST P-384 (aka secp384r1)
   variants used to test the keyUsage extension
+- test-ca3.crt aka "CN=TestCASecp256r1, O=MbedTLS, C=UK"
+  uses an EC key with NIST P-256 (aka secp256r1)
 The files test-ca_cat12 and test-ca_cat21 contain them concatenated both ways.
 
 Two intermediate CAs are signed by them:
@@ -40,6 +42,7 @@
 - name or pattern
 - issuing CA:   1   -> test-ca.crt
                 2   -> test-ca2.crt
+                3   -> test-ca3.crt
                 I1  -> test-int-ca.crt
                 I2  -> test-int-ca2.crt
                 I3  -> test-int-ca3.crt
@@ -57,6 +60,7 @@
 - cert_md*.crt, cert_sha*.crt: 1 R: signature hash
 - cert_v1_with_ext.crt: 1 R: v1 with extensions (illegal)
 - cli2.crt: 2 E: basic
+- cli3.crt: 3 E, secp256r1 curve
 - cli-rsa.key, cli-rsa-*.crt: RSA key used for test clients, signed by
   the RSA test CA.
 - enco-cert-utf8str.pem: see enco-ca-prstr.pem above
@@ -102,6 +106,7 @@
     _int3_int-ca2.crt: S10 + I3 + I2
     _int3_int-ca2_ca.crt: S10 + I3 + I2 + 1
     _int3_spurious_int-ca2.crt: S10 + I3 + I1(spurious) + I2
+ - server11.crt: 3 E, secp256r1 curve
 
 Certificate revocation lists
 ----------------------------
diff --git a/tests/data_files/cli3.crt.der b/tests/data_files/cli3.crt.der
new file mode 100644
index 0000000..70878cb
--- /dev/null
+++ b/tests/data_files/cli3.crt.der
Binary files differ
diff --git a/tests/data_files/cli3.crt.pem b/tests/data_files/cli3.crt.pem
new file mode 100644
index 0000000..e823c0a
--- /dev/null
+++ b/tests/data_files/cli3.crt.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBuTCCAVygAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg
+Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w
+MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMD0xHDAaBgNVBAMME1Rlc3QgQ1JU
+MiBTZWNwMjU2cjExEDAOBgNVBAoMB01iZWRUTFMxCzAJBgNVBAYTAlVLMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAEEm+TJ4LBB85IBjWNcNIodr2L06CZqLbVClmH
+uxPqiZafsAZDl0lqgL6cCigF/ML2EqFyKW+Oext3uAmNkemj6aNNMEswCQYDVR0T
+BAIwADAdBgNVHQ4EFgQUF9Yq9UkoSClnXwrdghuhrokH/hIwHwYDVR0jBBgwFoAU
+Sl6kYTNLFkgMMXgiNdb7zlDnIBIwDAYIKoZIzj0EAwIFAANJADBGAiEAg3UsTyLd
+vCPRG13gbf1R8gb85g4K1VbZ+CKl58HW2VgCIQDXk/8WFrt7vA+m3L1xJxj8iln9
+wMR16i9Fqykw7cqsRw==
+-----END CERTIFICATE-----
diff --git a/tests/data_files/cli3.csr b/tests/data_files/cli3.csr
new file mode 100644
index 0000000..501bc30
--- /dev/null
+++ b/tests/data_files/cli3.csr
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIH6MIGfAgEAMD0xHDAaBgNVBAMME1Rlc3QgQ1JUMiBTZWNwMjU2cjExEDAOBgNV
+BAoMB01iZWRUTFMxCzAJBgNVBAYTAlVLMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
+QgAEEm+TJ4LBB85IBjWNcNIodr2L06CZqLbVClmHuxPqiZafsAZDl0lqgL6cCigF
+/ML2EqFyKW+Oext3uAmNkemj6aAAMAwGCCqGSM49BAMCBQADSAAwRQIgPbHQgHvW
+f/gN4jV+GHIkQGhI4OAa7d82/dVzxXbYxnACIQCoqAs7agETcK6jp7A36pnKT9Jc
+Lck5I3roXwDPXMtzSg==
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/data_files/cli3.key.der b/tests/data_files/cli3.key.der
new file mode 100644
index 0000000..0a1851e
--- /dev/null
+++ b/tests/data_files/cli3.key.der
Binary files differ
diff --git a/tests/data_files/cli3.key.pem b/tests/data_files/cli3.key.pem
new file mode 100644
index 0000000..3d1cd1a
--- /dev/null
+++ b/tests/data_files/cli3.key.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIGFE8JJMBKeo1BnPGgzGae1stIrWdEaUvjo9xO8OTC5QoAoGCCqGSM49
+AwEHoUQDQgAEEm+TJ4LBB85IBjWNcNIodr2L06CZqLbVClmHuxPqiZafsAZDl0lq
+gL6cCigF/ML2EqFyKW+Oext3uAmNkemj6Q==
+-----END EC PRIVATE KEY-----
diff --git a/tests/data_files/server11.crt.der b/tests/data_files/server11.crt.der
new file mode 100644
index 0000000..e47f10f
--- /dev/null
+++ b/tests/data_files/server11.crt.der
Binary files differ
diff --git a/tests/data_files/server11.crt.pem b/tests/data_files/server11.crt.pem
new file mode 100644
index 0000000..ad1a2ff
--- /dev/null
+++ b/tests/data_files/server11.crt.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBrzCCAVKgAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg
+Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w
+MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMDMxEjAQBgNVBAMMCWxvY2FsaG9z
+dDEQMA4GA1UECgwHTWJlZFRMUzELMAkGA1UEBhMCVUswWTATBgcqhkjOPQIBBggq
+hkjOPQMBBwNCAATH4k2I+9HG/2AM4cN0pPkfO62ddKWwtDsdFezZoKxwXYm0ClZe
+zZYmfpl8x5Q7+V2oGg3TXoC8TOmXjAtabfDNo00wSzAJBgNVHRMEAjAAMB0GA1Ud
+DgQWBBQjXj0e2wlEVpSCbySpu2oDJgn7sjAfBgNVHSMEGDAWgBRKXqRhM0sWSAwx
+eCI11vvOUOcgEjAMBggqhkjOPQQDAgUAA0kAMEYCIQCN7/F5DbM4Ug5NcKHeKFbb
+3EHpsBjg0//gXa9mJ7Q4jAIhAIzio6vwCYnzrslzsTbPpmtU+6Op6SlzdGO/iR77
+bcfp
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server11.csr b/tests/data_files/server11.csr
new file mode 100644
index 0000000..5978e34
--- /dev/null
+++ b/tests/data_files/server11.csr
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIHwMIGVAgEAMDMxEjAQBgNVBAMMCWxvY2FsaG9zdDEQMA4GA1UECgwHTWJlZFRM
+UzELMAkGA1UEBhMCVUswWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATH4k2I+9HG
+/2AM4cN0pPkfO62ddKWwtDsdFezZoKxwXYm0ClZezZYmfpl8x5Q7+V2oGg3TXoC8
+TOmXjAtabfDNoAAwDAYIKoZIzj0EAwIFAANIADBFAiB8fjrx5Y4vietqCbuB1/1y
+1UMETwhDoCr5uRlPmOME/AIhAKr7gJJguJcXvyWPBBLJ7Ig4ingF8UGirfeWu6es
+4t3v
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/data_files/server11.key.der b/tests/data_files/server11.key.der
new file mode 100644
index 0000000..894b8fb
--- /dev/null
+++ b/tests/data_files/server11.key.der
Binary files differ
diff --git a/tests/data_files/server11.key.pem b/tests/data_files/server11.key.pem
new file mode 100644
index 0000000..ec75875
--- /dev/null
+++ b/tests/data_files/server11.key.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIGEWs7/9cQHgEI5v2qeQRGLoFhjrNK4lul6tmcqDACKuoAoGCCqGSM49
+AwEHoUQDQgAEx+JNiPvRxv9gDOHDdKT5HzutnXSlsLQ7HRXs2aCscF2JtApWXs2W
+Jn6ZfMeUO/ldqBoN016AvEzpl4wLWm3wzQ==
+-----END EC PRIVATE KEY-----
diff --git a/tests/data_files/test-ca3.crt.der b/tests/data_files/test-ca3.crt.der
new file mode 100644
index 0000000..75ba4bc
--- /dev/null
+++ b/tests/data_files/test-ca3.crt.der
Binary files differ
diff --git a/tests/data_files/test-ca3.crt.pem b/tests/data_files/test-ca3.crt.pem
new file mode 100644
index 0000000..66c2335
--- /dev/null
+++ b/tests/data_files/test-ca3.crt.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBuTCCAV2gAwIBAgIBATAMBggqhkjOPQQDAgUAMDsxGjAYBgNVBAMMEVRlc3Qg
+Q0EgU2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzAeFw0w
+MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMDsxGjAYBgNVBAMMEVRlc3QgQ0Eg
+U2VjcDI1NnIxMRAwDgYDVQQKDAdNYmVkVExTMQswCQYDVQQGEwJVSzBZMBMGByqG
+SM49AgEGCCqGSM49AwEHA0IABLZIHgilzw/iCx1r09kyZsZfarzztX4y1km0S5Mx
+rsFB67NjUhXE6/YY3W38oxeY4eIvEb516BOR/g3e3OL7Q8WjUDBOMAwGA1UdEwQF
+MAMBAf8wHQYDVR0OBBYEFEpepGEzSxZIDDF4IjXW+85Q5yASMB8GA1UdIwQYMBaA
+FEpepGEzSxZIDDF4IjXW+85Q5yASMAwGCCqGSM49BAMCBQADSAAwRQIhAKejV1jK
+vPH1vIsZAr6/VmSvjXkxmT2rpzEP9iJvJAteAiBhCPtV7LdSF1ZUqphAK3DYh2m7
+l1eSxSKXB29adbF96g==
+-----END CERTIFICATE-----
diff --git a/tests/data_files/test-ca3.csr b/tests/data_files/test-ca3.csr
new file mode 100644
index 0000000..b79b655
--- /dev/null
+++ b/tests/data_files/test-ca3.csr
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIH5MIGdAgEAMDsxGjAYBgNVBAMMEVRlc3QgQ0EgU2VjcDI1NnIxMRAwDgYDVQQK
+DAdNYmVkVExTMQswCQYDVQQGEwJVSzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
+BLZIHgilzw/iCx1r09kyZsZfarzztX4y1km0S5MxrsFB67NjUhXE6/YY3W38oxeY
+4eIvEb516BOR/g3e3OL7Q8WgADAMBggqhkjOPQQDAgUAA0kAMEYCIQD55eBPVcht
+2trIK3YYWKJbGXIoKF0930KQh8eFAcFD8AIhAI2exrMqoNF8JDoUS2m3Vv0ZFYRG
+982wT8Ok59LiWCOX
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/data_files/test-ca3.key.der b/tests/data_files/test-ca3.key.der
new file mode 100644
index 0000000..f5d2972
--- /dev/null
+++ b/tests/data_files/test-ca3.key.der
Binary files differ
diff --git a/tests/data_files/test-ca3.key.pem b/tests/data_files/test-ca3.key.pem
new file mode 100644
index 0000000..e67005f
--- /dev/null
+++ b/tests/data_files/test-ca3.key.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIDlfIVA04pd23r9UJhLf0kt6SkROecrhPbNWtawigBCkoAoGCCqGSM49
+AwEHoUQDQgAEtkgeCKXPD+ILHWvT2TJmxl9qvPO1fjLWSbRLkzGuwUHrs2NSFcTr
+9hjdbfyjF5jh4i8RvnXoE5H+Dd7c4vtDxQ==
+-----END EC PRIVATE KEY-----
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index dc6c49e..ef5dfcc 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -682,6 +682,27 @@
     if_build_succeeded tests/compat.sh -t RSA
 }
 
+component_test_no_ctr_drbg () {
+    msg "build: Default + !MBEDTLS_CTR_DRBG_C"
+    scripts/config.pl unset MBEDTLS_CTR_DRBG_C
+    CC=gcc cmake .
+    make
+
+    msg "test: !MBEDTLS_CTR_DRBG_C - ssl-opt.sh" # ~ 5s
+    if_build_succeeded tests/ssl-opt.sh --filter "Default"
+}
+
+component_test_no_ctr_drbg_no_sha512 () {
+    msg "build: Default + !MBEDTLS_CTR_DRBG_C + !MBEDTLS_SHA512_C"
+    scripts/config.pl unset MBEDTLS_CTR_DRBG_C
+    scripts/config.pl unset MBEDTLS_SHA512_C
+    CC=gcc cmake .
+    make
+
+    msg "test: !MBEDTLS_CTR_DRBG_C + !MBEDTLS_SHA512_C - ssl-opt.sh" # ~ 5s
+    if_build_succeeded tests/ssl-opt.sh --filter "Default"
+}
+
 component_test_no_resumption () {
     msg "build: Default + MBEDTLS_SSL_NO_SESSION_RESUMPTION (ASan build)" # ~ 6 min
     scripts/config.pl unset MBEDTLS_SSL_SESSION_TICKETS
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 71dba36..57d9158 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1139,14 +1139,14 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
 run_test    "CertificateRequest with empty CA list, TLS 1.1 (GnuTLS server)" \
             "$G_SRV"\
-            "$P_CLI force_version=tls1_1" \
+            "$P_CLI force_version=tls1_1 ca_file=data_files/test-ca2.crt" \
             0
 
 requires_gnutls
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1
 run_test    "CertificateRequest with empty CA list, TLS 1.0 (GnuTLS server)" \
             "$G_SRV"\
-            "$P_CLI force_version=tls1" \
+            "$P_CLI force_version=tls1 ca_file=data_files/test-ca2.crt" \
             0
 
 # Tests for SHA-1 support
@@ -2187,7 +2187,7 @@
 requires_openssl_with_fallback_scsv
 run_test    "Fallback SCSV: default, openssl server" \
             "$O_SRV" \
-            "$P_CLI debug_level=3 force_version=tls1_1 fallback=0" \
+            "$P_CLI debug_level=3 force_version=tls1_1 fallback=0 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "adding FALLBACK_SCSV" \
             -C "is a fatal alert message (msg 86)"
@@ -2195,7 +2195,7 @@
 requires_openssl_with_fallback_scsv
 run_test    "Fallback SCSV: enabled, openssl server" \
             "$O_SRV" \
-            "$P_CLI debug_level=3 force_version=tls1_1 fallback=1" \
+            "$P_CLI debug_level=3 force_version=tls1_1 fallback=1 ca_file=data_files/test-ca2.crt" \
             1 \
             -c "adding FALLBACK_SCSV" \
             -c "is a fatal alert message (msg 86)"
@@ -2426,7 +2426,7 @@
 requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
 run_test    "Session resume using tickets: openssl server" \
             "$O_SRV" \
-            "$P_CLI debug_level=3 tickets=1 reconnect=1" \
+            "$P_CLI debug_level=3 tickets=1 reconnect=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "client hello, adding session ticket extension" \
             -c "found session_ticket extension" \
@@ -2517,7 +2517,7 @@
 requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
 run_test    "Session resume using tickets, DTLS: openssl server" \
             "$O_SRV -dtls1" \
-            "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "client hello, adding session ticket extension" \
             -c "found session_ticket extension" \
@@ -2658,7 +2658,7 @@
 requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE
 run_test    "Session resume using cache: openssl server" \
             "$O_SRV" \
-            "$P_CLI debug_level=3 tickets=0 reconnect=1" \
+            "$P_CLI debug_level=3 tickets=0 reconnect=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "found session_ticket extension" \
             -C "parse new session ticket" \
@@ -2784,7 +2784,7 @@
 requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE
 run_test    "Session resume using cache, DTLS: openssl server" \
             "$O_SRV -dtls1" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "found session_ticket extension" \
             -C "parse new session ticket" \
@@ -2893,7 +2893,7 @@
 requires_gnutls
 run_test    "Max fragment length: gnutls server" \
             "$G_SRV" \
-            "$P_CLI debug_level=3 max_frag_len=4096" \
+            "$P_CLI debug_level=3 max_frag_len=4096 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "Maximum fragment length is 4096" \
             -c "client hello, adding max_fragment_length extension" \
@@ -3235,7 +3235,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Renegotiation: openssl server, client-initiated" \
             "$O_SRV -www" \
-            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
+            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "client hello, adding renegotiation extension" \
             -c "found renegotiation extension" \
@@ -3248,7 +3248,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Renegotiation: gnutls server strict, client-initiated" \
             "$G_SRV --priority=NORMAL:%SAFE_RENEGOTIATION" \
-            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
+            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "client hello, adding renegotiation extension" \
             -c "found renegotiation extension" \
@@ -3261,7 +3261,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Renegotiation: gnutls server unsafe, client-initiated default" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
-            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1" \
+            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 ca_file=data_files/test-ca2.crt" \
             1 \
             -c "client hello, adding renegotiation extension" \
             -C "found renegotiation extension" \
@@ -3274,7 +3274,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Renegotiation: gnutls server unsafe, client-inititated no legacy" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
-            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 \
+            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 ca_file=data_files/test-ca2.crt \
              allow_legacy=0" \
             1 \
             -c "client hello, adding renegotiation extension" \
@@ -3288,7 +3288,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Renegotiation: gnutls server unsafe, client-inititated legacy" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
-            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 \
+            "$P_CLI debug_level=3 exchanges=1 renegotiation=1 renegotiate=1 ca_file=data_files/test-ca2.crt \
              allow_legacy=1" \
             0 \
             -c "client hello, adding renegotiation extension" \
@@ -3345,7 +3345,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "Renegotiation: DTLS, gnutls server, client-initiated" \
             "$G_SRV -u --mtu 4096" \
-            "$P_CLI debug_level=3 dtls=1 exchanges=1 renegotiation=1 renegotiate=1" \
+            "$P_CLI debug_level=3 dtls=1 exchanges=1 renegotiation=1 renegotiate=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "client hello, adding renegotiation extension" \
             -c "found renegotiation extension" \
@@ -3359,7 +3359,7 @@
 requires_gnutls
 run_test    "Renego ext: gnutls server strict, client default" \
             "$G_SRV --priority=NORMAL:%SAFE_RENEGOTIATION" \
-            "$P_CLI debug_level=3" \
+            "$P_CLI debug_level=3 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found renegotiation extension" \
             -C "error" \
@@ -3368,7 +3368,7 @@
 requires_gnutls
 run_test    "Renego ext: gnutls server unsafe, client default" \
             "$G_SRV --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION" \
-            "$P_CLI debug_level=3" \
+            "$P_CLI debug_level=3 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "found renegotiation extension" \
             -C "error" \
@@ -3385,7 +3385,7 @@
 
 requires_gnutls
 run_test    "Renego ext: gnutls client strict, server default" \
-            "$P_SRV debug_level=3" \
+            "$P_SRV debug_level=3 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
             "$G_CLI --priority=NORMAL:%SAFE_RENEGOTIATION localhost" \
             0 \
             -s "received TLS_EMPTY_RENEGOTIATION_INFO\|found renegotiation extension" \
@@ -3393,7 +3393,7 @@
 
 requires_gnutls
 run_test    "Renego ext: gnutls client unsafe, server default" \
-            "$P_SRV debug_level=3" \
+            "$P_SRV debug_level=3 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
             "$G_CLI --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION localhost" \
             0 \
             -S "received TLS_EMPTY_RENEGOTIATION_INFO\|found renegotiation extension" \
@@ -3401,7 +3401,7 @@
 
 requires_gnutls
 run_test    "Renego ext: gnutls client unsafe, server break legacy" \
-            "$P_SRV debug_level=3 allow_legacy=-1" \
+            "$P_SRV debug_level=3 allow_legacy=-1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \
             "$G_CLI --priority=NORMAL:%DISABLE_SAFE_RENEGOTIATION localhost" \
             1 \
             -S "received TLS_EMPTY_RENEGOTIATION_INFO\|found renegotiation extension" \
@@ -3550,7 +3550,7 @@
             -C "X509 - Certificate verification failed"
 
 run_test    "Authentication: client SHA256, server required" \
-            "$P_SRV auth_mode=required" \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt" \
             "$P_CLI debug_level=3 crt_file=data_files/server6.crt \
              key_file=data_files/server6.key \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" \
@@ -3558,7 +3558,7 @@
             -c "Supported Signature Algorithm found: 5,"
 
 run_test    "Authentication: client SHA384, server required" \
-            "$P_SRV auth_mode=required" \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt" \
             "$P_CLI debug_level=3 crt_file=data_files/server6.crt \
              key_file=data_files/server6.key \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \
@@ -3692,7 +3692,7 @@
 
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
 run_test    "Authentication: openssl client no cert, server optional" \
-            "$P_SRV debug_level=3 auth_mode=optional" \
+            "$P_SRV debug_level=3 auth_mode=optional ca_file=data_files/test-ca2.crt" \
             "$O_CLI" \
             0 \
             -S "skip write certificate request" \
@@ -3703,7 +3703,7 @@
 
 run_test    "Authentication: client no cert, openssl server optional" \
             "$O_SRV -verify 10" \
-            "$P_CLI debug_level=3 crt_file=none key_file=none" \
+            "$P_CLI debug_level=3 crt_file=none key_file=none ca_file=data_files/test-ca2.crt" \
             0 \
             -C "skip parse certificate request" \
             -c "got a certificate request" \
@@ -3713,7 +3713,7 @@
 
 run_test    "Authentication: client no cert, openssl server required" \
             "$O_SRV -Verify 10" \
-            "$P_CLI debug_level=3 crt_file=none key_file=none" \
+            "$P_CLI debug_level=3 crt_file=none key_file=none ca_file=data_files/test-ca2.crt" \
             1 \
             -C "skip parse certificate request" \
             -c "got a certificate request" \
@@ -3827,14 +3827,14 @@
 # Tests for CA list in CertificateRequest messages
 
 run_test    "Authentication: send CA list in CertificateRequest  (default)" \
-            "$P_SRV debug_level=3 auth_mode=required" \
+            "$P_SRV debug_level=3 auth_mode=required ca_file=data_files/test-ca2.crt" \
             "$P_CLI crt_file=data_files/server6.crt \
              key_file=data_files/server6.key" \
             0 \
             -s "requested DN"
 
 run_test    "Authentication: do not send CA list in CertificateRequest" \
-            "$P_SRV debug_level=3 auth_mode=required cert_req_ca_list=0" \
+            "$P_SRV debug_level=3 auth_mode=required cert_req_ca_list=0 ca_file=data_files/test-ca2.crt" \
             "$P_CLI crt_file=data_files/server6.crt \
              key_file=data_files/server6.key" \
             0 \
@@ -3861,7 +3861,7 @@
                     key_file=data_files/server5.key \
                     crt_file2=data_files/server5-sha1.crt \
                     key_file2=data_files/server5.key" \
-            "$P_CLI force_version=tls1_2" \
+            "$P_CLI force_version=tls1_2 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "signed using.*ECDSA with SHA256" \
             -C "signed using.*ECDSA with SHA1"
@@ -3872,7 +3872,7 @@
                     key_file=data_files/server5.key \
                     crt_file2=data_files/server5-sha1.crt \
                     key_file2=data_files/server5.key" \
-            "$P_CLI force_version=tls1_1" \
+            "$P_CLI force_version=tls1_1 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "signed using.*ECDSA with SHA256" \
             -c "signed using.*ECDSA with SHA1"
@@ -3883,7 +3883,7 @@
                     key_file=data_files/server5.key \
                     crt_file2=data_files/server5-sha1.crt \
                     key_file2=data_files/server5.key" \
-            "$P_CLI force_version=tls1" \
+            "$P_CLI force_version=tls1 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "signed using.*ECDSA with SHA256" \
             -c "signed using.*ECDSA with SHA1"
@@ -3894,7 +3894,7 @@
                     key_file=data_files/server5.key \
                     crt_file2=data_files/server6.crt \
                     key_file2=data_files/server6.key" \
-            "$P_CLI force_version=tls1_1" \
+            "$P_CLI force_version=tls1_1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "serial number.*09" \
             -c "signed using.*ECDSA with SHA256" \
@@ -3906,7 +3906,7 @@
                     key_file=data_files/server6.key \
                     crt_file2=data_files/server5.crt \
                     key_file2=data_files/server5.key" \
-            "$P_CLI force_version=tls1_1" \
+            "$P_CLI force_version=tls1_1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "serial number.*0A" \
             -c "signed using.*ECDSA with SHA256" \
@@ -3918,7 +3918,7 @@
 run_test    "SNI: no SNI callback" \
             "$P_SRV debug_level=3 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key" \
-            "$P_CLI server_name=localhost" \
+            "$P_CLI server_name=localhost ca_file=data_files/test-ca2.crt" \
             0 \
             -S "parse ServerName extension" \
             -c "issuer name *: C=NL, O=PolarSSL, CN=Polarssl Test EC CA" \
@@ -3930,7 +3930,7 @@
             "$P_SRV debug_level=3 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
              sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
-            "$P_CLI server_name=localhost" \
+            "$P_CLI server_name=localhost ca_file=data_files/test-ca.crt" \
             0 \
             -s "parse ServerName extension" \
             -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
@@ -4068,7 +4068,7 @@
 run_test    "SNI: DTLS, no SNI callback" \
             "$P_SRV debug_level=3 dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key" \
-            "$P_CLI server_name=localhost dtls=1" \
+            "$P_CLI server_name=localhost dtls=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -S "parse ServerName extension" \
             -c "issuer name *: C=NL, O=PolarSSL, CN=Polarssl Test EC CA" \
@@ -4080,7 +4080,7 @@
             "$P_SRV debug_level=3 dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
              sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
-            "$P_CLI server_name=localhost dtls=1" \
+            "$P_CLI server_name=localhost dtls=1 ca_file=data_files/test-ca.crt" \
             0 \
             -s "parse ServerName extension" \
             -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
@@ -4092,7 +4092,7 @@
             "$P_SRV debug_level=3 dtls=1 \
              crt_file=data_files/server5.crt key_file=data_files/server5.key \
              sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
-            "$P_CLI server_name=polarssl.example dtls=1" \
+            "$P_CLI server_name=polarssl.example dtls=1 ca_file=data_files/test-ca.crt" \
             0 \
             -s "parse ServerName extension" \
             -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
@@ -4568,7 +4568,7 @@
 run_test    "keyUsage srv: ECDSA, digitalSignature -> ECDHE-ECDSA" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ds.crt" \
-            "$P_CLI" \
+            "$P_CLI ca_file=data_files/test-ca2.crt" \
             0 \
             -c "Ciphersuite is TLS-ECDHE-ECDSA-WITH-"
 
@@ -4576,14 +4576,14 @@
 run_test    "keyUsage srv: ECDSA, keyAgreement -> ECDH-" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ka.crt" \
-            "$P_CLI" \
+            "$P_CLI ca_file=data_files/test-ca2.crt" \
             0 \
             -c "Ciphersuite is TLS-ECDH-"
 
 run_test    "keyUsage srv: ECDSA, keyEncipherment -> fail" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.ku-ke.crt" \
-            "$P_CLI" \
+            "$P_CLI ca_file=data_files/test-ca2.crt" \
             1 \
             -C "Ciphersuite is "
 
@@ -4722,25 +4722,25 @@
 run_test    "extKeyUsage srv: serverAuth -> OK" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.eku-srv.crt" \
-            "$P_CLI" \
+            "$P_CLI ca_file=data_files/test-ca2.crt" \
             0
 
 run_test    "extKeyUsage srv: serverAuth,clientAuth -> OK" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.eku-srv.crt" \
-            "$P_CLI" \
+            "$P_CLI ca_file=data_files/test-ca2.crt" \
             0
 
 run_test    "extKeyUsage srv: codeSign,anyEKU -> OK" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.eku-cs_any.crt" \
-            "$P_CLI" \
+            "$P_CLI ca_file=data_files/test-ca2.crt" \
             0
 
 run_test    "extKeyUsage srv: codeSign -> fail" \
             "$P_SRV key_file=data_files/server5.key \
              crt_file=data_files/server5.eku-cli.crt" \
-            "$P_CLI" \
+            "$P_CLI ca_file=data_files/test-ca2.crt" \
             1
 
 # Tests for extendedKeyUsage, part 2: client-side checking of server cert
@@ -4748,7 +4748,7 @@
 run_test    "extKeyUsage cli: serverAuth -> OK" \
             "$O_SRV -key data_files/server5.key \
              -cert data_files/server5.eku-srv.crt" \
-            "$P_CLI debug_level=1" \
+            "$P_CLI debug_level=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "bad certificate (usage extensions)" \
             -C "Processing of the Certificate handshake message failed" \
@@ -4757,7 +4757,7 @@
 run_test    "extKeyUsage cli: serverAuth,clientAuth -> OK" \
             "$O_SRV -key data_files/server5.key \
              -cert data_files/server5.eku-srv_cli.crt" \
-            "$P_CLI debug_level=1" \
+            "$P_CLI debug_level=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "bad certificate (usage extensions)" \
             -C "Processing of the Certificate handshake message failed" \
@@ -4766,7 +4766,7 @@
 run_test    "extKeyUsage cli: codeSign,anyEKU -> OK" \
             "$O_SRV -key data_files/server5.key \
              -cert data_files/server5.eku-cs_any.crt" \
-            "$P_CLI debug_level=1" \
+            "$P_CLI debug_level=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "bad certificate (usage extensions)" \
             -C "Processing of the Certificate handshake message failed" \
@@ -4775,7 +4775,7 @@
 run_test    "extKeyUsage cli: codeSign -> fail" \
             "$O_SRV -key data_files/server5.key \
              -cert data_files/server5.eku-cs.crt" \
-            "$P_CLI debug_level=1" \
+            "$P_CLI debug_level=1 ca_file=data_files/test-ca2.crt" \
             1 \
             -c "bad certificate (usage extensions)" \
             -c "Processing of the Certificate handshake message failed" \
@@ -4816,7 +4816,7 @@
             -S "Processing of the Certificate handshake message failed"
 
 run_test    "extKeyUsage cli-auth: codeSign -> fail (hard)" \
-            "$P_SRV debug_level=1 auth_mode=required" \
+            "$P_SRV debug_level=1 auth_mode=required ca_file=data_files/test-ca2.crt" \
             "$O_CLI -key data_files/server5.key \
              -cert data_files/server5.eku-cs.crt" \
             1 \
@@ -6182,7 +6182,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 run_test    "EC restart: TLS, default" \
-            "$P_SRV auth_mode=required" \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              key_file=data_files/server5.key crt_file=data_files/server5.crt  \
              debug_level=1" \
@@ -6194,7 +6194,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 run_test    "EC restart: TLS, max_ops=0" \
-            "$P_SRV auth_mode=required" \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              key_file=data_files/server5.key crt_file=data_files/server5.crt  \
              debug_level=1 ec_max_ops=0" \
@@ -6206,7 +6206,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 run_test    "EC restart: TLS, max_ops=65535" \
-            "$P_SRV auth_mode=required" \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              key_file=data_files/server5.key crt_file=data_files/server5.crt  \
              debug_level=1 ec_max_ops=65535" \
@@ -6218,7 +6218,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 run_test    "EC restart: TLS, max_ops=1000" \
-            "$P_SRV auth_mode=required" \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              key_file=data_files/server5.key crt_file=data_files/server5.crt  \
              debug_level=1 ec_max_ops=1000" \
@@ -6231,11 +6231,11 @@
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
 run_test    "EC restart: TLS, max_ops=1000, badsign" \
-            "$P_SRV auth_mode=required \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt \
              crt_file=data_files/server5-badsign.crt \
              key_file=data_files/server5.key" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
-             key_file=data_files/server5.key crt_file=data_files/server5.crt  \
+             key_file=data_files/server5.key crt_file=data_files/server5.crt ca_file=data_files/test-ca2.crt  \
              debug_level=1 ec_max_ops=1000" \
             1 \
             -c "x509_verify_cert.*4b00" \
@@ -6249,11 +6249,12 @@
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 run_test    "EC restart: TLS, max_ops=1000, auth_mode=optional badsign" \
-            "$P_SRV auth_mode=required \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt \
              crt_file=data_files/server5-badsign.crt \
              key_file=data_files/server5.key" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              key_file=data_files/server5.key crt_file=data_files/server5.crt  \
+             ca_file=data_files/test-ca2.crt \
              debug_level=1 ec_max_ops=1000 auth_mode=optional" \
             0 \
             -c "x509_verify_cert.*4b00" \
@@ -6267,10 +6268,11 @@
 requires_config_disabled MBEDTLS_X509_REMOVE_INFO
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 run_test    "EC restart: TLS, max_ops=1000, auth_mode=none badsign" \
-            "$P_SRV auth_mode=required \
+            "$P_SRV auth_mode=required ca_file=data_files/test-ca2.crt \
              crt_file=data_files/server5-badsign.crt \
              key_file=data_files/server5.key" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+             ca_file=data_files/test-ca2.crt \
              key_file=data_files/server5.key crt_file=data_files/server5.crt  \
              debug_level=1 ec_max_ops=1000 auth_mode=none" \
             0 \
@@ -6284,7 +6286,7 @@
 
 requires_config_enabled MBEDTLS_ECP_RESTARTABLE
 run_test    "EC restart: DTLS, max_ops=1000" \
-            "$P_SRV auth_mode=required dtls=1" \
+            "$P_SRV auth_mode=required dtls=1 ca_file=data_files/test-ca2.crt" \
             "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              key_file=data_files/server5.key crt_file=data_files/server5.crt  \
              dtls=1 debug_level=1 ec_max_ops=1000" \
@@ -6450,7 +6452,7 @@
              async_operations=s async_private_delay1=1 \
              key_file=data_files/server5.key crt_file=data_files/server5.crt \
              key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
-            "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
+            "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 ca_file=data_files/test-ca2.crt" \
             0 \
             -s "Async sign callback: using key slot 0," \
             -s "Async resume (slot 0): call 0 more times." \
@@ -6853,7 +6855,7 @@
 requires_gnutls
 run_test    "DTLS reassembly: no fragmentation (gnutls server)" \
             "$G_SRV -u --mtu 2048 -a" \
-            "$P_CLI dtls=1 debug_level=2" \
+            "$P_CLI dtls=1 debug_level=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "found fragmented DTLS handshake message" \
             -C "error"
@@ -6861,7 +6863,7 @@
 requires_gnutls
 run_test    "DTLS reassembly: some fragmentation (gnutls server)" \
             "$G_SRV -u --mtu 512" \
-            "$P_CLI dtls=1 debug_level=2" \
+            "$P_CLI dtls=1 debug_level=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found fragmented DTLS handshake message" \
             -C "error"
@@ -6869,7 +6871,7 @@
 requires_gnutls
 run_test    "DTLS reassembly: more fragmentation (gnutls server)" \
             "$G_SRV -u --mtu 128" \
-            "$P_CLI dtls=1 debug_level=2" \
+            "$P_CLI dtls=1 debug_level=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found fragmented DTLS handshake message" \
             -C "error"
@@ -6877,7 +6879,7 @@
 requires_gnutls
 run_test    "DTLS reassembly: more fragmentation, nbio (gnutls server)" \
             "$G_SRV -u --mtu 128" \
-            "$P_CLI dtls=1 nbio=2 debug_level=2" \
+            "$P_CLI dtls=1 nbio=2 debug_level=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found fragmented DTLS handshake message" \
             -C "error"
@@ -6886,7 +6888,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "DTLS reassembly: fragmentation, renego (gnutls server)" \
             "$G_SRV -u --mtu 256" \
-            "$P_CLI debug_level=3 dtls=1 renegotiation=1 renegotiate=1" \
+            "$P_CLI debug_level=3 dtls=1 renegotiation=1 renegotiate=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found fragmented DTLS handshake message" \
             -c "client hello, adding renegotiation extension" \
@@ -6900,7 +6902,7 @@
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 run_test    "DTLS reassembly: fragmentation, nbio, renego (gnutls server)" \
             "$G_SRV -u --mtu 256" \
-            "$P_CLI debug_level=3 nbio=2 dtls=1 renegotiation=1 renegotiate=1" \
+            "$P_CLI debug_level=3 nbio=2 dtls=1 renegotiation=1 renegotiate=1 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found fragmented DTLS handshake message" \
             -c "client hello, adding renegotiation extension" \
@@ -6912,28 +6914,28 @@
 
 run_test    "DTLS reassembly: no fragmentation (openssl server)" \
             "$O_SRV -dtls1 -mtu 2048" \
-            "$P_CLI dtls=1 debug_level=2" \
+            "$P_CLI dtls=1 debug_level=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -C "found fragmented DTLS handshake message" \
             -C "error"
 
 run_test    "DTLS reassembly: some fragmentation (openssl server)" \
             "$O_SRV -dtls1 -mtu 768" \
-            "$P_CLI dtls=1 debug_level=2" \
+            "$P_CLI dtls=1 debug_level=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found fragmented DTLS handshake message" \
             -C "error"
 
 run_test    "DTLS reassembly: more fragmentation (openssl server)" \
             "$O_SRV -dtls1 -mtu 256" \
-            "$P_CLI dtls=1 debug_level=2" \
+            "$P_CLI dtls=1 debug_level=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found fragmented DTLS handshake message" \
             -C "error"
 
 run_test    "DTLS reassembly: fragmentation, nbio (openssl server)" \
             "$O_SRV -dtls1 -mtu 256" \
-            "$P_CLI dtls=1 nbio=2 debug_level=2" \
+            "$P_CLI dtls=1 nbio=2 debug_level=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -c "found fragmented DTLS handshake message" \
             -C "error"
@@ -6958,11 +6960,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              max_frag_len=4096" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              max_frag_len=4096" \
             0 \
@@ -6978,11 +6982,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              max_frag_len=1024" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              max_frag_len=2048" \
             0 \
@@ -7002,11 +7008,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              max_frag_len=512" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              max_frag_len=4096" \
             0 \
@@ -7022,11 +7030,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=none \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              max_frag_len=2048" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              max_frag_len=1024" \
              0 \
@@ -7050,11 +7060,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=none \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              max_frag_len=2048" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              max_frag_len=1024" \
             0 \
@@ -7070,11 +7082,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              max_frag_len=2048" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              max_frag_len=1024" \
             0 \
@@ -7098,11 +7112,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              max_frag_len=2048" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              max_frag_len=1024" \
             0 \
@@ -7117,11 +7133,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              mtu=4096" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              mtu=4096" \
             0 \
@@ -7136,11 +7154,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=3500-60000 \
              mtu=4096" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=3500-60000 \
              mtu=1024" \
             0 \
@@ -7155,11 +7175,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              mtu=512" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              mtu=2048" \
             0 \
@@ -7175,11 +7197,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              mtu=1024" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=2500-60000 \
              mtu=1024" \
             0 \
@@ -7200,11 +7224,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=2500-60000 \
              mtu=512" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=2500-60000 \
              mtu=512" \
@@ -7231,10 +7257,12 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=400-3200" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=400-3200" \
             0 \
@@ -7255,10 +7283,12 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=250-10000" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=250-10000" \
             0 \
@@ -7278,11 +7308,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=10000-60000 \
              mtu=1024" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=10000-60000 \
              mtu=1024" \
             0 \
@@ -7307,11 +7339,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=10000-60000 \
              mtu=512" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=10000-60000 \
              mtu=512" \
@@ -7330,11 +7364,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=10000-60000 \
              mtu=1024 nbio=2" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=10000-60000 \
              mtu=1024 nbio=2" \
             0 \
@@ -7356,11 +7392,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=10000-60000 \
              mtu=512 nbio=2" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=10000-60000 \
              mtu=512 nbio=2" \
@@ -7392,11 +7430,13 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=10000-60000 \
              mtu=1450" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=10000-60000 \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              mtu=1450 reconnect=1 reco_delay=1" \
@@ -7421,12 +7461,14 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              exchanges=2 renegotiation=1 \
              hs_timeout=10000-60000 \
              mtu=512" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              exchanges=2 renegotiation=1 renegotiate=1 \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=10000-60000 \
@@ -7453,12 +7495,14 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              exchanges=2 renegotiation=1 \
              hs_timeout=10000-60000 \
              mtu=512" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              exchanges=2 renegotiation=1 renegotiate=1 \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=10000-60000 \
@@ -7485,6 +7529,7 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              exchanges=2 renegotiation=1 \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8 \
              hs_timeout=10000-60000 \
@@ -7492,6 +7537,7 @@
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              exchanges=2 renegotiation=1 renegotiate=1 \
              hs_timeout=10000-60000 \
              mtu=1024" \
@@ -7518,6 +7564,7 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              exchanges=2 renegotiation=1 \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 \
              hs_timeout=10000-60000 \
@@ -7525,6 +7572,7 @@
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              exchanges=2 renegotiation=1 renegotiate=1 \
              hs_timeout=10000-60000 \
              mtu=1024" \
@@ -7550,6 +7598,7 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              exchanges=2 renegotiation=1 \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 etm=0 \
              hs_timeout=10000-60000 \
@@ -7557,6 +7606,7 @@
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              exchanges=2 renegotiation=1 renegotiate=1 \
              hs_timeout=10000-60000 \
              mtu=1024" \
@@ -7579,10 +7629,12 @@
             "$P_SRV dgram_packing=0 dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=250-10000 mtu=512" \
             "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=250-10000 mtu=512" \
             0 \
@@ -7603,10 +7655,12 @@
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca.crt \
              hs_timeout=250-10000 mtu=512 nbio=2" \
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
              hs_timeout=250-10000 mtu=512 nbio=2" \
             0 \
@@ -7628,6 +7682,7 @@
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              mtu=512 force_version=dtls1_2" \
             0 \
             -c "fragmenting handshake message" \
@@ -7643,6 +7698,7 @@
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              mtu=512 force_version=dtls1" \
             0 \
             -c "fragmenting handshake message" \
@@ -7665,6 +7721,7 @@
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca2.crt \
              mtu=512 force_version=dtls1_2" \
             "$G_CLI -u --insecure 127.0.0.1" \
             0 \
@@ -7681,6 +7738,7 @@
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca2.crt \
              mtu=512 force_version=dtls1" \
             "$G_CLI -u --insecure 127.0.0.1" \
             0 \
@@ -7695,6 +7753,7 @@
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              mtu=512 force_version=dtls1_2" \
             0 \
             -c "fragmenting handshake message" \
@@ -7709,6 +7768,7 @@
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              mtu=512 force_version=dtls1" \
             0 \
             -c "fragmenting handshake message" \
@@ -7722,6 +7782,7 @@
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca2.crt \
              mtu=512 force_version=dtls1_2" \
             "$O_CLI -dtls1_2" \
             0 \
@@ -7735,6 +7796,7 @@
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca2.crt \
              mtu=512 force_version=dtls1" \
             "$O_CLI -dtls1" \
             0 \
@@ -7756,6 +7818,7 @@
             "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=250-60000 mtu=512 force_version=dtls1_2" \
             0 \
             -c "fragmenting handshake message" \
@@ -7773,6 +7836,7 @@
             "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=250-60000 mtu=512 force_version=dtls1" \
             0 \
             -c "fragmenting handshake message" \
@@ -7789,6 +7853,7 @@
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=250-60000 mtu=512 force_version=dtls1_2" \
            "$G_NEXT_CLI -u --insecure 127.0.0.1" \
             0 \
@@ -7805,6 +7870,7 @@
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=250-60000 mtu=512 force_version=dtls1" \
            "$G_NEXT_CLI -u --insecure 127.0.0.1" \
             0 \
@@ -7827,6 +7893,7 @@
             "$P_CLI dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=250-60000 mtu=512 force_version=dtls1_2" \
             0 \
             -c "fragmenting handshake message" \
@@ -7844,6 +7911,7 @@
             "$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
              crt_file=data_files/server8_int-ca2.crt \
              key_file=data_files/server8.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=250-60000 mtu=512 force_version=dtls1" \
             0 \
             -c "fragmenting handshake message" \
@@ -7860,6 +7928,7 @@
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=250-60000 mtu=512 force_version=dtls1_2" \
             "$O_CLI -dtls1_2" \
             0 \
@@ -7878,6 +7947,7 @@
             "$P_SRV dgram_packing=0 dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
              key_file=data_files/server7.key \
+             ca_file=data_files/test-ca2.crt \
              hs_timeout=250-60000 mtu=512 force_version=dtls1" \
             "$O_CLI -nbio -dtls1" \
             0 \
@@ -8381,7 +8451,7 @@
 run_test    "DTLS proxy: 3d, gnutls server" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$G_SRV -u --mtu 2048 -a" \
-            "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000" \
+            "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000 ca_file=data_files/test-ca2.crt" \
             0 \
             -s "Extra-header:" \
             -c "Extra-header:"
@@ -8392,7 +8462,7 @@
 run_test    "DTLS proxy: 3d, gnutls server, fragmentation" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$G_NEXT_SRV -u --mtu 512" \
-            "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000" \
+            "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000 ca_file=data_files/test-ca2.crt" \
             0 \
             -s "Extra-header:" \
             -c "Extra-header:"
@@ -8403,7 +8473,7 @@
 run_test    "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \
             -p "$P_PXY drop=5 delay=5 duplicate=5" \
             "$G_NEXT_SRV -u --mtu 512" \
-            "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000 nbio=2" \
+            "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000 nbio=2 ca_file=data_files/test-ca2.crt" \
             0 \
             -s "Extra-header:" \
             -c "Extra-header:"
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index 89c84e8..f2a9b98 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -1506,7 +1506,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */
+/* BEGIN_CASE depends_on:MBEDTLS_CTR_DRBG_C:MBEDTLS_ENTROPY_C:ENTROPY_HAVE_STRONG */
 void mbedtls_rsa_validate_params( int radix_N, char *input_N,
                                   int radix_P, char *input_P,
                                   int radix_Q, char *input_Q,