Merge pull request #3051 from danh-arm/dh/drop-cla

Drop requirement for a CLA 
diff --git a/ChangeLog b/ChangeLog
index 4bbf8f1..3f2f593 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,12 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
-= mbed TLS X.X.X branch released XXXX-XX-XX
+= mbed TLS x.x.x branch released xxxx-xx-xx
+
+New deprecations
+   * Deprecate MBEDTLS_SSL_HW_RECORD_ACCEL that enables function hooks in the
+     SSL module for hardware acceleration of individual records.
+
+= mbed TLS 2.21.0 branch released 2020-02-20
 
 New deprecations
    * Deprecate MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO that enables parsing
@@ -44,6 +50,11 @@
      contributed by apple-ihack-geek in #2663.
    * Fix a possible error code mangling in psa_mac_verify_finish() when
      a cryptographic accelerator fails. ARMmbed/mbed-crypto#345
+   * Fix a bug in mbedtls_pk_parse_key() that would cause it to accept some
+     RSA keys that would later be rejected by functions expecting private
+     keys. Found by Catena cyber using oss-fuzz (issue 20467).
+   * Fix a bug in mbedtls_pk_parse_key() that would cause it to
+     accept some RSA keys with invalid values by silently fixing those values.
 
 = mbed TLS 2.20.0 branch released 2020-01-15
 
diff --git a/crypto b/crypto
index 4d8c836..cf4a40b 160000
--- a/crypto
+++ b/crypto
@@ -1 +1 @@
-Subproject commit 4d8c836cdc4559d862337c5b2ecc9ca5d1e7810f
+Subproject commit cf4a40ba0a3086cabb5a8227245191161fd26383
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 5b5aefb..8e2539d 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -24,7 +24,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.20.0 source code documentation
+ * @mainpage mbed TLS v2.21.0 source code documentation
  *
  * This documentation describes the internal structure of mbed TLS.  It was
  * automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index 47a9740..7db91bc 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
 # identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "mbed TLS v2.20.0"
+PROJECT_NAME           = "mbed TLS v2.21.0"
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index ec11426..99363b3 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -798,6 +798,14 @@
 #endif
 #endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
 
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS"
+#elif defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS"
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
 /*
  * Avoid warning from -pedantic. This is a convenient place for this
  * workaround since this is included by every single file before the
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 7abdaa5..70a9740 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1527,6 +1527,9 @@
  * Enable hooking functions in SSL module for hardware acceleration of
  * individual records.
  *
+ * \deprecated This option is deprecated and will be removed in a future
+ *             version of Mbed TLS.
+ *
  * Uncomment this macro to enable hooking functions.
  */
 //#define MBEDTLS_SSL_HW_RECORD_ACCEL
@@ -1781,8 +1784,8 @@
  *
  * Fallback to old (pre-2.7), non-conforming implementation of the truncated
  * HMAC extension which also truncates the HMAC key. Note that this option is
- * only meant for a transitory upgrade period and is likely to be removed in
- * a future version of the library.
+ * only meant for a transitory upgrade period and will be removed in a future
+ * version of the library.
  *
  * \warning The old implementation is non-compliant and has a security weakness
  *          (2^80 brute force attack on the HMAC key used for a single,
@@ -1791,7 +1794,7 @@
  *          bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
  *          the fixed implementation yet (pre-2.7).
  *
- * \deprecated This option is deprecated and will likely be removed in a
+ * \deprecated This option is deprecated and will be removed in a
  *             future version of Mbed TLS.
  *
  * Uncomment to fallback to old, non-compliant truncated HMAC implementation.
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 655f59d..1666f8c 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1323,21 +1323,40 @@
 
 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
 
-#define MBEDTLS_SSL_CHANNEL_OUTBOUND    0
-#define MBEDTLS_SSL_CHANNEL_INBOUND     1
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
 
-extern int (*mbedtls_ssl_hw_record_init)(mbedtls_ssl_context *ssl,
-                const unsigned char *key_enc, const unsigned char *key_dec,
-                size_t keylen,
-                const unsigned char *iv_enc,  const unsigned char *iv_dec,
-                size_t ivlen,
-                const unsigned char *mac_enc, const unsigned char *mac_dec,
-                size_t maclen);
-extern int (*mbedtls_ssl_hw_record_activate)(mbedtls_ssl_context *ssl, int direction);
-extern int (*mbedtls_ssl_hw_record_reset)(mbedtls_ssl_context *ssl);
-extern int (*mbedtls_ssl_hw_record_write)(mbedtls_ssl_context *ssl);
-extern int (*mbedtls_ssl_hw_record_read)(mbedtls_ssl_context *ssl);
-extern int (*mbedtls_ssl_hw_record_finish)(mbedtls_ssl_context *ssl);
+#define MBEDTLS_SSL_CHANNEL_OUTBOUND   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( 0 )
+#define MBEDTLS_SSL_CHANNEL_INBOUND    MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( 1 )
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_init)(
+                    mbedtls_ssl_context *ssl,
+                    const unsigned char *key_enc, const unsigned char *key_dec,
+                    size_t keylen,
+                    const unsigned char *iv_enc,  const unsigned char *iv_dec,
+                    size_t ivlen,
+                    const unsigned char *mac_enc, const unsigned char *mac_dec,
+                    size_t maclen);
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_activate)(
+                                                    mbedtls_ssl_context *ssl,
+                                                    int direction );
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_reset)(
+                                                    mbedtls_ssl_context *ssl );
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_write)(
+                                                    mbedtls_ssl_context *ssl );
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_read)(
+                                                    mbedtls_ssl_context *ssl );
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_finish)(
+                                                    mbedtls_ssl_context *ssl );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
 #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
 
 /**
@@ -3169,7 +3188,7 @@
  * \warning        Use of RC4 in DTLS/TLS has been prohibited by RFC 7465
  *                 for security reasons. Use at your own risk.
  *
- * \note           This function is deprecated and will likely be removed in
+ * \note           This function is deprecated and will be removed in
  *                 a future version of the library.
  *                 RC4 is disabled by default at compile time and needs to be
  *                 actively enabled for use with legacy systems.
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index d4e5d54..35af4cc 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -39,7 +39,7 @@
  * Major, Minor, Patchlevel
  */
 #define MBEDTLS_VERSION_MAJOR  2
-#define MBEDTLS_VERSION_MINOR  20
+#define MBEDTLS_VERSION_MINOR  21
 #define MBEDTLS_VERSION_PATCH  0
 
 /**
@@ -47,9 +47,9 @@
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02140000
-#define MBEDTLS_VERSION_STRING         "2.20.0"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.20.0"
+#define MBEDTLS_VERSION_NUMBER         0x02150000
+#define MBEDTLS_VERSION_STRING         "2.21.0"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.21.0"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 1544325..ed244a7 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -175,14 +175,14 @@
 if(USE_SHARED_MBEDTLS_LIBRARY)
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.20.0 SOVERSION 1)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.21.0 SOVERSION 1)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
     target_include_directories(mbedx509
         PUBLIC ${MBEDTLS_DIR}/include/
         PUBLIC ${MBEDTLS_DIR}/crypto/include/)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.20.0 SOVERSION 13)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.21.0 SOVERSION 13)
     target_link_libraries(mbedtls ${libs} mbedx509)
     target_include_directories(mbedtls
         PUBLIC ${MBEDTLS_DIR}/include/
diff --git a/programs/Makefile b/programs/Makefile
index 188c2be..d004e2e 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -56,34 +56,56 @@
 LOCAL_LDFLAGS += -lz
 endif
 
-APPS =	aes/aescrypt2$(EXEXT)		aes/crypt_and_hash$(EXEXT)	\
-	hash/hello$(EXEXT)		hash/generic_sum$(EXEXT)	\
-					pkey/dh_client$(EXEXT)		\
-	pkey/dh_genprime$(EXEXT)	pkey/dh_server$(EXEXT)		\
-	pkey/ecdh_curve25519$(EXEXT)					\
-	pkey/ecdsa$(EXEXT)		pkey/gen_key$(EXEXT)		\
-	pkey/key_app$(EXEXT)		pkey/key_app_writer$(EXEXT)	\
-	pkey/mpi_demo$(EXEXT)		pkey/pk_decrypt$(EXEXT)		\
-	pkey/pk_encrypt$(EXEXT)		pkey/pk_sign$(EXEXT)		\
-	pkey/pk_verify$(EXEXT)		pkey/rsa_genkey$(EXEXT)		\
-	pkey/rsa_decrypt$(EXEXT)	pkey/rsa_encrypt$(EXEXT)	\
-	pkey/rsa_sign$(EXEXT)		pkey/rsa_verify$(EXEXT)		\
-	pkey/rsa_sign_pss$(EXEXT)	pkey/rsa_verify_pss$(EXEXT)	\
-	ssl/dtls_client$(EXEXT)		ssl/dtls_server$(EXEXT)		\
-	ssl/ssl_client1$(EXEXT)		ssl/ssl_client2$(EXEXT)		\
-	ssl/ssl_server$(EXEXT)		ssl/ssl_server2$(EXEXT)		\
-	ssl/ssl_fork_server$(EXEXT)	ssl/mini_client$(EXEXT)		\
-	ssl/ssl_mail_client$(EXEXT)	random/gen_entropy$(EXEXT)	\
-	random/gen_random_havege$(EXEXT)				\
-	random/gen_random_ctr_drbg$(EXEXT)				\
-	test/benchmark$(EXEXT)                          		\
-	test/selftest$(EXEXT)		test/udp_proxy$(EXEXT)		\
-	test/zeroize$(EXEXT)						\
-	test/query_compile_time_config$(EXEXT)				\
-	util/pem2der$(EXEXT)		util/strerror$(EXEXT)		\
-	x509/cert_app$(EXEXT)		x509/crl_app$(EXEXT)		\
-	x509/cert_req$(EXEXT)		x509/cert_write$(EXEXT)		\
-	x509/req_app$(EXEXT)
+APPS = \
+	aes/aescrypt2$(EXEXT) \
+	aes/crypt_and_hash$(EXEXT) \
+	hash/hello$(EXEXT) \
+	hash/generic_sum$(EXEXT) \
+	pkey/dh_client$(EXEXT) \
+	pkey/dh_genprime$(EXEXT) \
+	pkey/dh_server$(EXEXT) \
+	pkey/ecdh_curve25519$(EXEXT) \
+	pkey/ecdsa$(EXEXT) \
+	pkey/gen_key$(EXEXT) \
+	pkey/key_app$(EXEXT) \
+	pkey/key_app_writer$(EXEXT) \
+	pkey/mpi_demo$(EXEXT) \
+	pkey/pk_decrypt$(EXEXT) \
+	pkey/pk_encrypt$(EXEXT) \
+	pkey/pk_sign$(EXEXT) \
+	pkey/pk_verify$(EXEXT) \
+	pkey/rsa_genkey$(EXEXT) \
+	pkey/rsa_decrypt$(EXEXT) \
+	pkey/rsa_encrypt$(EXEXT) \
+	pkey/rsa_sign$(EXEXT) \
+	pkey/rsa_verify$(EXEXT) \
+	pkey/rsa_sign_pss$(EXEXT) \
+	pkey/rsa_verify_pss$(EXEXT) \
+	ssl/dtls_client$(EXEXT) \
+	ssl/dtls_server$(EXEXT) \
+	ssl/ssl_client1$(EXEXT) \
+	ssl/ssl_client2$(EXEXT) \
+	ssl/ssl_server$(EXEXT) \
+	ssl/ssl_server2$(EXEXT) \
+	ssl/ssl_fork_server$(EXEXT) \
+	ssl/mini_client$(EXEXT) \
+	ssl/ssl_mail_client$(EXEXT) \
+	random/gen_entropy$(EXEXT) \
+	random/gen_random_havege$(EXEXT) \
+	random/gen_random_ctr_drbg$(EXEXT) \
+	test/benchmark$(EXEXT) \
+	test/selftest$(EXEXT) \
+	test/udp_proxy$(EXEXT) \
+	test/zeroize$(EXEXT) \
+	test/query_compile_time_config$(EXEXT) \
+	util/pem2der$(EXEXT) \
+	util/strerror$(EXEXT) \
+	x509/cert_app$(EXEXT) \
+	x509/crl_app$(EXEXT) \
+	x509/cert_req$(EXEXT) \
+	x509/cert_write$(EXEXT) \
+	x509/req_app$(EXEXT) \
+# End of APPS
 
 ifdef PTHREAD
 APPS +=	ssl/ssl_pthread_server$(EXEXT)
@@ -231,17 +253,17 @@
 	echo "  CC    ssl/ssl_client1.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client1.c  $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
-ssl/ssl_client2$(EXEXT): ssl/ssl_client2.c ssl/query_config.c $(DEP)
+ssl/ssl_client2$(EXEXT): ssl/ssl_client2.c test/query_config.c $(DEP)
 	echo "  CC    ssl/ssl_client2.c"
-	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client2.c ssl/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_client2.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
 ssl/ssl_server$(EXEXT): ssl/ssl_server.c $(DEP)
 	echo "  CC    ssl/ssl_server.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server.c   $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
-ssl/ssl_server2$(EXEXT): ssl/ssl_server2.c ssl/query_config.c $(DEP)
+ssl/ssl_server2$(EXEXT): ssl/ssl_server2.c test/query_config.c $(DEP)
 	echo "  CC    ssl/ssl_server2.c"
-	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server2.c ssl/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/ssl_server2.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
 ssl/ssl_fork_server$(EXEXT): ssl/ssl_fork_server.c $(DEP)
 	echo "  CC    ssl/ssl_fork_server.c"
@@ -279,9 +301,9 @@
 	echo "  CC    test/zeroize.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/zeroize.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
-test/query_compile_time_config$(EXEXT): test/query_compile_time_config.c ssl/query_config.c $(DEP)
+test/query_compile_time_config$(EXEXT): test/query_compile_time_config.c test/query_config.c $(DEP)
 	echo "  CC    test/query_compile_time_config.c"
-	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/query_compile_time_config.c ssl/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/query_compile_time_config.c test/query_config.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
 util/pem2der$(EXEXT): util/pem2der.c $(DEP)
 	echo "  CC    util/pem2der.c"
diff --git a/programs/aes/CMakeLists.txt b/programs/aes/CMakeLists.txt
index f5a0caa..6c4c7e1 100644
--- a/programs/aes/CMakeLists.txt
+++ b/programs/aes/CMakeLists.txt
@@ -1,8 +1,8 @@
 add_executable(aescrypt2 aescrypt2.c)
-target_link_libraries(aescrypt2 mbedtls)
+target_link_libraries(aescrypt2 mbedcrypto)
 
 add_executable(crypt_and_hash crypt_and_hash.c)
-target_link_libraries(crypt_and_hash mbedtls)
+target_link_libraries(crypt_and_hash mbedcrypto)
 
 install(TARGETS aescrypt2 crypt_and_hash
         DESTINATION "bin"
diff --git a/programs/hash/CMakeLists.txt b/programs/hash/CMakeLists.txt
index eda975b..3c6cca9 100644
--- a/programs/hash/CMakeLists.txt
+++ b/programs/hash/CMakeLists.txt
@@ -1,8 +1,8 @@
 add_executable(hello hello.c)
-target_link_libraries(hello mbedtls)
+target_link_libraries(hello mbedcrypto)
 
 add_executable(generic_sum generic_sum.c)
-target_link_libraries(generic_sum mbedtls)
+target_link_libraries(generic_sum mbedcrypto)
 
 install(TARGETS hello generic_sum
         DESTINATION "bin"
diff --git a/programs/pkey/CMakeLists.txt b/programs/pkey/CMakeLists.txt
index 5a37a42..8456228 100644
--- a/programs/pkey/CMakeLists.txt
+++ b/programs/pkey/CMakeLists.txt
@@ -2,61 +2,61 @@
 target_link_libraries(dh_client mbedtls)
 
 add_executable(dh_genprime dh_genprime.c)
-target_link_libraries(dh_genprime mbedtls)
+target_link_libraries(dh_genprime mbedcrypto)
 
 add_executable(dh_server dh_server.c)
 target_link_libraries(dh_server mbedtls)
 
 add_executable(ecdh_curve25519 ecdh_curve25519.c)
-target_link_libraries(ecdh_curve25519 mbedtls)
+target_link_libraries(ecdh_curve25519 mbedcrypto)
 
 add_executable(ecdsa ecdsa.c)
-target_link_libraries(ecdsa mbedtls)
+target_link_libraries(ecdsa mbedcrypto)
 
 add_executable(gen_key gen_key.c)
-target_link_libraries(gen_key mbedtls)
+target_link_libraries(gen_key mbedcrypto)
 
 add_executable(key_app key_app.c)
-target_link_libraries(key_app mbedtls)
+target_link_libraries(key_app mbedcrypto)
 
 add_executable(key_app_writer key_app_writer.c)
-target_link_libraries(key_app_writer mbedtls)
+target_link_libraries(key_app_writer mbedcrypto)
 
 add_executable(mpi_demo mpi_demo.c)
-target_link_libraries(mpi_demo mbedtls)
+target_link_libraries(mpi_demo mbedcrypto)
 
 add_executable(rsa_genkey rsa_genkey.c)
-target_link_libraries(rsa_genkey mbedtls)
+target_link_libraries(rsa_genkey mbedcrypto)
 
 add_executable(rsa_sign rsa_sign.c)
-target_link_libraries(rsa_sign mbedtls)
+target_link_libraries(rsa_sign mbedcrypto)
 
 add_executable(rsa_verify rsa_verify.c)
-target_link_libraries(rsa_verify mbedtls)
+target_link_libraries(rsa_verify mbedcrypto)
 
 add_executable(rsa_sign_pss rsa_sign_pss.c)
-target_link_libraries(rsa_sign_pss mbedtls)
+target_link_libraries(rsa_sign_pss mbedcrypto)
 
 add_executable(rsa_verify_pss rsa_verify_pss.c)
-target_link_libraries(rsa_verify_pss mbedtls)
+target_link_libraries(rsa_verify_pss mbedcrypto)
 
 add_executable(rsa_encrypt rsa_encrypt.c)
-target_link_libraries(rsa_encrypt mbedtls)
+target_link_libraries(rsa_encrypt mbedcrypto)
 
 add_executable(rsa_decrypt rsa_decrypt.c)
-target_link_libraries(rsa_decrypt mbedtls)
+target_link_libraries(rsa_decrypt mbedcrypto)
 
 add_executable(pk_sign pk_sign.c)
-target_link_libraries(pk_sign mbedtls)
+target_link_libraries(pk_sign mbedcrypto)
 
 add_executable(pk_verify pk_verify.c)
-target_link_libraries(pk_verify mbedtls)
+target_link_libraries(pk_verify mbedcrypto)
 
 add_executable(pk_encrypt pk_encrypt.c)
-target_link_libraries(pk_encrypt mbedtls)
+target_link_libraries(pk_encrypt mbedcrypto)
 
 add_executable(pk_decrypt pk_decrypt.c)
-target_link_libraries(pk_decrypt mbedtls)
+target_link_libraries(pk_decrypt mbedcrypto)
 
 install(TARGETS dh_client dh_genprime dh_server key_app mpi_demo rsa_genkey rsa_sign rsa_verify rsa_encrypt rsa_decrypt pk_encrypt pk_decrypt pk_sign pk_verify gen_key
         DESTINATION "bin"
diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c
index 7939309..19dcdfe 100644
--- a/programs/pkey/key_app.c
+++ b/programs/pkey/key_app.c
@@ -40,7 +40,7 @@
     defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO)
 #include "mbedtls/error.h"
 #include "mbedtls/rsa.h"
-#include "mbedtls/x509.h"
+#include "mbedtls/pk.h"
 
 #include <string.h>
 #endif
diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c
index d556c19..f2b7b50 100644
--- a/programs/pkey/rsa_genkey.c
+++ b/programs/pkey/rsa_genkey.c
@@ -42,7 +42,6 @@
 #include "mbedtls/entropy.h"
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/bignum.h"
-#include "mbedtls/x509.h"
 #include "mbedtls/rsa.h"
 
 #include <stdio.h>
@@ -149,19 +148,6 @@
         mbedtls_printf( " failed\n  ! mbedtls_mpi_write_file returned %d\n\n", ret );
         goto exit;
     }
-/*
-    mbedtls_printf( " ok\n  . Generating the certificate..." );
-
-    x509write_init_raw( &cert );
-    x509write_add_pubkey( &cert, &rsa );
-    x509write_add_subject( &cert, "CN='localhost'" );
-    x509write_add_validity( &cert, "2007-09-06 17:00:32",
-                                   "2010-09-06 17:00:32" );
-    x509write_create_selfsign( &cert, &rsa );
-    x509write_crtfile( &cert, "cert.der", X509_OUTPUT_DER );
-    x509write_crtfile( &cert, "cert.pem", X509_OUTPUT_PEM );
-    x509write_free_raw( &cert );
-*/
     mbedtls_printf( " ok\n\n" );
 
     exit_code = MBEDTLS_EXIT_SUCCESS;
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index 42209e2..5019f28 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -55,7 +55,7 @@
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/md.h"
 #include "mbedtls/rsa.h"
-#include "mbedtls/x509.h"
+#include "mbedtls/pk.h"
 
 #include <stdio.h>
 #include <string.h>
diff --git a/programs/pkey/rsa_verify_pss.c b/programs/pkey/rsa_verify_pss.c
index 148cd51..de28337 100644
--- a/programs/pkey/rsa_verify_pss.c
+++ b/programs/pkey/rsa_verify_pss.c
@@ -55,7 +55,6 @@
 #include "mbedtls/pem.h"
 #include "mbedtls/pk.h"
 #include "mbedtls/md.h"
-#include "mbedtls/x509.h"
 
 #include <stdio.h>
 #include <string.h>
diff --git a/programs/random/CMakeLists.txt b/programs/random/CMakeLists.txt
index 30933d8..630c66e 100644
--- a/programs/random/CMakeLists.txt
+++ b/programs/random/CMakeLists.txt
@@ -1,11 +1,11 @@
 add_executable(gen_random_havege gen_random_havege.c)
-target_link_libraries(gen_random_havege mbedtls)
+target_link_libraries(gen_random_havege mbedcrypto)
 
 add_executable(gen_random_ctr_drbg gen_random_ctr_drbg.c)
-target_link_libraries(gen_random_ctr_drbg mbedtls)
+target_link_libraries(gen_random_ctr_drbg mbedcrypto)
 
 add_executable(gen_entropy gen_entropy.c)
-target_link_libraries(gen_entropy mbedtls)
+target_link_libraries(gen_entropy mbedcrypto)
 
 install(TARGETS gen_random_havege gen_random_ctr_drbg gen_entropy
         DESTINATION "bin"
diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt
index 803920c..f28a47d 100644
--- a/programs/ssl/CMakeLists.txt
+++ b/programs/ssl/CMakeLists.txt
@@ -34,14 +34,14 @@
 target_link_libraries(ssl_client1 ${libs})
 
 add_executable(ssl_client2 ssl_client2.c)
-target_sources(ssl_client2 PUBLIC query_config.c)
+target_sources(ssl_client2 PUBLIC ../test/query_config.c)
 target_link_libraries(ssl_client2 ${libs})
 
 add_executable(ssl_server ssl_server.c)
 target_link_libraries(ssl_server ${libs})
 
 add_executable(ssl_server2 ssl_server2.c)
-target_sources(ssl_server2 PUBLIC query_config.c)
+target_sources(ssl_server2 PUBLIC ../test/query_config.c)
 target_link_libraries(ssl_server2 ${libs})
 
 add_executable(ssl_fork_server ssl_fork_server.c)
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index c188900..ab72f15 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -145,6 +145,7 @@
 #define DFL_REPRODUCIBLE        0
 #define DFL_NSS_KEYLOG          0
 #define DFL_NSS_KEYLOG_FILE     NULL
+#define DFL_SKIP_CLOSE_NOTIFY   0
 
 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
 #define GET_REQUEST_END "\r\n\r\n"
@@ -389,6 +390,7 @@
     "                        options: 1 (level-triggered, implies nbio=1),\n" \
     "    read_timeout=%%d     default: 0 ms (no timeout)\n"        \
     "    max_resend=%%d       default: 0 (no resend on timeout)\n" \
+    "    skip_close_notify=%%d default: 0 (send close_notify)\n" \
     "\n"                                                    \
     USAGE_DTLS                                              \
     USAGE_CID                                               \
@@ -517,6 +519,7 @@
     const char *cid_val_renego; /* the CID to use for incoming messages
                                  * after renegotiation                      */
     int reproducible;           /* make communication reproducible          */
+    int skip_close_notify;      /* skip sending the close_notify alert      */
 } opt;
 
 int query_config( const char *config );
@@ -1311,6 +1314,7 @@
     opt.reproducible        = DFL_REPRODUCIBLE;
     opt.nss_keylog          = DFL_NSS_KEYLOG;
     opt.nss_keylog_file     = DFL_NSS_KEYLOG_FILE;
+    opt.skip_close_notify   = DFL_SKIP_CLOSE_NOTIFY;
 
     for( i = 1; i < argc; i++ )
     {
@@ -1723,6 +1727,12 @@
         {
             opt.nss_keylog_file = q;
         }
+        else if( strcmp( p, "skip_close_notify" ) == 0 )
+        {
+            opt.skip_close_notify = atoi( q );
+            if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 )
+                goto usage;
+        }
         else
             goto usage;
     }
@@ -3160,10 +3170,25 @@
     mbedtls_printf( "  . Closing the connection..." );
     fflush( stdout );
 
-    /* No error checking, the connection might be closed already */
-    do ret = mbedtls_ssl_close_notify( &ssl );
-    while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
-    ret = 0;
+    /*
+     * Most of the time sending a close_notify before closing is the right
+     * thing to do. However, when the server already knows how many messages
+     * are expected and closes the connection by itself, this alert becomes
+     * redundant. Sometimes with DTLS this redundancy becomes a problem by
+     * leading to a race condition where the server might close the connection
+     * before seeing the alert, and since UDP is connection-less when the
+     * alert arrives it will be seen as a new connection, which will fail as
+     * the alert is clearly not a valid ClientHello. This may cause spurious
+     * failures in tests that use DTLS and resumption with ssl_server2 in
+     * ssl-opt.sh, avoided by enabling skip_close_notify client-side.
+     */
+    if( opt.skip_close_notify == 0 )
+    {
+        /* No error checking, the connection might be closed already */
+        do ret = mbedtls_ssl_close_notify( &ssl );
+        while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
+        ret = 0;
+    }
 
     mbedtls_printf( " done\n" );
 
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 282ef58..a26c096 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -14,22 +14,22 @@
 target_link_libraries(selftest ${libs})
 
 add_executable(benchmark benchmark.c)
-target_link_libraries(benchmark ${libs})
+target_link_libraries(benchmark mbedcrypto)
 
 if(TEST_CPP)
     add_executable(cpp_dummy_build cpp_dummy_build.cpp)
-    target_link_libraries(cpp_dummy_build ${libs})
+    target_link_libraries(cpp_dummy_build mbedcrypto)
 endif()
 
 add_executable(udp_proxy udp_proxy.c)
 target_link_libraries(udp_proxy ${libs})
 
 add_executable(zeroize zeroize.c)
-target_link_libraries(zeroize ${libs})
+target_link_libraries(zeroize mbedcrypto)
 
 add_executable(query_compile_time_config query_compile_time_config.c)
-target_sources(query_compile_time_config PUBLIC ../ssl/query_config.c)
-target_link_libraries(query_compile_time_config ${libs})
+target_sources(query_compile_time_config PUBLIC query_config.c)
+target_link_libraries(query_compile_time_config mbedcrypto)
 
 install(TARGETS selftest benchmark udp_proxy query_compile_time_config
         DESTINATION "bin"
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index b005c20..8f89c70 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -686,12 +686,13 @@
         mbedtls_ctr_drbg_context ctr_drbg;
 
         mbedtls_ctr_drbg_init( &ctr_drbg );
-
         if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
             mbedtls_exit(1);
         TIME_AND_TSC( "CTR_DRBG (NOPR)",
                 mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) );
+        mbedtls_ctr_drbg_free( &ctr_drbg );
 
+        mbedtls_ctr_drbg_init( &ctr_drbg );
         if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
             mbedtls_exit(1);
         mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON );
diff --git a/programs/ssl/query_config.c b/programs/test/query_config.c
similarity index 100%
rename from programs/ssl/query_config.c
rename to programs/test/query_config.c
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 727054e..bd28e9a 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -66,6 +66,8 @@
 #else
 #include <stdio.h>
 #include <stdlib.h>
+#define mbedtls_calloc     calloc
+#define mbedtls_free       free
 #define mbedtls_printf     printf
 #define mbedtls_snprintf   snprintf
 #define mbedtls_exit       exit
@@ -78,6 +80,86 @@
 #endif
 
 
+#if defined MBEDTLS_SELF_TEST
+/* Sanity check for malloc. This is not expected to fail, and is rather
+ * intended to display potentially useful information about the platform,
+ * in particular the behavior of malloc(0). */
+static int calloc_self_test( int verbose )
+{
+    int failures = 0;
+    void *empty1 = mbedtls_calloc( 0, 1 );
+    void *empty2 = mbedtls_calloc( 0, 1 );
+    void *buffer1 = mbedtls_calloc( 1, 1 );
+    void *buffer2 = mbedtls_calloc( 1, 1 );
+    uintptr_t old_buffer1;
+
+    if( empty1 == NULL && empty2 == NULL )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(0): passed (NULL)\n" );
+    }
+    else if( empty1 == NULL || empty2 == NULL )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(0): failed (mix of NULL and non-NULL)\n" );
+        ++failures;
+    }
+    else if( empty1 == empty2 )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(0): passed (same non-null)\n" );
+    }
+    else
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(0): passed (distinct non-null)\n" );
+    }
+
+    if( buffer1 == NULL || buffer2 == NULL )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1): failed (NULL)\n" );
+        ++failures;
+    }
+    else if( buffer1 == buffer2 )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1): failed (same buffer twice)\n" );
+        ++failures;
+    }
+    else
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1): passed\n" );
+    }
+
+    old_buffer1 = (uintptr_t) buffer1;
+    mbedtls_free( buffer1 );
+    buffer1 = mbedtls_calloc( 1, 1 );
+    if( buffer1 == NULL )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1 again): failed (NULL)\n" );
+        ++failures;
+    }
+    else
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1 again): passed (%s address)\n",
+                            (uintptr_t) old_buffer1 == (uintptr_t) buffer1 ?
+                            "same" : "different" );
+    }
+
+    if( verbose )
+        mbedtls_printf( "\n" );
+    mbedtls_free( empty1 );
+    mbedtls_free( empty2 );
+    mbedtls_free( buffer1 );
+    mbedtls_free( buffer2 );
+    return( failures );
+}
+#endif /* MBEDTLS_SELF_TEST */
+
 static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
 {
     int ret;
@@ -174,6 +256,7 @@
 
 const selftest_t selftests[] =
 {
+    {"calloc", calloc_self_test},
 #if defined(MBEDTLS_MD2_C)
     {"md2", mbedtls_md2_self_test},
 #endif
diff --git a/programs/util/CMakeLists.txt b/programs/util/CMakeLists.txt
index f9b6604..4c3fb0d 100644
--- a/programs/util/CMakeLists.txt
+++ b/programs/util/CMakeLists.txt
@@ -1,5 +1,5 @@
 set(libs
-    mbedtls
+    mbedcrypto
 )
 
 add_executable(strerror strerror.c)
diff --git a/programs/x509/CMakeLists.txt b/programs/x509/CMakeLists.txt
index 39b8b5b..68dec99 100644
--- a/programs/x509/CMakeLists.txt
+++ b/programs/x509/CMakeLists.txt
@@ -1,5 +1,5 @@
 set(libs
-    mbedtls
+    mbedx509
 )
 
 if(USE_PKCS11_HELPER_LIBRARY)
@@ -11,7 +11,7 @@
 endif(ENABLE_ZLIB_SUPPORT)
 
 add_executable(cert_app cert_app.c)
-target_link_libraries(cert_app ${libs})
+target_link_libraries(cert_app ${libs} mbedtls)
 
 add_executable(crl_app crl_app.c)
 target_link_libraries(crl_app ${libs})
diff --git a/scripts/bump_version.sh b/scripts/bump_version.sh
index c39a86a..cf875c8 100755
--- a/scripts/bump_version.sh
+++ b/scripts/bump_version.sh
@@ -132,7 +132,7 @@
 [ $VERBOSE ] && echo "Re-generating library/error.c"
 scripts/generate_errors.pl
 
-[ $VERBOSE ] && echo "Re-generating programs/ssl/query_config.c"
+[ $VERBOSE ] && echo "Re-generating programs/test/query_config.c"
 scripts/generate_query_config.pl
 
 [ $VERBOSE ] && echo "Re-generating library/version_features.c"
diff --git a/scripts/generate_query_config.pl b/scripts/generate_query_config.pl
index f15e03a..d94fdad 100755
--- a/scripts/generate_query_config.pl
+++ b/scripts/generate_query_config.pl
@@ -21,7 +21,7 @@
 my $config_file = "./include/mbedtls/config.h";
 
 my $query_config_format_file = "./scripts/data_files/query_config.fmt";
-my $query_config_file = "./programs/ssl/query_config.c";
+my $query_config_file = "./programs/test/query_config.c";
 
 # Excluded macros from the generated query_config.c. For example, macros that
 # have commas or function-like macros cannot be transformed into strings easily
diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl
index 90ab609..0342f8f 100755
--- a/scripts/generate_visualc_files.pl
+++ b/scripts/generate_visualc_files.pl
@@ -117,7 +117,7 @@
     my $srcs = "\n    <ClCompile Include=\"..\\..\\programs\\$path.c\" \/>\r";
     if( $appname eq "ssl_client2" or $appname eq "ssl_server2" or
         $appname eq "query_compile_time_config" ) {
-        $srcs .= "\n    <ClCompile Include=\"..\\..\\programs\\ssl\\query_config.c\" \/>\r";
+        $srcs .= "\n    <ClCompile Include=\"..\\..\\programs\\test\\query_config.c\" \/>\r";
     }
 
     my $content = $template;
diff --git a/tests/configs/config-wrapper-malloc-0-null.h b/tests/configs/config-wrapper-malloc-0-null.h
new file mode 100644
index 0000000..ed74eda
--- /dev/null
+++ b/tests/configs/config-wrapper-malloc-0-null.h
@@ -0,0 +1,39 @@
+/* config.h wrapper that forces calloc(0) to return NULL.
+ * Used for testing.
+ */
+/*
+ *  Copyright (C) 2019, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CONFIG_H
+/* Don't #define MBEDTLS_CONFIG_H, let config.h do it. */
+
+#include "mbedtls/config.h"
+
+#include <stdlib.h>
+static inline void *custom_calloc( size_t nmemb, size_t size )
+{
+    if( nmemb == 0 || size == 0 )
+        return( NULL );
+    return( calloc( nmemb, size ) );
+}
+
+#define MBEDTLS_PLATFORM_MEMORY
+#define MBEDTLS_PLATFORM_STD_CALLOC custom_calloc
+
+#endif /* MBEDTLS_CONFIG_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index cc19ab2..2ade64d 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1183,6 +1183,29 @@
     make test
 }
 
+component_test_malloc_0_null () {
+    msg "build: malloc(0) returns NULL (ASan+UBSan build)"
+    scripts/config.pl full
+    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    make CC=gcc CFLAGS="'-DMBEDTLS_CONFIG_FILE=\"$PWD/tests/configs/config-wrapper-malloc-0-null.h\"' -O -Werror -Wall -Wextra -fsanitize=address,undefined" LDFLAGS='-fsanitize=address,undefined'
+
+    msg "test: malloc(0) returns NULL (ASan+UBSan build)"
+    make test
+
+    msg "selftest: malloc(0) returns NULL (ASan+UBSan build)"
+    # Just the calloc selftest. "make test" ran the others as part of the
+    # test suites.
+    if_build_succeeded programs/test/selftest calloc
+
+    msg "test ssl-opt.sh: malloc(0) returns NULL (ASan+UBSan build)"
+    # Run a subset of the tests. The choice is a balance between coverage
+    # and time (including time indirectly wasted due to flaky tests).
+    # The current choice is to skip tests whose description includes
+    # "proxy", which is an approximation of skipping tests that use the
+    # UDP proxy, which tend to be slower and flakier.
+    if_build_succeeded tests/ssl-opt.sh -e 'proxy'
+}
+
 component_test_make_shared () {
     msg "build/test: make shared" # ~ 40s
     make SHARED=1 all check
diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh
index 065ea33..f41e465 100755
--- a/tests/scripts/check-generated-files.sh
+++ b/tests/scripts/check-generated-files.sh
@@ -65,6 +65,6 @@
 }
 
 check scripts/generate_errors.pl library/error.c
-check scripts/generate_query_config.pl programs/ssl/query_config.c
+check scripts/generate_query_config.pl programs/test/query_config.c
 check scripts/generate_features.pl library/version_features.c
 check scripts/generate_visualc_files.pl visualc/VS2010
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index e65b8ec..8585b25 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -2535,7 +2535,7 @@
 
 run_test    "Session resume using tickets, DTLS: basic" \
             "$P_SRV debug_level=3 dtls=1 tickets=1" \
-            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1" \
+            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -2549,7 +2549,7 @@
 
 run_test    "Session resume using tickets, DTLS: cache disabled" \
             "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \
-            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1" \
+            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -2563,7 +2563,7 @@
 
 run_test    "Session resume using tickets, DTLS: timeout" \
             "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0 ticket_timeout=1" \
-            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 reco_delay=2" \
+            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1 reco_delay=2" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -2577,7 +2577,7 @@
 
 run_test    "Session resume using tickets, DTLS: session copy" \
             "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \
-            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 reco_mode=0" \
+            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1 reco_mode=0" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -2718,7 +2718,7 @@
 
 run_test    "Session resume using cache, DTLS: tickets enabled on client" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -2732,7 +2732,7 @@
 
 run_test    "Session resume using cache, DTLS: tickets enabled on server" \
             "$P_SRV dtls=1 debug_level=3 tickets=1" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -C "client hello, adding session ticket extension" \
             -S "found session ticket extension" \
@@ -2746,7 +2746,7 @@
 
 run_test    "Session resume using cache, DTLS: cache_max=0" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -S "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -2755,7 +2755,7 @@
 
 run_test    "Session resume using cache, DTLS: cache_max=1" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=1" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -s "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -2764,7 +2764,7 @@
 
 run_test    "Session resume using cache, DTLS: timeout > delay" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=0" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=0" \
             0 \
             -s "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -2773,7 +2773,7 @@
 
 run_test    "Session resume using cache, DTLS: timeout < delay" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=1" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=2" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
             0 \
             -S "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -2782,7 +2782,7 @@
 
 run_test    "Session resume using cache, DTLS: no timeout" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=2" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
             0 \
             -s "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -2791,7 +2791,7 @@
 
 run_test    "Session resume using cache, DTLS: session copy" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_mode=0" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_mode=0" \
             0 \
             -s "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -4543,19 +4543,19 @@
 
 run_test    "Event-driven I/O, DTLS: ticket + client auth + resume" \
             "$P_SRV dtls=1 event=1 tickets=1 auth_mode=required" \
-            "$P_CLI dtls=1 event=1 tickets=1 reconnect=1" \
+            "$P_CLI dtls=1 event=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
 run_test    "Event-driven I/O, DTLS: ticket + resume" \
             "$P_SRV dtls=1 event=1 tickets=1 auth_mode=none" \
-            "$P_CLI dtls=1 event=1 tickets=1 reconnect=1" \
+            "$P_CLI dtls=1 event=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
 run_test    "Event-driven I/O, DTLS: session-id resume" \
             "$P_SRV dtls=1 event=1 tickets=0 auth_mode=none" \
-            "$P_CLI dtls=1 event=1 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 event=1 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
@@ -4567,7 +4567,7 @@
 run_test    "Event-driven I/O, DTLS: session-id resume, UDP packing" \
             -p "$P_PXY pack=50" \
             "$P_SRV dtls=1 event=1 tickets=0 auth_mode=required" \
-            "$P_CLI dtls=1 event=1 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 event=1 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
@@ -7807,7 +7807,7 @@
              key_file=data_files/server8.key \
              hs_timeout=10000-60000 \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
-             mtu=1450 reconnect=1 reco_delay=1" \
+             mtu=1450 reconnect=1 skip_close_notify=1 reco_delay=1" \
             0 \
             -S "autoreduction" \
             -s "found fragmented DTLS handshake message" \
@@ -8656,7 +8656,7 @@
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
              psk=abc123 debug_level=3" \
             "$P_CLI dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 psk=abc123 \
-             debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
+             debug_level=3 reconnect=1 skip_close_notify=1 read_timeout=1000 max_resend=10 \
              force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
             0 \
             -s "a session has been resumed" \
@@ -8670,7 +8670,7 @@
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
              psk=abc123 debug_level=3 nbio=2" \
             "$P_CLI dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 psk=abc123 \
-             debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
+             debug_level=3 reconnect=1 skip_close_notify=1 read_timeout=1000 max_resend=10 \
              force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 nbio=2" \
             0 \
             -s "a session has been resumed" \
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index abc61b5..39a9d54 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -199,83 +199,174 @@
 Negative test moving servers ssl to state: NEW_SESSION_TICKET
 move_handshake_to_state:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:0
 
+# Note - the case below will have to updated, since the test sends no data due to a 1n-1 split against BEAST, that was not expected when preparing the fragment counting code.
 Handshake, SSL3
 depends_on:MBEDTLS_SSL_PROTO_SSL3:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED
-handshake:"":MBEDTLS_SSL_MINOR_VERSION_0:MBEDTLS_PK_RSA:""
+handshake_version:MBEDTLS_SSL_MINOR_VERSION_0:0
 
+# Note - the case below will have to updated, since the test sends no data due to a 1n-1 split against BEAST, that was not expected when preparing the fragment counting code.
 Handshake, tls1
-depends_on:MBEDTLS_SSL_PROTO_TLS1:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CIPHER_MODE_CBC
-handshake:"":MBEDTLS_SSL_MINOR_VERSION_1:MBEDTLS_PK_RSA:""
+depends_on:MBEDTLS_SSL_PROTO_TLS1:MBEDTLS_CIPHER_MODE_CBC
+handshake_version:MBEDTLS_SSL_MINOR_VERSION_1:0
 
 Handshake, tls1_1
-depends_on:MBEDTLS_SSL_PROTO_TLS1_1:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CIPHER_MODE_CBC
-handshake:"":MBEDTLS_SSL_MINOR_VERSION_2:MBEDTLS_PK_RSA:""
+depends_on:MBEDTLS_SSL_PROTO_TLS1_1:MBEDTLS_CIPHER_MODE_CBC
+handshake_version:MBEDTLS_SSL_MINOR_VERSION_2:0
 
 Handshake, tls1_2
-depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED
-handshake:"":MBEDTLS_SSL_MINOR_VERSION_3:MBEDTLS_PK_RSA:""
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2
+handshake_version:MBEDTLS_SSL_MINOR_VERSION_3:0
 
 Handshake, ECDHE-RSA-WITH-AES-256-GCM-SHA384
-depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SHA512_C:MBEDTLS_AES_C:MBEDTLS_GCM_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
-handshake:"TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384":MBEDTLS_SSL_MINOR_VERSION_3:MBEDTLS_PK_RSA:""
+depends_on:MBEDTLS_SHA512_C:MBEDTLS_AES_C:MBEDTLS_GCM_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+handshake_cipher:"TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384":MBEDTLS_PK_RSA:0
 
 Handshake, RSA-WITH-AES-128-CCM
-depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED
-handshake:"TLS-RSA-WITH-AES-128-CCM":MBEDTLS_SSL_MINOR_VERSION_3:MBEDTLS_PK_RSA:""
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+handshake_cipher:"TLS-RSA-WITH-AES-128-CCM":MBEDTLS_PK_RSA:0
 
 Handshake, DHE-RSA-WITH-AES-256-CBC-SHA256
-depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SHA256_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED
-handshake:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256":MBEDTLS_SSL_MINOR_VERSION_3:MBEDTLS_PK_RSA:""
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_SHA256_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+handshake_cipher:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256":MBEDTLS_PK_RSA:0
 
 Handshake, ECDHE-ECDSA-WITH-AES-256-CCM
-depends_on:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
-handshake:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_SSL_MINOR_VERSION_3:MBEDTLS_PK_ECDSA:""
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+handshake_cipher:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:0
 
 Handshake, ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384
-depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SHA512_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C
-handshake:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_SSL_MINOR_VERSION_3:MBEDTLS_PK_ECDSA:""
+depends_on:MBEDTLS_SHA512_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C
+handshake_cipher:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:0
 
 Handshake, PSK-WITH-AES-128-CBC-SHA
-depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED
-handshake:"TLS-PSK-WITH-AES-128-CBC-SHA":MBEDTLS_SSL_MINOR_VERSION_3:MBEDTLS_PK_RSA:"abc123"
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+handshake_psk_cipher:"TLS-PSK-WITH-AES-128-CBC-SHA":MBEDTLS_PK_RSA:"abc123":0
 
-Test sending app data MFL=512 without fragmentation
+DTLS Handshake, tls1_1
+depends_on:MBEDTLS_SSL_PROTO_TLS1_1:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_SSL_PROTO_DTLS
+handshake_version:MBEDTLS_SSL_MINOR_VERSION_2:1
+
+DTLS Handshake, tls1_2
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_PROTO_DTLS
+handshake_version:MBEDTLS_SSL_MINOR_VERSION_3:1
+
+DTLS Handshake, ECDHE-RSA-WITH-AES-256-GCM-SHA384
+depends_on:MBEDTLS_SHA512_C:MBEDTLS_AES_C:MBEDTLS_GCM_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED:MBEDTLS_SSL_PROTO_DTLS
+handshake_cipher:"TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384":MBEDTLS_PK_RSA:1
+
+DTLS Handshake, RSA-WITH-AES-128-CCM
+depends_on:MBEDTLS_CCM_C:MBEDTLS_AES_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS
+handshake_cipher:"TLS-RSA-WITH-AES-128-CCM":MBEDTLS_PK_RSA:1
+
+DTLS Handshake, DHE-RSA-WITH-AES-256-CBC-SHA256
+depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_SHA256_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS
+handshake_cipher:"TLS-DHE-RSA-WITH-AES-256-CBC-SHA256":MBEDTLS_PK_RSA:1
+
+DTLS Handshake, ECDHE-ECDSA-WITH-AES-256-CCM
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS
+handshake_cipher:"TLS-ECDHE-ECDSA-WITH-AES-256-CCM":MBEDTLS_PK_ECDSA:1
+
+DTLS Handshake, ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384
+depends_on:MBEDTLS_SHA512_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_CAMELLIA_C:MBEDTLS_SSL_PROTO_DTLS
+handshake_cipher:"TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384":MBEDTLS_PK_ECDSA:1
+
+DTLS Handshake, PSK-WITH-AES-128-CBC-SHA
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS
+handshake_psk_cipher:"TLS-PSK-WITH-AES-128-CBC-SHA":MBEDTLS_PK_RSA:"abc123":1
+
+DTLS Handshake with serialization, tls1_2
+depends_on:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS
+handshake_serialization
+
+DTLS Handshake fragmentation, MFL=512
+handshake_fragmentation:MBEDTLS_SSL_MAX_FRAG_LEN_512:1:1
+
+DTLS Handshake fragmentation, MFL=1024
+handshake_fragmentation:MBEDTLS_SSL_MAX_FRAG_LEN_1024:0:1
+
+Sending app data via TLS, MFL=512 without fragmentation
 depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_512:400:512:1:1
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_512:400:512:1:1
 
-Test sending app data MFL=512 with fragmentation
+Sending app data via TLS, MFL=512 with fragmentation
 depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_512:513:1536:2:3
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_512:513:1536:2:3
 
-Test sending app data MFL=1024 without fragmentation
+Sending app data via TLS, MFL=1024 without fragmentation
 depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1000:1024:1:1
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1000:1024:1:1
 
-Test sending app data MFL=1024 with fragmentation
+Sending app data via TLS, MFL=1024 with fragmentation
 depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1025:5120:2:5
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1025:5120:2:5
 
-Test sending app data MFL=2048 without fragmentation
+Sending app data via TLS, MFL=2048 without fragmentation
 depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2000:2048:1:1
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2000:2048:1:1
 
-Test sending app data MFL=2048 with fragmentation
+Sending app data via TLS, MFL=2048 with fragmentation
 depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2049:8192:2:4
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2049:8192:2:4
 
-Test sending app data MFL=4096 without fragmentation
+Sending app data via TLS, MFL=4096 without fragmentation
 depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4000:4096:1:1
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4000:4096:1:1
 
-Test sending app data MFL=4096 with fragmentation
+Sending app data via TLS, MFL=4096 with fragmentation
 depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4097:12288:2:3
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4097:12288:2:3
 
-Test sending app data without MFL and without fragmentation
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16001:16384:1:1
+Sending app data via TLS without MFL and without fragmentation
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16001:16384:1:1
 
-Test sending app data without MFL and with fragmentation
-send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16385:100000:2:7
+Sending app data via TLS without MFL and with fragmentation
+app_data_tls:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16385:100000:2:7
+
+Sending app data via DTLS, MFL=512 without fragmentation
+depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_512:400:512:1:1
+
+Sending app data via DTLS, MFL=512 with fragmentation
+depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_512:513:1536:0:0
+
+Sending app data via DTLS, MFL=1024 without fragmentation
+depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1000:1024:1:1
+
+Sending app data via DTLS, MFL=1024 with fragmentation
+depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1025:5120:0:0
+
+Sending app data via DTLS, MFL=2048 without fragmentation
+depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2000:2048:1:1
+
+Sending app data via DTLS, MFL=2048 with fragmentation
+depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2049:8192:0:0
+
+Sending app data via DTLS, MFL=4096 without fragmentation
+depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4000:4096:1:1
+
+Sending app data via DTLS, MFL=4096 with fragmentation
+depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4097:12288:0:0
+
+Sending app data via DTLS, without MFL and without fragmentation
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16001:16384:1:1
+
+Sending app data via DTLS, without MFL and with fragmentation
+app_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16385:100000:0:0
+
+DTLS renegotiation: no legacy renegotiation
+renegotiation:MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION
+
+DTLS renegotiation: legacy renegotiation
+renegotiation:MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION
+
+DTLS renegotiation: legacy break handshake
+renegotiation:MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE
 
 SSL DTLS replay: initial state, seqnum 0
 ssl_dtls_replay:"":"000000000000":0
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 1a62078..44e2227 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -4,7 +4,80 @@
 #include <mbedtls/ctr_drbg.h>
 #include <mbedtls/entropy.h>
 #include <mbedtls/certs.h>
+#include <mbedtls/timing.h>
+#include <mbedtls/debug.h>
 
+typedef struct log_pattern
+{
+    const char *pattern;
+    size_t counter;
+} log_pattern;
+
+/* This function can be passed to mbedtls to receive output logs from it. In
+ * this case, it will count the instances of a log_pattern in the received
+ * logged messages.
+ */
+void log_analyzer( void *ctx, int level,
+                   const char *file, int line,
+                   const char *str )
+{
+    log_pattern *p = (log_pattern *) ctx;
+
+    (void) level;
+    (void) line;
+    (void) file;
+
+    if( NULL != p &&
+        NULL != p->pattern &&
+        NULL != strstr( str, p->pattern ) )
+    {
+        p->counter++;
+    }
+}
+
+typedef struct handshake_test_options
+{
+    const char *cipher;
+    int version;
+    int pk_alg;
+    data_t *psk_str;
+    int dtls;
+    int srv_auth_mode;
+    int serialize;
+    int mfl;
+    int cli_msg_len;
+    int srv_msg_len;
+    int expected_cli_fragments;
+    int expected_srv_fragments;
+    int renegotiate;
+    int legacy_renegotiation;
+    void *srv_log_obj;
+    void *cli_log_obj;
+    void (*srv_log_fun)(void *, int, const char *, int, const char *);
+    void (*cli_log_fun)(void *, int, const char *, int, const char *);
+} handshake_test_options;
+
+void init_handshake_options( handshake_test_options *opts )
+{
+  opts->cipher = "";
+  opts->version = MBEDTLS_SSL_MINOR_VERSION_3;
+  opts->pk_alg = MBEDTLS_PK_RSA;
+  opts->psk_str = NULL;
+  opts->dtls = 0;
+  opts->srv_auth_mode = MBEDTLS_SSL_VERIFY_NONE;
+  opts->serialize = 0;
+  opts->mfl = MBEDTLS_SSL_MAX_FRAG_LEN_NONE;
+  opts->cli_msg_len = 100;
+  opts->srv_msg_len = 100;
+  opts->expected_cli_fragments = 1;
+  opts->expected_srv_fragments = 1;
+  opts->renegotiate = 0;
+  opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION;
+  opts->srv_log_obj = NULL;
+  opts->srv_log_obj = NULL;
+  opts->srv_log_fun = NULL;
+  opts->cli_log_fun = NULL;
+}
 /*
  * Buffer structure for custom I/O callbacks.
  */
@@ -158,8 +231,6 @@
  * Errors used in the message transport mock tests
  */
  #define MBEDTLS_TEST_ERROR_ARG_NULL -11
- #define MBEDTLS_TEST_ERROR_QUEUE_FULL -22
- #define MBEDTLS_TEST_ERROR_QUEUE_EMPTY -33
  #define MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED -44
 
 /*
@@ -212,7 +283,7 @@
  * This will become the last element to leave it (fifo).
  *
  * \retval  MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null.
- * \retval  MBEDTLS_TEST_ERROR_QUEUE_FULL, if the queue is full.
+ * \retval  MBEDTLS_ERR_SSL_WANT_WRITE, if the queue is full.
  * \retval  \p len, if the push was successful.
  */
 int mbedtls_test_message_queue_push_info( mbedtls_test_message_queue *queue,
@@ -223,7 +294,7 @@
         return MBEDTLS_TEST_ERROR_ARG_NULL;
 
     if( queue->num >= queue->capacity )
-        return MBEDTLS_TEST_ERROR_QUEUE_FULL;
+        return MBEDTLS_ERR_SSL_WANT_WRITE;
 
     place = ( queue->pos + queue->num ) % queue->capacity;
     queue->messages[place] = len;
@@ -237,7 +308,7 @@
  * case the data will be popped from the queue but not copied anywhere.
  *
  * \retval  MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null.
- * \retval  MBEDTLS_TEST_ERROR_QUEUE_EMPTY, if the queue is empty.
+ * \retval  MBEDTLS_ERR_SSL_WANT_READ, if the queue is empty.
  * \retval  message length, if the pop was successful, up to the given
             \p buf_len.
  */
@@ -248,7 +319,7 @@
     if( queue == NULL )
         return MBEDTLS_TEST_ERROR_ARG_NULL;
     if( queue->num == 0 )
-        return MBEDTLS_TEST_ERROR_QUEUE_EMPTY;
+        return MBEDTLS_ERR_SSL_WANT_READ;
 
     message_length = queue->messages[queue->pos];
     queue->messages[queue->pos] = 0;
@@ -266,7 +337,7 @@
  * This will be the oldest inserted message length(fifo).
  *
  * \retval  MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null.
- * \retval  MBEDTLS_TEST_ERROR_QUEUE_EMPTY, if the queue is empty.
+ * \retval  MBEDTLS_ERR_SSL_WANT_READ, if the queue is empty.
  * \retval  0, if the peek was successful.
  * \retval  MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED, if the given buffer length is
  *          too small to fit the message. In this case the \p msg_len will be
@@ -279,7 +350,7 @@
     if( queue == NULL || msg_len == NULL )
         return MBEDTLS_TEST_ERROR_ARG_NULL;
     if( queue->num == 0 )
-        return MBEDTLS_TEST_ERROR_QUEUE_EMPTY;
+        return MBEDTLS_ERR_SSL_WANT_READ;
 
     *msg_len = queue->messages[queue->pos];
     return ( *msg_len > buf_len ) ? MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED : 0;
@@ -528,7 +599,7 @@
  * \retval  MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context
  *          elements or the context itself is null.
  * \retval  MBEDTLS_TEST_ERROR_SEND_FAILED if mbedtls_mock_tcp_send_b failed.
- * \retval  MBEDTLS_TEST_ERROR_QUEUE_FULL, if the output queue is full.
+ * \retval  MBEDTLS_ERR_SSL_WANT_WRITE, if the output queue is full.
  *
  * This function will also return any error from
  * mbedtls_test_message_queue_push_info.
@@ -549,7 +620,7 @@
     socket = context->socket;
 
     if( queue->num >= queue->capacity )
-        return MBEDTLS_TEST_ERROR_QUEUE_FULL;
+        return MBEDTLS_ERR_SSL_WANT_WRITE;
 
     if( mbedtls_mock_tcp_send_b( socket, buf, len ) != (int) len )
         return MBEDTLS_TEST_ERROR_SEND_FAILED;
@@ -758,17 +829,26 @@
  *
  * \p endpoint_type must be set as MBEDTLS_SSL_IS_SERVER or
  * MBEDTLS_SSL_IS_CLIENT.
+ * \p pk_alg the algorithm to use, currently only MBEDTLS_PK_RSA and
+ * MBEDTLS_PK_ECDSA are supported.
+ * \p dtls_context - in case of DTLS - this is the context handling metadata.
+ * \p input_queue - used only in case of DTLS.
+ * \p output_queue - used only in case of DTLS.
  *
  * \retval  0 on success, otherwise error code.
  */
-int mbedtls_endpoint_init( mbedtls_endpoint *ep, int endpoint_type, int pk_alg )
+int mbedtls_endpoint_init( mbedtls_endpoint *ep, int endpoint_type, int pk_alg,
+                           mbedtls_test_message_socket_context *dtls_context,
+                           mbedtls_test_message_queue *input_queue,
+                           mbedtls_test_message_queue *output_queue )
 {
     int ret = -1;
 
-    if( ep == NULL )
-    {
+    if( dtls_context != NULL && ( input_queue == NULL || output_queue == NULL ) )
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
-    }
+
+    if( ep == NULL )
+        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
 
     memset( ep, 0, sizeof( *ep ) );
 
@@ -781,7 +861,16 @@
         mbedtls_ctr_drbg_random,
         &( ep->ctr_drbg ) );
     mbedtls_entropy_init( &( ep->entropy ) );
-    mbedtls_mock_socket_init( &( ep->socket ) );
+    if( dtls_context != NULL )
+    {
+        TEST_ASSERT( mbedtls_message_socket_setup( input_queue, output_queue,
+                                                   100, &( ep->socket ),
+                                                   dtls_context ) == 0 );
+    }
+    else
+    {
+        mbedtls_mock_socket_init( &( ep->socket ) );
+    }
 
     ret = mbedtls_ctr_drbg_seed( &( ep->ctr_drbg ), mbedtls_entropy_func,
                     &( ep->entropy ), (const unsigned char *) ( ep->name ),
@@ -789,18 +878,35 @@
     TEST_ASSERT( ret == 0 );
 
     /* Non-blocking callbacks without timeout */
-    mbedtls_ssl_set_bio( &( ep->ssl ), &( ep->socket ),
-        mbedtls_mock_tcp_send_nb,
-        mbedtls_mock_tcp_recv_nb,
-        NULL );
+    if( dtls_context != NULL )
+    {
+        mbedtls_ssl_set_bio( &( ep->ssl ), dtls_context,
+            mbedtls_mock_tcp_send_msg,
+            mbedtls_mock_tcp_recv_msg,
+            NULL );
+    }
+    else
+    {
+        mbedtls_ssl_set_bio( &( ep->ssl ), &( ep->socket ),
+            mbedtls_mock_tcp_send_nb,
+            mbedtls_mock_tcp_recv_nb,
+            NULL );
+    }
+
+    ret = mbedtls_ssl_config_defaults( &( ep->conf ), endpoint_type,
+                                       ( dtls_context != NULL ) ?
+                                           MBEDTLS_SSL_TRANSPORT_DATAGRAM :
+                                           MBEDTLS_SSL_TRANSPORT_STREAM,
+                                       MBEDTLS_SSL_PRESET_DEFAULT );
+    TEST_ASSERT( ret == 0 );
 
     ret = mbedtls_ssl_setup( &( ep->ssl ), &( ep->conf ) );
     TEST_ASSERT( ret == 0 );
 
-    ret = mbedtls_ssl_config_defaults( &( ep->conf ), endpoint_type,
-                                        MBEDTLS_SSL_TRANSPORT_STREAM,
-                                        MBEDTLS_SSL_PRESET_DEFAULT );
-    TEST_ASSERT( ret == 0 );
+#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_SRV_C)
+    if( endpoint_type == MBEDTLS_SSL_IS_SERVER && dtls_context != NULL )
+         mbedtls_ssl_conf_dtls_cookies( &( ep->conf ), NULL, NULL, NULL );
+#endif
 
     ret = mbedtls_endpoint_certificate_init( ep, pk_alg );
     TEST_ASSERT( ret == 0 );
@@ -823,7 +929,8 @@
 /*
  * Deinitializes endpoint represented by \p ep.
  */
-void mbedtls_endpoint_free( mbedtls_endpoint *ep )
+void mbedtls_endpoint_free( mbedtls_endpoint *ep,
+                            mbedtls_test_message_socket_context *context )
 {
     mbedtls_endpoint_certificate_free( ep );
 
@@ -831,7 +938,15 @@
     mbedtls_ssl_config_free( &( ep->conf ) );
     mbedtls_ctr_drbg_free( &( ep->ctr_drbg ) );
     mbedtls_entropy_free( &( ep->entropy ) );
-    mbedtls_mock_socket_close( &( ep->socket ) );
+
+    if( context != NULL )
+    {
+        mbedtls_message_socket_close( context );
+    }
+    else
+    {
+        mbedtls_mock_socket_close( &( ep->socket ) );
+    }
 }
 
 /*
@@ -885,31 +1000,87 @@
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
 /*
- * Write application data. Then increase write and fragments counter
+ * Write application data. Increase write counter and fragments counter if
+ * necessary.
  */
 int mbedtls_ssl_write_fragment( mbedtls_ssl_context *ssl, unsigned char *buf,
-                                int ln, int *writen, int *fragments )
+                                int buf_len, int *written,
+                                int *fragments, const int expected_fragments )
 {
-    int ret = mbedtls_ssl_write( ssl, buf + *writen, ln - *writen );
-    if( ret >= 0 )
+    int ret = mbedtls_ssl_write( ssl, buf + *written, buf_len - *written );
+    if( ret > 0 )
     {
         (*fragments)++;
-        *writen += ret;
+        *written += ret;
     }
-    return ret;
+
+    if( expected_fragments == 0 )
+    {
+        /* Used for DTLS and the message size larger than MFL. In that case
+         * the message can not be fragmented and the library should return
+         * MBEDTLS_ERR_SSL_BAD_INPUT_DATA error. This error must be returned
+         * to prevent a dead loop inside mbedtls_exchange_data(). */
+        return ret;
+    }
+    else if( expected_fragments == 1 )
+    {
+        /* Used for TLS/DTLS and the message size lower than MFL */
+        TEST_ASSERT( ret == buf_len ||
+                     ret == MBEDTLS_ERR_SSL_WANT_READ ||
+                     ret == MBEDTLS_ERR_SSL_WANT_WRITE );
+    }
+    else
+    {
+        /* Used for TLS and the message size larger than MFL */
+        TEST_ASSERT( expected_fragments > 1 );
+        TEST_ASSERT( ( ret >= 0 && ret <= buf_len ) ||
+                       ret == MBEDTLS_ERR_SSL_WANT_READ ||
+                       ret == MBEDTLS_ERR_SSL_WANT_WRITE );
+    }
+
+    return 0;
+
+exit:
+    /* Some of the tests failed */
+    return -1;
 }
 
 /*
- * Read application data and increase read counter
+ * Read application data and increase read counter if necessary.
  */
-int mbedtls_ssl_read_fragment( mbedtls_ssl_context *ssl, unsigned char *buf, int ln, int *read )
+int mbedtls_ssl_read_fragment( mbedtls_ssl_context *ssl, unsigned char *buf,
+                               int buf_len, int *read,
+                               const int expected_fragments )
 {
-    int ret = mbedtls_ssl_read( ssl, buf + *read, ln - *read );
-    if( ret >= 0 )
+    int ret = mbedtls_ssl_read( ssl, buf + *read, buf_len - *read );
+    if( ret > 0 )
     {
         *read += ret;
     }
-    return ret;
+
+    if( expected_fragments == 0 )
+    {
+        TEST_ASSERT( ret == 0 );
+    }
+    else if( expected_fragments == 1 )
+    {
+        TEST_ASSERT( ret == buf_len ||
+                     ret == MBEDTLS_ERR_SSL_WANT_READ ||
+                     ret == MBEDTLS_ERR_SSL_WANT_WRITE );
+    }
+    else
+    {
+        TEST_ASSERT( expected_fragments > 1 );
+        TEST_ASSERT( ( ret >= 0 && ret <= buf_len ) ||
+                       ret == MBEDTLS_ERR_SSL_WANT_READ ||
+                       ret == MBEDTLS_ERR_SSL_WANT_WRITE );
+    }
+
+    return 0;
+
+exit:
+    /* Some of the tests failed */
+    return -1;
 }
 
 /*
@@ -1304,6 +1475,422 @@
     return( 0 );
 }
 
+/*
+ * Perform data exchanging between \p ssl_1 and \p ssl_2 and check if the
+ * message was sent in the correct number of fragments.
+ *
+ * /p ssl_1 and /p ssl_2    Endpoints represented by mbedtls_ssl_context. Both
+ *                          of them must be initialized and connected beforehand.
+ * /p msg_len_1 and /p msg_len_2 specify the size of the message to send.
+ * /p expected_fragments_1 and /p expected_fragments_2 determine in how many
+ *                          fragments the message should be sent.
+ *      expected_fragments is 0: can be used for DTLS testing while the message
+ *                          size is larger than MFL. In that case the message
+ *                          cannot be fragmented and sent to the second endpoint.
+ *                          This value can be used for negative tests.
+ *      expected_fragments is 1: can be used for TLS/DTLS testing while the
+ *                          message size is below MFL
+ *      expected_fragments > 1: can be used for TLS testing while the message
+ *                          size is larger than MFL
+ *
+ * \retval  0 on success, otherwise error code.
+ */
+int mbedtls_exchange_data( mbedtls_ssl_context *ssl_1,
+                           int msg_len_1, const int expected_fragments_1,
+                           mbedtls_ssl_context *ssl_2,
+                           int msg_len_2, const int expected_fragments_2 )
+{
+    unsigned char *msg_buf_1 = malloc( msg_len_1 );
+    unsigned char *msg_buf_2 = malloc( msg_len_2 );
+    unsigned char *in_buf_1  = malloc( msg_len_2 );
+    unsigned char *in_buf_2  = malloc( msg_len_1 );
+    int msg_type, ret = -1;
+
+    /* Perform this test with two message types. At first use a message
+     * consisting of only 0x00 for the client and only 0xFF for the server.
+     * At the second time use message with generated data */
+    for( msg_type = 0; msg_type < 2; msg_type++ )
+    {
+        int written_1 = 0;
+        int written_2 = 0;
+        int read_1 = 0;
+        int read_2 = 0;
+        int fragments_1 = 0;
+        int fragments_2 = 0;
+
+        if( msg_type == 0 )
+        {
+            memset( msg_buf_1, 0x00, msg_len_1 );
+            memset( msg_buf_2, 0xff, msg_len_2 );
+        }
+        else
+        {
+            int i, j = 0;
+            for( i = 0; i < msg_len_1; i++ )
+            {
+                msg_buf_1[i] = j++ & 0xFF;
+            }
+            for( i = 0; i < msg_len_2; i++ )
+            {
+                msg_buf_2[i] = ( j -= 5 ) & 0xFF;
+            }
+        }
+
+        while( read_1 < msg_len_2 || read_2 < msg_len_1 )
+        {
+            /* ssl_1 sending */
+            if( msg_len_1 > written_1 )
+            {
+                ret = mbedtls_ssl_write_fragment( ssl_1, msg_buf_1,
+                                                  msg_len_1, &written_1,
+                                                  &fragments_1,
+                                                  expected_fragments_1 );
+                if( expected_fragments_1 == 0 )
+                {
+                    /* This error is expected when the message is too large and
+                     * cannot be fragmented */
+                    TEST_ASSERT( ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+                    msg_len_1 = 0;
+                }
+                else
+                {
+                    TEST_ASSERT( ret == 0 );
+                }
+            }
+
+            /* ssl_2 sending */
+            if( msg_len_2 > written_2 )
+            {
+                ret = mbedtls_ssl_write_fragment( ssl_2, msg_buf_2,
+                                                  msg_len_2, &written_2,
+                                                  &fragments_2,
+                                                  expected_fragments_2 );
+                if( expected_fragments_2 == 0 )
+                {
+                    /* This error is expected when the message is too large and
+                     * cannot be fragmented */
+                    TEST_ASSERT( ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+                    msg_len_2 = 0;
+                }
+                else
+                {
+                    TEST_ASSERT( ret == 0 );
+                }
+            }
+
+            /* ssl_1 reading */
+            if( read_1 < msg_len_2 )
+            {
+                ret = mbedtls_ssl_read_fragment( ssl_1, in_buf_1,
+                                                 msg_len_2, &read_1,
+                                                 expected_fragments_1 );
+                TEST_ASSERT( ret == 0 );
+            }
+
+            /* ssl_2 reading */
+            if( read_2 < msg_len_1 )
+            {
+                ret = mbedtls_ssl_read_fragment( ssl_2, in_buf_2,
+                                                 msg_len_1, &read_2,
+                                                 expected_fragments_2 );
+                TEST_ASSERT( ret == 0 );
+            }
+        }
+
+        ret = -1;
+        TEST_ASSERT( 0 == memcmp( msg_buf_1, in_buf_2, msg_len_1 ) );
+        TEST_ASSERT( 0 == memcmp( msg_buf_2, in_buf_1, msg_len_2 ) );
+        TEST_ASSERT( fragments_1 == expected_fragments_1 );
+        TEST_ASSERT( fragments_2 == expected_fragments_2 );
+    }
+
+    ret = 0;
+
+exit:
+    free( msg_buf_1 );
+    free( in_buf_1 );
+    free( msg_buf_2 );
+    free( in_buf_2 );
+
+    return ret;
+}
+
+/*
+ * Perform data exchanging between \p ssl_1 and \p ssl_2. Both of endpoints
+ * must be initialized and connected beforehand.
+ *
+ * \retval  0 on success, otherwise error code.
+ */
+int exchange_data( mbedtls_ssl_context *ssl_1,
+                   mbedtls_ssl_context *ssl_2 )
+{
+    return mbedtls_exchange_data( ssl_1, 256, 1,
+                                  ssl_2, 256, 1 );
+}
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+void perform_handshake( handshake_test_options* options )
+{
+    /* forced_ciphersuite needs to last until the end of the handshake */
+    int forced_ciphersuite[2];
+    enum { BUFFSIZE = 17000 };
+    mbedtls_endpoint client, server;
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    const char *psk_identity = "foo";
+#endif
+#if defined(MBEDTLS_TIMING_C)
+    mbedtls_timing_delay_context timer_client, timer_server;
+#endif
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    unsigned char *context_buf = NULL;
+    size_t context_buf_len;
+#endif
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    int ret = -1;
+#endif
+
+
+    mbedtls_test_message_queue server_queue, client_queue;
+    mbedtls_test_message_socket_context server_context, client_context;
+
+    /* Client side */
+    if( options->dtls != 0 )
+    {
+        TEST_ASSERT( mbedtls_endpoint_init( &client, MBEDTLS_SSL_IS_CLIENT,
+                                            options->pk_alg, &client_context,
+                                            &client_queue,
+                                            &server_queue ) == 0 );
+#if defined(MBEDTLS_TIMING_C)
+        mbedtls_ssl_set_timer_cb( &client.ssl, &timer_client,
+                                  mbedtls_timing_set_delay,
+                                  mbedtls_timing_get_delay );
+#endif
+    }
+    else
+    {
+        TEST_ASSERT( mbedtls_endpoint_init( &client, MBEDTLS_SSL_IS_CLIENT,
+                                            options->pk_alg, NULL, NULL,
+                                            NULL ) == 0 );
+    }
+    mbedtls_ssl_conf_min_version( &client.conf, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                      options->version );
+    mbedtls_ssl_conf_max_version( &client.conf, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                      options->version );
+
+    if( strlen( options->cipher ) > 0 )
+    {
+        set_ciphersuite( &client.conf, options->cipher, forced_ciphersuite );
+    }
+
+#if defined (MBEDTLS_DEBUG_C)
+    if( options->cli_log_fun )
+    {
+        mbedtls_debug_set_threshold( 4 );
+        mbedtls_ssl_conf_dbg( &client.conf, options->cli_log_fun,
+                                            options->cli_log_obj );
+    }
+#endif
+
+    /* Server side */
+    if( options->dtls != 0 )
+    {
+        TEST_ASSERT( mbedtls_endpoint_init( &server, MBEDTLS_SSL_IS_SERVER,
+                                            options->pk_alg, &server_context,
+                                            &server_queue,
+                                            &client_queue) == 0 );
+#if defined(MBEDTLS_TIMING_C)
+        mbedtls_ssl_set_timer_cb( &server.ssl, &timer_server,
+                                  mbedtls_timing_set_delay,
+                                  mbedtls_timing_get_delay );
+#endif
+    }
+    else
+    {
+        TEST_ASSERT( mbedtls_endpoint_init( &server, MBEDTLS_SSL_IS_SERVER,
+                                            options->pk_alg, NULL, NULL, NULL ) == 0 );
+    }
+
+    mbedtls_ssl_conf_authmode( &server.conf, options->srv_auth_mode );
+
+    mbedtls_ssl_conf_min_version( &server.conf, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                      options->version );
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    TEST_ASSERT( mbedtls_ssl_conf_max_frag_len( &(server.conf),
+                                         (unsigned char) options->mfl ) == 0 );
+    TEST_ASSERT( mbedtls_ssl_conf_max_frag_len( &(client.conf),
+                                         (unsigned char) options->mfl ) == 0 );
+#else
+    TEST_ASSERT( MBEDTLS_SSL_MAX_FRAG_LEN_NONE == options->mfl );
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( options->psk_str != NULL && options->psk_str->len > 0 )
+    {
+        TEST_ASSERT( mbedtls_ssl_conf_psk( &client.conf, options->psk_str->x,
+                             options->psk_str->len,
+                             (const unsigned char *) psk_identity,
+                             strlen( psk_identity ) ) == 0 );
+
+        TEST_ASSERT( mbedtls_ssl_conf_psk( &server.conf, options->psk_str->x,
+                             options->psk_str->len,
+                             (const unsigned char *) psk_identity,
+                             strlen( psk_identity ) ) == 0 );
+
+        mbedtls_ssl_conf_psk_cb( &server.conf, psk_dummy_callback, NULL );
+    }
+#endif
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( options->renegotiate )
+    {
+        mbedtls_ssl_conf_renegotiation( &(server.conf),
+                                        MBEDTLS_SSL_RENEGOTIATION_ENABLED );
+        mbedtls_ssl_conf_renegotiation( &(client.conf),
+                                        MBEDTLS_SSL_RENEGOTIATION_ENABLED );
+
+        mbedtls_ssl_conf_legacy_renegotiation( &(server.conf),
+                                               options->legacy_renegotiation );
+        mbedtls_ssl_conf_legacy_renegotiation( &(client.conf),
+                                               options->legacy_renegotiation );
+    }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+#if defined (MBEDTLS_DEBUG_C)
+    if( options->srv_log_fun )
+    {
+        mbedtls_debug_set_threshold( 4 );
+        mbedtls_ssl_conf_dbg( &server.conf, options->srv_log_fun,
+                                            options->srv_log_obj );
+    }
+#endif
+
+    TEST_ASSERT( mbedtls_mock_socket_connect( &(client.socket),
+                                              &(server.socket),
+                                              BUFFSIZE ) == 0 );
+
+    TEST_ASSERT( mbedtls_move_handshake_to_state( &(client.ssl),
+                                                  &(server.ssl),
+                                                  MBEDTLS_SSL_HANDSHAKE_OVER )
+                 == 0 );
+    TEST_ASSERT( client.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER );
+    TEST_ASSERT( server.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER );
+
+    if( options->cli_msg_len != 0 || options->srv_msg_len != 0 )
+    {
+        /* Start data exchanging test */
+        TEST_ASSERT( mbedtls_exchange_data( &(client.ssl), options->cli_msg_len,
+                                            options->expected_cli_fragments,
+                                            &(server.ssl), options->srv_msg_len,
+                                            options->expected_srv_fragments )
+                     == 0 );
+    }
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( options->serialize == 1 )
+    {
+        TEST_ASSERT( options->dtls == 1 );
+
+        TEST_ASSERT( mbedtls_ssl_context_save( &(server.ssl), NULL,
+                                               0, &context_buf_len )
+                                             == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+        context_buf = mbedtls_calloc( 1, context_buf_len );
+        TEST_ASSERT( context_buf != NULL );
+
+        TEST_ASSERT( mbedtls_ssl_context_save( &(server.ssl), context_buf,
+                                               context_buf_len,
+                                               &context_buf_len ) == 0 );
+
+        mbedtls_ssl_free( &(server.ssl) );
+        mbedtls_ssl_init( &(server.ssl) );
+
+        TEST_ASSERT( mbedtls_ssl_setup( &(server.ssl), &(server.conf) ) == 0 );
+
+        mbedtls_ssl_set_bio( &( server.ssl ), &server_context,
+                             mbedtls_mock_tcp_send_msg,
+                             mbedtls_mock_tcp_recv_msg,
+                             NULL );
+
+#if defined(MBEDTLS_TIMING_C)
+        mbedtls_ssl_set_timer_cb( &server.ssl, &timer_server,
+                                  mbedtls_timing_set_delay,
+                                  mbedtls_timing_get_delay );
+#endif
+        TEST_ASSERT( mbedtls_ssl_context_load( &( server.ssl ), context_buf,
+                                               context_buf_len ) == 0 );
+
+        /* Retest writing/reading */
+        if( options->cli_msg_len != 0 || options->srv_msg_len != 0 )
+        {
+            TEST_ASSERT( mbedtls_exchange_data( &(client.ssl),
+                                                options->cli_msg_len,
+                                                options->expected_cli_fragments,
+                                                &(server.ssl),
+                                                options->srv_msg_len,
+                                                options->expected_srv_fragments )
+                                                == 0 );
+        }
+    }
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( options->renegotiate )
+    {
+        /* Start test with renegotiation */
+        TEST_ASSERT( server.ssl.renego_status ==
+                     MBEDTLS_SSL_INITIAL_HANDSHAKE );
+        TEST_ASSERT( client.ssl.renego_status ==
+                     MBEDTLS_SSL_INITIAL_HANDSHAKE );
+
+        /* After calling this function for the server, it only sends a handshake
+         * request. All renegotiation should happen during data exchanging */
+        TEST_ASSERT( mbedtls_ssl_renegotiate( &(server.ssl) ) == 0 );
+        TEST_ASSERT( server.ssl.renego_status ==
+                     MBEDTLS_SSL_RENEGOTIATION_PENDING );
+        TEST_ASSERT( client.ssl.renego_status ==
+                     MBEDTLS_SSL_INITIAL_HANDSHAKE );
+
+        TEST_ASSERT( exchange_data( &(client.ssl), &(server.ssl) ) == 0 );
+        TEST_ASSERT( server.ssl.renego_status ==
+                     MBEDTLS_SSL_RENEGOTIATION_DONE );
+        TEST_ASSERT( client.ssl.renego_status ==
+                     MBEDTLS_SSL_RENEGOTIATION_DONE );
+
+        /* After calling mbedtls_ssl_renegotiate for the client all renegotiation
+         * should happen inside this function. However in this test, we cannot
+         * perform simultaneous communication betwen client and server so this
+         * function will return waiting error on the socket. All rest of
+         * renegotiation should happen during data exchanging */
+        ret = mbedtls_ssl_renegotiate( &(client.ssl) );
+        TEST_ASSERT( ret == 0 ||
+                     ret == MBEDTLS_ERR_SSL_WANT_READ ||
+                     ret == MBEDTLS_ERR_SSL_WANT_WRITE );
+        TEST_ASSERT( server.ssl.renego_status ==
+                     MBEDTLS_SSL_RENEGOTIATION_DONE );
+        TEST_ASSERT( client.ssl.renego_status ==
+                     MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS );
+
+        TEST_ASSERT( exchange_data( &(client.ssl), &(server.ssl) ) == 0 );
+        TEST_ASSERT( server.ssl.renego_status ==
+                     MBEDTLS_SSL_RENEGOTIATION_DONE );
+        TEST_ASSERT( client.ssl.renego_status ==
+                     MBEDTLS_SSL_RENEGOTIATION_DONE );
+    }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+exit:
+    mbedtls_endpoint_free( &client, options->dtls != 0 ? &client_context : NULL );
+    mbedtls_endpoint_free( &server, options->dtls != 0 ? &server_context : NULL );
+#if defined (MBEDTLS_DEBUG_C)
+    if( options->cli_log_fun || options->srv_log_fun )
+    {
+        mbedtls_debug_set_threshold( 0 );
+    }
+#endif
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( context_buf != NULL )
+        mbedtls_free( context_buf );
+#endif
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -1841,14 +2428,14 @@
     TEST_ASSERT( mbedtls_test_message_queue_push_info( &queue, 1 ) == 1 );
     TEST_ASSERT( mbedtls_test_message_queue_push_info( &queue, 2 ) == 2 );
     TEST_ASSERT( mbedtls_test_message_queue_push_info( &queue, 3 )
-                 == MBEDTLS_TEST_ERROR_QUEUE_FULL );
+                 == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     TEST_ASSERT( mbedtls_test_message_queue_pop_info( &queue, 1 ) == 1 );
     TEST_ASSERT( mbedtls_test_message_queue_pop_info( &queue, 1 ) == 1 );
     TEST_ASSERT( mbedtls_test_message_queue_pop_info( &queue, 2 ) == 2 );
 
     TEST_ASSERT( mbedtls_test_message_queue_pop_info( &queue, 1 )
-                 == MBEDTLS_TEST_ERROR_QUEUE_EMPTY );
+                 == MBEDTLS_ERR_SSL_WANT_READ );
 
 exit:
     mbedtls_test_message_queue_free( &queue );
@@ -1936,7 +2523,7 @@
                  == MBEDTLS_TEST_ERROR_SEND_FAILED );
 
     TEST_ASSERT( mbedtls_mock_tcp_recv_msg( &server_context, received, MSGLEN )
-                 == MBEDTLS_TEST_ERROR_QUEUE_EMPTY );
+                 == MBEDTLS_ERR_SSL_WANT_READ );
 
     /* Push directly to a queue to later simulate a disconnected behavior */
     TEST_ASSERT( mbedtls_test_message_queue_push_info( &server_queue, MSGLEN )
@@ -2041,7 +2628,7 @@
 
     TEST_ASSERT( mbedtls_mock_tcp_send_msg( &client_context, message,
                                             MSGLEN )
-                 == MBEDTLS_TEST_ERROR_QUEUE_FULL );
+                 == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     /* Read three messages from the server, last one with an error */
     TEST_ASSERT( mbedtls_mock_tcp_recv_msg( &server_context, received,
@@ -2053,7 +2640,7 @@
     TEST_ASSERT( memcmp( message, received, MSGLEN ) == 0 );
 
     TEST_ASSERT( mbedtls_mock_tcp_recv_msg( &server_context, received, MSGLEN )
-                 == MBEDTLS_TEST_ERROR_QUEUE_EMPTY );
+                 == MBEDTLS_ERR_SSL_WANT_READ );
 
     exit:
     mbedtls_message_socket_close( &server_context );
@@ -2268,7 +2855,7 @@
         TEST_ASSERT( memcmp( message, received, MSGLEN ) == 0 );
     }
     TEST_ASSERT( mbedtls_mock_tcp_recv_msg( &server_context, received, MSGLEN )
-                 == MBEDTLS_TEST_ERROR_QUEUE_EMPTY );
+                 == MBEDTLS_ERR_SSL_WANT_READ );
     exit:
     mbedtls_message_socket_close( &server_context );
     mbedtls_message_socket_close( &client_context );
@@ -2349,10 +2936,10 @@
     }
 
     TEST_ASSERT( mbedtls_mock_tcp_recv_msg( &server_context, received, MSGLEN )
-                 == MBEDTLS_TEST_ERROR_QUEUE_EMPTY );
+                 == MBEDTLS_ERR_SSL_WANT_READ );
 
     TEST_ASSERT( mbedtls_mock_tcp_recv_msg( &client_context, received, MSGLEN )
-                 == MBEDTLS_TEST_ERROR_QUEUE_EMPTY );
+                 == MBEDTLS_ERR_SSL_WANT_READ );
     exit:
     mbedtls_message_socket_close( &server_context );
     mbedtls_message_socket_close( &client_context );
@@ -2990,17 +3577,19 @@
     mbedtls_endpoint ep;
     int ret = -1;
 
-    ret = mbedtls_endpoint_init( NULL, endpoint_type, MBEDTLS_PK_RSA );
+    ret = mbedtls_endpoint_init( NULL, endpoint_type, MBEDTLS_PK_RSA,
+                                 NULL, NULL, NULL );
     TEST_ASSERT( MBEDTLS_ERR_SSL_BAD_INPUT_DATA == ret );
 
     ret = mbedtls_endpoint_certificate_init( NULL, MBEDTLS_PK_RSA );
     TEST_ASSERT( MBEDTLS_ERR_SSL_BAD_INPUT_DATA == ret );
 
-    ret = mbedtls_endpoint_init( &ep, endpoint_type, MBEDTLS_PK_RSA );
+    ret = mbedtls_endpoint_init( &ep, endpoint_type, MBEDTLS_PK_RSA,
+                                 NULL, NULL, NULL );
     TEST_ASSERT( ret == 0 );
 
 exit:
-    mbedtls_endpoint_free( &ep );
+    mbedtls_endpoint_free( &ep, NULL );
 }
 /* END_CASE */
 
@@ -3011,13 +3600,14 @@
     mbedtls_endpoint base_ep, second_ep;
     int ret = -1;
 
-    ret = mbedtls_endpoint_init( &base_ep, endpoint_type, MBEDTLS_PK_RSA );
+    ret = mbedtls_endpoint_init( &base_ep, endpoint_type, MBEDTLS_PK_RSA,
+                                 NULL, NULL, NULL );
     TEST_ASSERT( ret == 0 );
 
     ret = mbedtls_endpoint_init( &second_ep,
                             ( endpoint_type == MBEDTLS_SSL_IS_SERVER ) ?
                             MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
-                                 MBEDTLS_PK_RSA );
+                                 MBEDTLS_PK_RSA, NULL, NULL, NULL );
     TEST_ASSERT( ret == 0 );
 
     ret = mbedtls_mock_socket_connect( &(base_ep.socket),
@@ -3040,193 +3630,168 @@
     }
 
 exit:
-    mbedtls_endpoint_free( &base_ep );
-    mbedtls_endpoint_free( &second_ep );
+    mbedtls_endpoint_free( &base_ep, NULL );
+    mbedtls_endpoint_free( &second_ep, NULL );
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15 */
-void handshake( const char *cipher, int version, int pk_alg,
-                data_t *psk_str )
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+void handshake_version( int version, int dtls )
 {
-    /* forced_ciphersuite needs to last until the end of the handshake */
-    int forced_ciphersuite[2];
-    enum { BUFFSIZE = 1024 };
-    mbedtls_endpoint client, server;
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    const char *psk_identity = "foo";
-#else
-    (void) psk_str;
-#endif
-    /* Client side */
-    TEST_ASSERT( mbedtls_endpoint_init( &client, MBEDTLS_SSL_IS_CLIENT,
-                                 pk_alg ) == 0 );
+    handshake_test_options options;
+    init_handshake_options( &options );
 
-    mbedtls_ssl_conf_min_version( &client.conf, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                      version );
-    mbedtls_ssl_conf_max_version( &client.conf, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                      version );
-
-    if( strlen( cipher ) > 0 )
+    options.version = version;
+    options.dtls = dtls;
+    /* Note - the case below will have to updated, since the test sends no data
+     * due to a 1n-1 split against BEAST, that was not expected when preparing
+     * the fragment counting code. */
+    if( version == MBEDTLS_SSL_MINOR_VERSION_0 ||
+        version == MBEDTLS_SSL_MINOR_VERSION_1 )
     {
-        set_ciphersuite( &client.conf, cipher, forced_ciphersuite );
+        options.cli_msg_len = 0;
+        options.srv_msg_len = 0;
     }
-    /* Server side */
-    TEST_ASSERT( mbedtls_endpoint_init( &server, MBEDTLS_SSL_IS_SERVER,
-                                 pk_alg ) == 0 );
+    perform_handshake( &options );
 
-    mbedtls_ssl_conf_min_version( &server.conf, MBEDTLS_SSL_MAJOR_VERSION_3,
-                                      version );
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    if( psk_str->len > 0 )
-    {
-        TEST_ASSERT( mbedtls_ssl_conf_psk( &client.conf, psk_str->x,
-                             psk_str->len,
-                             (const unsigned char *) psk_identity,
-                             strlen( psk_identity ) ) == 0 );
-
-        TEST_ASSERT( mbedtls_ssl_conf_psk( &server.conf, psk_str->x,
-                             psk_str->len,
-                             (const unsigned char *) psk_identity,
-                             strlen( psk_identity ) ) == 0 );
-
-        mbedtls_ssl_conf_psk_cb( &server.conf, psk_dummy_callback, NULL );
-    }
-#endif
-    TEST_ASSERT( mbedtls_mock_socket_connect( &(client.socket),
-                                              &(server.socket),
-                                              BUFFSIZE ) == 0 );
-
-    TEST_ASSERT( mbedtls_move_handshake_to_state( &(client.ssl),
-                                                  &(server.ssl),
-                                                  MBEDTLS_SSL_HANDSHAKE_OVER )
-                 == 0 );
-    TEST_ASSERT( client.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER );
-    TEST_ASSERT( server.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER );
-
-exit:
-    mbedtls_endpoint_free( &client );
-    mbedtls_endpoint_free( &server );
+    /* The goto below is used to avoid an "unused label" warning.*/
+    goto exit;
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15 */
-void send_application_data( int mfl, int cli_msg_len, int srv_msg_len,
-                            const int expected_cli_frames,
-                            const int expected_srv_frames )
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2 */
+void handshake_psk_cipher( char* cipher, int pk_alg, data_t *psk_str, int dtls )
 {
-    enum { BUFFSIZE = 2048 };
-    mbedtls_endpoint server, client;
-    unsigned char *cli_msg_buf = malloc( cli_msg_len );
-    unsigned char *cli_in_buf  = malloc( srv_msg_len );
-    unsigned char *srv_msg_buf = malloc( srv_msg_len );
-    unsigned char *srv_in_buf  = malloc( cli_msg_len );
-    int ret = -1;
+    handshake_test_options options;
+    init_handshake_options( &options );
 
-    ret = mbedtls_endpoint_init( &server, MBEDTLS_SSL_IS_SERVER, MBEDTLS_PK_RSA );
-    TEST_ASSERT( ret == 0 );
+    options.cipher = cipher;
+    options.dtls = dtls;
+    options.psk_str = psk_str;
+    options.pk_alg = pk_alg;
 
-    ret = mbedtls_endpoint_init( &client, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_PK_RSA );
-    TEST_ASSERT( ret == 0 );
+    perform_handshake( &options );
 
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-    ret = mbedtls_ssl_conf_max_frag_len( &(server.conf), (unsigned char) mfl );
-    TEST_ASSERT( ret == 0 );
+    /* The goto below is used to avoid an "unused label" warning.*/
+    goto exit;
+}
+/* END_CASE */
 
-    ret = mbedtls_ssl_conf_max_frag_len( &(client.conf), (unsigned char) mfl );
-    TEST_ASSERT( ret == 0 );
-#else
-    TEST_ASSERT( MBEDTLS_SSL_MAX_FRAG_LEN_NONE == mfl );
-#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2 */
+void handshake_cipher( char* cipher, int pk_alg, int dtls )
+{
+    test_handshake_psk_cipher( cipher, pk_alg, NULL, dtls );
 
-    ret = mbedtls_mock_socket_connect( &(server.socket), &(client.socket),
-                                       BUFFSIZE );
-    TEST_ASSERT( ret == 0 );
+    /* The goto below is used to avoid an "unused label" warning.*/
+    goto exit;
+}
+/* END_CASE */
 
-    ret = mbedtls_move_handshake_to_state( &(client.ssl),
-                                           &(server.ssl),
-                                           MBEDTLS_SSL_HANDSHAKE_OVER );
-    TEST_ASSERT( ret == 0 );
-    TEST_ASSERT( client.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER );
-    TEST_ASSERT( server.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER );
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+void app_data( int mfl, int cli_msg_len, int srv_msg_len,
+               int expected_cli_fragments,
+               int expected_srv_fragments, int dtls )
+{
+    handshake_test_options options;
+    init_handshake_options( &options );
 
-    /* Perform this test with two message types. At first use a message
-     * consisting of only 0x00 for the client and only 0xFF for the server.
-     * At the second time use message with generated data */
-    for( int msg_type = 0; msg_type < 2; msg_type++ )
+    options.mfl = mfl;
+    options.cli_msg_len = cli_msg_len;
+    options.srv_msg_len = srv_msg_len;
+    options.expected_cli_fragments = expected_cli_fragments;
+    options.expected_srv_fragments = expected_srv_fragments;
+    options.dtls = dtls;
+
+    perform_handshake( &options );
+    /* The goto below is used to avoid an "unused label" warning.*/
+    goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+void app_data_tls( int mfl, int cli_msg_len, int srv_msg_len,
+                   int expected_cli_fragments,
+                   int expected_srv_fragments )
+{
+    test_app_data( mfl, cli_msg_len, srv_msg_len, expected_cli_fragments,
+                   expected_srv_fragments, 0 );
+    /* The goto below is used to avoid an "unused label" warning.*/
+    goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS */
+void app_data_dtls( int mfl, int cli_msg_len, int srv_msg_len,
+                    int expected_cli_fragments,
+                    int expected_srv_fragments )
+{
+    test_app_data( mfl, cli_msg_len, srv_msg_len, expected_cli_fragments,
+                   expected_srv_fragments, 1 );
+    /* The goto below is used to avoid an "unused label" warning.*/
+    goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_SSL_CONTEXT_SERIALIZATION */
+void handshake_serialization( )
+{
+    handshake_test_options options;
+    init_handshake_options( &options );
+
+    options.serialize = 1;
+    options.dtls = 1;
+    perform_handshake( &options );
+    /* The goto below is used to avoid an "unused label" warning.*/
+    goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_DEBUG_C:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+void handshake_fragmentation( int mfl, int expected_srv_hs_fragmentation, int expected_cli_hs_fragmentation)
+{
+    handshake_test_options options;
+    log_pattern srv_pattern, cli_pattern;
+
+    srv_pattern.pattern = cli_pattern.pattern = "found fragmented DTLS handshake";
+    srv_pattern.counter = 0;
+    cli_pattern.counter = 0;
+
+    init_handshake_options( &options );
+    options.dtls = 1;
+    options.mfl = mfl;
+    options.srv_auth_mode = MBEDTLS_SSL_VERIFY_REQUIRED;
+    options.srv_log_obj = &srv_pattern;
+    options.cli_log_obj = &cli_pattern;
+    options.srv_log_fun = log_analyzer;
+    options.cli_log_fun = log_analyzer;
+
+    perform_handshake( &options );
+
+    /* Test if the server received a fragmented handshake */
+    if( expected_srv_hs_fragmentation )
     {
-        int cli_writen = 0;
-        int srv_writen = 0;
-        int cli_read = 0;
-        int srv_read = 0;
-        int cli_fragments = 0;
-        int srv_fragments = 0;
-
-        if( msg_type == 0 )
-        {
-            memset( cli_msg_buf, 0x00, cli_msg_len );
-            memset( srv_msg_buf, 0xff, srv_msg_len );
-        }
-        else
-        {
-            int j = 0;
-            for( int i = 0; i < cli_msg_len; i++ )
-                cli_msg_buf[i] = j++ & 0xFF;
-            for( int i = 0; i < srv_msg_len; i++ )
-                srv_msg_buf[i] = ( j -= 5 ) & 0xFF;
-        }
-
-        while( cli_read < srv_msg_len || srv_read < cli_msg_len )
-        {
-            /* Client sending */
-            if( cli_msg_len > cli_writen )
-            {
-                ret = mbedtls_ssl_write_fragment( &(client.ssl), cli_msg_buf,
-                                    cli_msg_len, &cli_writen, &cli_fragments );
-                TEST_ASSERT( ( ret >= 0 && ret <= cli_msg_len ) ||
-                               ret == MBEDTLS_ERR_SSL_WANT_WRITE );
-            }
-
-            /* Server sending */
-            if( srv_msg_len > srv_writen )
-            {
-                ret = mbedtls_ssl_write_fragment( &(server.ssl), srv_msg_buf,
-                                    srv_msg_len, &srv_writen, &srv_fragments );
-                TEST_ASSERT( ( ret >= 0 && ret <= srv_msg_len ) ||
-                               ret == MBEDTLS_ERR_SSL_WANT_WRITE );
-            }
-
-            /* Client reading */
-            if( cli_read < srv_msg_len )
-            {
-                ret = mbedtls_ssl_read_fragment( &(client.ssl), cli_in_buf,
-                                                    srv_msg_len, &cli_read );
-                TEST_ASSERT( ( ret >= 0 && ret <= srv_msg_len ) ||
-                               ret == MBEDTLS_ERR_SSL_WANT_READ );
-            }
-
-            /* Server reading */
-            if( srv_read < cli_msg_len )
-            {
-                ret = mbedtls_ssl_read_fragment( &(server.ssl), srv_in_buf,
-                                                    cli_msg_len, &srv_read );
-                TEST_ASSERT( ( ret >= 0 && ret <= cli_msg_len ) ||
-                               ret == MBEDTLS_ERR_SSL_WANT_READ );
-            }
-        }
-
-        TEST_ASSERT( 0 == memcmp( cli_msg_buf, srv_in_buf, cli_msg_len ) );
-        TEST_ASSERT( 0 == memcmp( srv_msg_buf, cli_in_buf, srv_msg_len ) );
-        TEST_ASSERT( cli_fragments == expected_cli_frames );
-        TEST_ASSERT( srv_fragments == expected_srv_frames );
+        TEST_ASSERT( srv_pattern.counter >= 1 );
     }
+    /* Test if the client received a fragmented handshake */
+    if( expected_cli_hs_fragmentation )
+    {
+        TEST_ASSERT( cli_pattern.counter >= 1 );
+    }
+}
+/* END_CASE */
 
-exit:
-    mbedtls_endpoint_free( &client );
-    mbedtls_endpoint_free( &server );
-    free( cli_msg_buf );
-    free( cli_in_buf );
-    free( srv_msg_buf );
-    free( srv_in_buf );
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION */
+void renegotiation( int legacy_renegotiation )
+{
+    handshake_test_options options;
+    init_handshake_options( &options );
+
+    options.renegotiate = 1;
+    options.legacy_renegotiation = legacy_renegotiation;
+    options.dtls = 1;
+
+    perform_handshake( &options );
+    /* The goto below is used to avoid an "unused label" warning.*/
+    goto exit;
 }
 /* END_CASE */
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index ff0612b..868fe06 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compiletime library version
-check_compiletime_version:"2.20.0"
+check_compiletime_version:"2.21.0"
 
 Check runtime library version
-check_runtime_version:"2.20.0"
+check_runtime_version:"2.21.0"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0
diff --git a/visualc/VS2010/query_compile_time_config.vcxproj b/visualc/VS2010/query_compile_time_config.vcxproj
index bb2f7ad..112fea8 100644
--- a/visualc/VS2010/query_compile_time_config.vcxproj
+++ b/visualc/VS2010/query_compile_time_config.vcxproj
@@ -20,7 +20,7 @@
   </ItemGroup>

   <ItemGroup>

     <ClCompile Include="..\..\programs\test\query_compile_time_config.c" />

-    <ClCompile Include="..\..\programs\ssl\query_config.c" />

+    <ClCompile Include="..\..\programs\test\query_config.c" />

   </ItemGroup>

   <ItemGroup>

     <ProjectReference Include="mbedTLS.vcxproj">
diff --git a/visualc/VS2010/ssl_client2.vcxproj b/visualc/VS2010/ssl_client2.vcxproj
index dd922c0..f23f9a1 100644
--- a/visualc/VS2010/ssl_client2.vcxproj
+++ b/visualc/VS2010/ssl_client2.vcxproj
@@ -20,7 +20,7 @@
   </ItemGroup>

   <ItemGroup>

     <ClCompile Include="..\..\programs\ssl\ssl_client2.c" />

-    <ClCompile Include="..\..\programs\ssl\query_config.c" />

+    <ClCompile Include="..\..\programs\test\query_config.c" />

   </ItemGroup>

   <ItemGroup>

     <ProjectReference Include="mbedTLS.vcxproj">
diff --git a/visualc/VS2010/ssl_server2.vcxproj b/visualc/VS2010/ssl_server2.vcxproj
index d4629bd..df1ee28 100644
--- a/visualc/VS2010/ssl_server2.vcxproj
+++ b/visualc/VS2010/ssl_server2.vcxproj
@@ -20,7 +20,7 @@
   </ItemGroup>

   <ItemGroup>

     <ClCompile Include="..\..\programs\ssl\ssl_server2.c" />

-    <ClCompile Include="..\..\programs\ssl\query_config.c" />

+    <ClCompile Include="..\..\programs\test\query_config.c" />

   </ItemGroup>

   <ItemGroup>

     <ProjectReference Include="mbedTLS.vcxproj">