Merge pull request #616 from mpg/context-s11n

[baremetal] Implement context serialization
diff --git a/configs/baremetal.h b/configs/baremetal.h
index a88f8ac..9929d56 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -60,6 +60,9 @@
 #define MBEDTLS_SSL_CONF_SINGLE_EC
 #define MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID MBEDTLS_ECP_DP_SECP256R1
 #define MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID 23
+#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH
+#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID MBEDTLS_MD_SHA256
+#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID MBEDTLS_SSL_HASH_SHA256
 
 /* Key exchanges */
 #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
@@ -119,6 +122,8 @@
 #define MBEDTLS_X509_CHECK_KEY_USAGE
 #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
 #define MBEDTLS_X509_REMOVE_INFO
+#define MBEDTLS_X509_CRT_REMOVE_TIME
+#define MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID
 #define MBEDTLS_X509_ON_DEMAND_PARSING
 #define MBEDTLS_X509_ALWAYS_FLUSH
 #define MBEDTLS_ASN1_PARSE_C
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 93831b7..29e61db 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -93,6 +93,12 @@
 #error "MBEDTLS_SSL_CONF_SINGLE_EC defined, but not all prerequesites"
 #endif
 
+#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH) &&           \
+    ( !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID) || \
+      !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID) )
+#error "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH defined, but not all prerequesites"
+#endif
+
 #if defined(MBEDTLS_USE_TINYCRYPT) && defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
 #error "MBEDTLS_USE_TINYCRYPT defined, but it cannot be defined with MBEDTLS_NO_64BIT_MULTIPLICATION"
 #endif
@@ -787,6 +793,11 @@
 #error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_X509_CRT_REMOVE_TIME) && \
+    defined(MBEDTLS_HAVE_TIME_DATE)
+#error "MBEDTLS_X509_CRT_REMOVE_TIME and MBEDTLS_HAVE_TIME_DATE cannot be defined simultaneously"
+#endif
+
 #if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64)
 #error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously"
 #endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 5b17238..f8a99f2 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1943,6 +1943,29 @@
 //#define MBEDTLS_X509_REMOVE_INFO
 
 /**
+ * \def MBEDTLS_X509_CRT_REMOVE_TIME
+ *
+ * Don't store time validity fields in X.509 certificate structures.
+ *
+ * Uncomment this to save some code and RAM on constrained systems which
+ * don't have time and where there's no use of the time validity fields
+ * in a certificate.
+ *
+ * Requires: !MBEDTLS_HAVE_TIME_DATE
+ */
+//#define MBEDTLS_X509_CRT_REMOVE_TIME
+
+/**
+ * \def MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID
+ *
+ * Don't store subject and issuer ID in X.509 certificate structures.
+ *
+ * Uncomment this to save some code and RAM on constrained systems which
+ * don't need to inspect issuer and subject ID fields in certificates.
+ */
+//#define MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID
+
+/**
  * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT
  *
  * Enable parsing and verification of X.509 certificates, CRLs and CSRS
@@ -3670,7 +3693,7 @@
  * If this is set, you must also define the following:
  * - MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID
  *   This must resolve to the Mbed TLS group ID for the elliptic
- *   curve to use (e.g. MBEDTLS_ECP_DP_SECP256R1_ENABLED); see
+ *   curve to use (e.g. MBEDTLS_ECP_DP_SECP256R1); see
  *   ::mbedtls_ecp_group_id in mbedtls/ecp.h for a complete list
  *   of curve identifiers.
  * - MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID
@@ -3682,8 +3705,36 @@
  * runtime configuration API mbedtls_ssl_conf_curves().
  */
 //#define MBEDTLS_SSL_CONF_SINGLE_EC
-//#define MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID
-//#define MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID
+//#define MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID 23
+//#define MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID MBEDTLS_ECP_DP_SECP256R1
+
+/* Enable support a single signature hash algorithm
+ * at compile-time, at the benefit of code-size.
+ *
+ * On highly constrained systems with large control
+ * over the configuration of the connection endpoints,
+ * this option can be used to hardcode the choice of
+ * hash algorithm to be used for signatures in the
+ * ServerKeyExchange and CertificateVerify messages.
+ *
+ * If this is set, you must also define the following:
+ * - MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID
+ *   This must resolve to the Mbed TLS hash ID for the hash
+ *   algorithm to use (e.g. MBEDTLS_MD_SHA256). See
+ *   ::mbedtls_md_type_t in mbedtls/md.h for a complete
+ *   list of supported hash algorithm identifiers.
+ * - MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID
+ *   This must resolve to the TLS identifier for the hash
+ *   algorithm to use. See
+ *   https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+ *   for a list of the supported identifiers.
+ *
+ * If defined, this option overwrites the effect of the
+ * runtime configuration API mbedtls_ssl_conf_sig_hashes().
+ */
+//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH
+//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID
+//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID
 
 /* \} SECTION: Compile-time SSL configuration */
 
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 33a6aa1..9e5fb2d 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -366,6 +366,7 @@
 #define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME    112  /* 0x70 */
 #define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115  /* 0x73 */
 #define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */
+#define MBEDTLS_SSL_ALERT_MSG_NONE                 255  /* internal */
 
 #define MBEDTLS_SSL_HS_HELLO_REQUEST            0
 #define MBEDTLS_SSL_HS_CLIENT_HELLO             1
@@ -1078,7 +1079,9 @@
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 
 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH)
     const int *sig_hashes;          /*!< allowed signature hashes           */
+#endif /* !MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */
 #endif
 
 #if defined(MBEDTLS_ECP_C)
@@ -1232,6 +1235,9 @@
 {
     const mbedtls_ssl_config *conf; /*!< configuration information          */
 
+    unsigned char pending_fatal_alert_msg; /*!< Type of a fatal alert
+                                            *   pending to be delivered.    */
+
     /*
      * Miscellaneous
      */
@@ -2863,6 +2869,10 @@
  * \note           This list should be ordered by decreasing preference
  *                 (preferred hash first).
  *
+ * \note           On highly constrained systems, the support for a single
+ *                 fixed signature hash algorithm can be configured at compile
+ *                 time through the option MBEDTLS_SSL_CONF_SINGLE_SIG_HASH.
+ *
  * \param conf     SSL configuration
  * \param hashes   Ordered list of allowed signature hashes,
  *                 terminated by \c MBEDTLS_MD_NONE.
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 0991926..9b8e21f 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1708,4 +1708,76 @@
 
 #endif /* MBEDTLS_SSL_CONF_SINGLE_EC */
 
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH)
+
+#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( MD_VAR )    \
+    {                                                                   \
+        int const *__md;                                                \
+        for( __md = ssl->conf->sig_hashes;                              \
+             *__md != MBEDTLS_MD_NONE; __md++ )                         \
+        {                                                               \
+            mbedtls_md_type_t MD_VAR = (mbedtls_md_type_t) *__md;       \
+
+ #define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH                              \
+        }                                                               \
+    }
+
+#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( HASH_VAR )             \
+    {                                                                   \
+        int const *__md;                                                \
+        for( __md = ssl->conf->sig_hashes;                              \
+             *__md != MBEDTLS_MD_NONE; __md++ )                         \
+        {                                                               \
+            unsigned char HASH_VAR;                                     \
+            HASH_VAR = mbedtls_ssl_hash_from_md_alg( *__md );
+
+#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS                           \
+        }                                                               \
+    }
+
+#else /* !MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */
+
+#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( MD_VAR )                   \
+    {                                                                   \
+        mbedtls_md_type_t MD_VAR = MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID; \
+        ((void) ssl);
+
+#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH                               \
+    }
+
+#define MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( HASH_VAR )                \
+    {                                                                      \
+        unsigned char HASH_VAR = MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID;  \
+        ((void) ssl);
+
+
+#define MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS                           \
+    }
+
+#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */
+
+#if defined(__GNUC__) || defined(__arm__)
+#define MBEDTLS_ALWAYS_INLINE __attribute__((always_inline))
+#else
+#define MBEDTLS_ALWAYS_INLINE
+#endif
+
+/* This internal function can be used to pend a fatal alert for
+ * later delivery.
+ *
+ * The check for pending alerts must be done by calling
+ * the function ssl_send_pending_fatal_alert() in ssl_tls.c.
+ * Currently, it happens only during the handshake loop and after
+ * calling ssl_get_next_record() in the record processing stack.
+ *
+ * This function must not be called multiple times without
+ * sending the pending fatal alerts in between.
+ */
+MBEDTLS_ALWAYS_INLINE static inline void mbedtls_ssl_pend_fatal_alert(
+    mbedtls_ssl_context *ssl,
+    unsigned char message )
+{
+    ssl->pending_fatal_alert_msg = message;
+}
+
 #endif /* ssl_internal.h */
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index b69dd71..c31847d 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -250,6 +250,7 @@
  */
 int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial );
 
+#if defined(MBEDTLS_HAVE_TIME_DATE)
 /**
  * \brief          Check a given mbedtls_x509_time against the system time
  *                 and tell if it's in the past.
@@ -277,6 +278,7 @@
  *                 0 otherwise.
  */
 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
 /**
  * \brief          Free a dynamic linked list presentation of an X.509 name
@@ -301,6 +303,20 @@
     mbedtls_asn1_sequence_free( (mbedtls_asn1_sequence*) seq );
 }
 
+#if !defined(MBEDTLS_HAVE_TIME_DATE)
+static inline int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
+{
+    ((void) to);
+    return( 0 );
+}
+
+static inline int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
+{
+    ((void) from);
+    return( 0 );
+}
+#endif /* !MBEDTLS_HAVE_TIME_DATE */
+
 #if defined(MBEDTLS_SELF_TEST)
 
 /**
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 3eee460..c8f488c 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -70,8 +70,10 @@
     uint32_t ext_types;                     /**< Bitfield indicating which extensions are present.
                                              *   See the values in x509.h.                                      */
 
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
     mbedtls_x509_time valid_from;           /**< The start time of certificate validity.                        */
     mbedtls_x509_time valid_to;             /**< The end time of certificate validity.                          */
+#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
 
     mbedtls_x509_buf_raw raw;               /**< The raw certificate data in DER.                               */
     mbedtls_x509_buf_raw tbs;               /**< The part of the CRT that is [T]o [B]e [S]igned.                */
@@ -80,10 +82,12 @@
 
     mbedtls_x509_buf_raw pubkey_raw;        /**< The raw public key data (DER).                                 */
 
+#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
     mbedtls_x509_buf_raw issuer_id;         /**< Optional X.509 v2/v3 issuer unique identifier.                 */
-    mbedtls_x509_buf_raw issuer_raw;        /**< The raw issuer data (DER). Used for quick comparison.          */
-
     mbedtls_x509_buf_raw subject_id;        /**< Optional X.509 v2/v3 subject unique identifier.                */
+#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
+
+    mbedtls_x509_buf_raw issuer_raw;        /**< The raw issuer data (DER). Used for quick comparison.          */
     mbedtls_x509_buf_raw subject_raw;       /**< The raw subject data (DER). Used for quick comparison.         */
 
     mbedtls_x509_buf_raw sig;               /**< Signature: hash of the tbs part signed with the private key.   */
@@ -123,14 +127,18 @@
     mbedtls_x509_name issuer;           /**< The parsed issuer data (named information object). */
     mbedtls_x509_name subject;          /**< The parsed subject data (named information object). */
 
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
     mbedtls_x509_time valid_from;       /**< Start time of certificate validity. */
     mbedtls_x509_time valid_to;         /**< End time of certificate validity. */
+#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
 
     mbedtls_x509_buf pk_raw;
     mbedtls_pk_context pk;              /**< Container for the public key context. */
 
+#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
     mbedtls_x509_buf issuer_id;         /**< Optional X.509 v2/v3 issuer unique identifier. */
     mbedtls_x509_buf subject_id;        /**< Optional X.509 v2/v3 subject unique identifier. */
+#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
     mbedtls_x509_buf v3_ext;            /**< Optional X.509 v3 extensions.  */
     mbedtls_x509_sequence subject_alt_names;    /**< Optional list of Subject Alternative Names (Only dNSName supported). */
 
@@ -235,8 +243,11 @@
 
     /* for find_parent_in() */
     mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */
+
+#if defined(MBEDTLS_HAVE_TIME_DATE)
     mbedtls_x509_crt *fallback_parent;
     int fallback_signature_is_good;
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
     /* for find_parent() */
     int parent_is_trusted; /* -1 if find_parent is not in progress */
diff --git a/library/ecdsa.c b/library/ecdsa.c
index dc19384..58e1a5f 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -172,11 +172,11 @@
 }
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
-#define ECDSA_RS_ECP    &rs_ctx->ecp
+#define ECDSA_RS_ECP    ( rs_ctx == NULL ? NULL : &rs_ctx->ecp )
 
 /* Utility macro for checking and updating ops budget */
 #define ECDSA_BUDGET( ops )   \
-    MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, &rs_ctx->ecp, ops ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, ECDSA_RS_ECP, ops ) );
 
 /* Call this when entering a function that needs its own sub-context */
 #define ECDSA_RS_ENTER( SUB )   do {                                 \
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index b0c0403..003aa10 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -173,7 +173,6 @@
     unsigned char *p = buf;
     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
     size_t sig_alg_len = 0;
-    const int *md;
 #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
     unsigned char *sig_alg_list = buf + 6;
 #endif
@@ -188,15 +187,15 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
 
-    for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
-    {
+    MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash )
+    ((void) hash);
 #if defined(MBEDTLS_ECDSA_C)
-        sig_alg_len += 2;
+    sig_alg_len += 2;
 #endif
 #if defined(MBEDTLS_RSA_C)
-        sig_alg_len += 2;
+    sig_alg_len += 2;
 #endif
-    }
+    MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS
 
     if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
     {
@@ -209,17 +208,16 @@
      */
     sig_alg_len = 0;
 
-    for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
-    {
+    MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash )
 #if defined(MBEDTLS_ECDSA_C)
-        sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
-        sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
+    sig_alg_list[sig_alg_len++] = hash;
+    sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
 #endif
 #if defined(MBEDTLS_RSA_C)
-        sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
-        sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
+    sig_alg_list[sig_alg_len++] = hash;
+    sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
 #endif
-    }
+    MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS
 
     /*
      * enum {
@@ -965,7 +963,7 @@
     p += 2;
 
     MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,
-                                            ssl->minor_ver,
+                                            mbedtls_ssl_get_minor_ver( ssl ),
                                             ciphersuite_info )
     {
         if( ssl_validate_ciphersuite( ciphersuite_info, ssl,
@@ -1187,8 +1185,8 @@
                           ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                   MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
     }
@@ -1198,8 +1196,8 @@
         if( len != 1 || buf[0] != 0x00 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                   MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
 
@@ -1223,8 +1221,8 @@
         buf[0] != ssl->conf->mfl_code )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1241,8 +1239,8 @@
         len != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1267,16 +1265,16 @@
         ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension unexpected" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
     if( len == 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1286,16 +1284,16 @@
     if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
     if( len != peer_cid_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1320,8 +1318,8 @@
         len != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1344,8 +1342,8 @@
         len != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1363,8 +1361,8 @@
         len != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1388,8 +1386,8 @@
     if( len == 0 || (size_t)( buf[0] + 1 ) != len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
     list_size = buf[0];
@@ -1415,8 +1413,8 @@
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
-    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+    mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
     return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 }
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
@@ -1446,8 +1444,8 @@
                                                 buf, len ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( ret );
     }
 
@@ -1466,8 +1464,8 @@
     if( ssl->conf->alpn_list == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1484,24 +1482,24 @@
     /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
     if( len < 4 )
     {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
     list_len = ( buf[0] << 8 ) | buf[1];
     if( list_len != len - 2 )
     {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
     name_len = buf[2];
     if( name_len != list_len - 1 )
     {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1517,8 +1515,8 @@
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) );
-    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+    mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
     return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 }
 #endif /* MBEDTLS_SSL_ALPN */
@@ -1556,8 +1554,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
 
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
 
         return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
     }
@@ -1569,8 +1567,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1,
             ( "cookie length does not match incoming message size" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                    MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1653,8 +1651,8 @@
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
 
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
@@ -1681,8 +1679,8 @@
         buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1720,8 +1718,8 @@
                          mbedtls_ssl_conf_get_max_major_ver( ssl->conf ),
                          mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ) ) );
 
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                 MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
 
             return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
         }
@@ -1750,8 +1748,8 @@
     if( n > 32 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1764,8 +1762,8 @@
             ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
     }
@@ -1776,8 +1774,8 @@
     else
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1800,8 +1798,8 @@
 #endif/* MBEDTLS_ZLIB_SUPPORT */
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
     }
 
@@ -1815,8 +1813,8 @@
     if( server_suite_info == MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
     mbedtls_ssl_optimize_checksum( ssl, server_suite_info );
@@ -1855,8 +1853,8 @@
         if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
             return( ret );
         }
     }
@@ -1885,7 +1883,7 @@
      * Perform cipher suite validation in same way as in ssl_write_client_hello.
      */
     MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,
-                                            ssl->minor_ver,
+                                            mbedtls_ssl_get_minor_ver( ssl ),
                                             ciphersuite_info )
     {
         if( ssl_validate_ciphersuite( ciphersuite_info, ssl,
@@ -1905,8 +1903,8 @@
     /* If we reach this code-path, the server's chosen ciphersuite
      * wasn't among those advertised by us. */
     MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                    MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+    mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
     return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 
 server_picked_valid_suite:
@@ -1930,8 +1928,8 @@
       )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                   MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
     ssl->session_negotiate->compression = comp;
@@ -1951,8 +1949,8 @@
         if( ext_size + 4 > ext_len )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                       MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
 
@@ -2163,8 +2161,8 @@
 
     if( handshake_failure == 1 )
     {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -2610,8 +2608,8 @@
         if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
             return( ret );
         }
 
@@ -2641,8 +2639,8 @@
     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                               MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
@@ -2665,8 +2663,8 @@
 
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must "
                                     "not be skipped" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                               MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
 
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
@@ -2694,8 +2692,8 @@
         if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                               MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
     } /* FALLTROUGH */
@@ -2723,8 +2721,8 @@
         if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                   MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
     }
@@ -2744,8 +2742,8 @@
         if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                   MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
     }
@@ -2762,8 +2760,8 @@
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                   MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
     }
@@ -2797,16 +2795,16 @@
                                                &md_alg, &pk_alg ) != 0 )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                    MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
                 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
             }
 
             if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
                 return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
             }
         }
@@ -2836,8 +2834,8 @@
         if( p > end - 2 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
         sig_len = ( p[0] << 8 ) | p[1];
@@ -2846,8 +2844,8 @@
         if( p != end - sig_len )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
 
@@ -2914,8 +2912,8 @@
         if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
             mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert );
 #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
@@ -2933,8 +2931,10 @@
 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
             if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
 #endif
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
+            {
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                     MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
+            }
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
             if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
@@ -3011,8 +3011,8 @@
     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                              MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
@@ -3059,8 +3059,8 @@
     if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                               MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
     }
     cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
@@ -3079,8 +3079,8 @@
     if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
     }
 
@@ -3110,8 +3110,8 @@
         if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
         }
 
@@ -3136,8 +3136,8 @@
     if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
     }
 
@@ -3170,8 +3170,8 @@
         ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
     }
 
@@ -3711,8 +3711,8 @@
     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                         MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
@@ -3730,8 +3730,8 @@
         ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
     }
 
@@ -3745,8 +3745,8 @@
     if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
     }
 
@@ -3781,8 +3781,8 @@
     if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
         return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
     }
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 3744cf6..573f327 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -94,16 +94,16 @@
     if( len < 2 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                       MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
     servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
     if( servername_list_size + 2 != len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -114,8 +114,8 @@
         if( hostname_len + 3 > servername_list_size )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
         }
 
@@ -126,7 +126,7 @@
             if( ret != 0 )
             {
                 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                mbedtls_ssl_pend_fatal_alert( ssl,
                         MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
@@ -140,8 +140,8 @@
     if( servername_list_size != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -163,8 +163,8 @@
                           ssl->verify_data_len ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
         }
     }
@@ -174,8 +174,8 @@
         if( len != 1 || buf[0] != 0x0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
         }
 
@@ -214,8 +214,8 @@
 
     if ( len < 2 ) {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                       MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
     sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
@@ -223,8 +223,8 @@
         sig_alg_list_size % 2 != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -287,8 +287,8 @@
 
     if ( len < 2 ) {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                       MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
     list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
@@ -296,8 +296,8 @@
         list_size % 2 != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -336,8 +336,8 @@
     if( len == 0 || (size_t)( buf[0] + 1 ) != len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
     list_size = buf[0];
@@ -384,8 +384,8 @@
                                                 buf, len ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( ret );
     }
 
@@ -404,8 +404,8 @@
     if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -426,8 +426,8 @@
     if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -443,8 +443,8 @@
     if( len < 1 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -454,8 +454,8 @@
     if( len != peer_cid_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -471,8 +471,8 @@
     if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -495,8 +495,8 @@
     if( len != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -517,7 +517,7 @@
     if( len != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+        mbedtls_ssl_pend_fatal_alert( ssl,
                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
@@ -542,8 +542,8 @@
     if( len != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -650,16 +650,16 @@
     /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
     if( len < 4 )
     {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
     list_len = ( buf[0] << 8 ) | buf[1];
     if( list_len != len - 2 )
     {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -675,16 +675,16 @@
         /* Current identifier must fit in list */
         if( cur_len > (size_t)( end - theirs ) )
         {
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
         }
 
         /* Empty strings MUST NOT be included */
         if( cur_len == 0 )
         {
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
         }
     }
@@ -709,8 +709,8 @@
     }
 
     /* If we get there, no match was found */
-    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                            MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
+    mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
     return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
 }
 #endif /* MBEDTLS_SSL_ALPN */
@@ -1056,8 +1056,8 @@
     if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
@@ -1112,8 +1112,8 @@
                             mbedtls_ssl_conf_get_min_major_ver( ssl->conf ),
                             mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ) ) );
 
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                     MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
         return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
     }
 
@@ -1210,8 +1210,8 @@
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV "
                                     "during renegotiation" ) );
 
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
@@ -1234,8 +1234,8 @@
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) );
 
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                         MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK );
 
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
@@ -1249,13 +1249,13 @@
 #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
     for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
     {
-        MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,                    \
-                                                ssl->minor_ver,         \
+        MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,                              \
+                                                mbedtls_ssl_get_minor_ver( ssl ), \
                                                 cur_info )
         {
 #else
-    MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,                \
-                                            ssl->minor_ver,     \
+    MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,                              \
+                                            mbedtls_ssl_get_minor_ver( ssl ), \
                                             cur_info )
     {
         for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
@@ -1323,8 +1323,8 @@
           MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -1652,8 +1652,8 @@
                             major_ver, minor_ver,
                             mbedtls_ssl_conf_get_min_major_ver( ssl->conf ),
                             mbedtls_ssl_conf_get_min_minor_ver( ssl->conf ) ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
             return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
         }
 
@@ -1689,8 +1689,8 @@
         sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -1714,8 +1714,8 @@
         if( cookie_offset + 1 + cookie_len + 2 > msg_len )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                               MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
         }
 
@@ -1774,8 +1774,8 @@
         ( ciph_len % 2 ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -1794,8 +1794,8 @@
         comp_len + comp_offset + 1 > msg_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -1835,8 +1835,8 @@
             if( msg_len < ext_offset + 2 )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
 
@@ -1847,8 +1847,8 @@
                 msg_len != ext_offset + 2 + ext_len )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
         }
@@ -1864,8 +1864,8 @@
             unsigned int ext_size;
             if ( ext_len < 4 ) {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                               MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
             ext_id   = ( ( ext[0] <<  8 ) | ( ext[1] ) );
@@ -1874,8 +1874,8 @@
             if( ext_size + 4 > ext_len )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
             switch( ext_id )
@@ -2033,8 +2033,8 @@
             if( ext_len > 0 && ext_len < 4 )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                         MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
         }
@@ -2055,8 +2055,8 @@
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) );
 
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                              MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK );
 
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
@@ -2099,8 +2099,8 @@
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV "
                                             "during renegotiation" ) );
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
             }
 #endif
@@ -2169,8 +2169,8 @@
 
     if( handshake_failure == 1 )
     {
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
     }
 
@@ -2183,13 +2183,13 @@
 #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
     for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
     {
-        MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,                    \
-                                                ssl->minor_ver,         \
+        MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,                              \
+                                                mbedtls_ssl_get_minor_ver( ssl ), \
                                                 cur_info )
         {
 #else
-    MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,                \
-                                            ssl->minor_ver,     \
+    MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl,                              \
+                                            mbedtls_ssl_get_minor_ver( ssl ), \
                                             cur_info )
     {
         for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
@@ -2229,15 +2229,15 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
                             "but none of them usable" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                          MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE );
     }
     else
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                           MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
         return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
     }
 
@@ -3074,18 +3074,19 @@
      */
     if( mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_3 )
     {
-        const int *cur;
-
         /*
          * Supported signature algorithms
          */
-        for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
+        MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH_TLS( hash )
+        if( 0
+#if defined(MBEDTLS_SHA512_C)
+            || hash == MBEDTLS_SSL_HASH_SHA384
+#endif
+#if defined(MBEDTLS_SHA256_C)
+            || hash == MBEDTLS_SSL_HASH_SHA256
+#endif
+            )
         {
-            unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur );
-
-            if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) )
-                continue;
-
 #if defined(MBEDTLS_RSA_C)
             p[2 + sa_len++] = hash;
             p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA;
@@ -3095,6 +3096,7 @@
             p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA;
 #endif
         }
+        MBEDTLS_SSL_END_FOR_EACH_SIG_HASH_TLS
 
         p[0] = (unsigned char)( sa_len >> 8 );
         p[1] = (unsigned char)( sa_len      );
@@ -4022,8 +4024,8 @@
     if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
     {
         MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                 MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY );
         return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY );
     }
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 9962278..3e78e5d 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -75,6 +75,17 @@
 #endif
 }
 
+static void ssl_send_pending_fatal_alert( mbedtls_ssl_context *ssl )
+{
+    if( ssl->pending_fatal_alert_msg == MBEDTLS_SSL_ALERT_MSG_NONE )
+        return;
+
+    mbedtls_ssl_send_alert_message( ssl,
+                                    MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                    ssl->pending_fatal_alert_msg );
+    ssl->pending_fatal_alert_msg = MBEDTLS_SSL_ALERT_MSG_NONE;
+}
+
 /*
  * Start a timer.
  * Passing millisecs = 0 cancels a running timer.
@@ -4714,8 +4725,8 @@
          * Section 4.1.2.7, that is, send alert only with TLS */
         if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
         {
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                    MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
         }
 #endif /* MBEDTLS_SSL_PROTO_TLS */
 
@@ -5111,6 +5122,7 @@
                     if( ret != 0 )
                     {
                         MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
+                        ssl_send_pending_fatal_alert( ssl );
                         return( ret );
                     }
                 }
@@ -5839,8 +5851,7 @@
 #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
                     if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
                     {
-                        mbedtls_ssl_send_alert_message( ssl,
-                                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                        mbedtls_ssl_pend_fatal_alert( ssl,
                                 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
                     }
 #endif
@@ -5876,8 +5887,7 @@
 #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
             if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
             {
-                mbedtls_ssl_send_alert_message( ssl,
-                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                mbedtls_ssl_pend_fatal_alert( ssl,
                         MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
             }
 #endif
@@ -6039,8 +6049,8 @@
 }
 
 int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
-                            unsigned char level,
-                            unsigned char message )
+                                    unsigned char level,
+                                    unsigned char message )
 {
     int ret;
 
@@ -6314,8 +6324,8 @@
     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                            MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
@@ -6323,8 +6333,8 @@
         ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
     }
 
@@ -6339,8 +6349,8 @@
         ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
     }
 
@@ -6353,9 +6363,8 @@
         /* Check that there's room for the next CRT's length fields. */
         if ( i + 3 > ssl->in_hslen ) {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-            mbedtls_ssl_send_alert_message( ssl,
-                              MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                              MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
         }
         /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
@@ -6363,9 +6372,8 @@
         if( ssl->in_msg[i] != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-            mbedtls_ssl_send_alert_message( ssl,
-                            MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
         }
 
@@ -6377,9 +6385,8 @@
         if( n < 128 || i + n > ssl->in_hslen )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
-            mbedtls_ssl_send_alert_message( ssl,
-                                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                          MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
             return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
         }
 
@@ -6400,9 +6407,8 @@
                                               n ) != 0 )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
-                mbedtls_ssl_send_alert_message( ssl,
-                                                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                                MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
+                mbedtls_ssl_pend_fatal_alert( ssl,
+                                       MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
                 return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
             }
 
@@ -6438,7 +6444,7 @@
             default:
                 alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
             crt_parse_der_failed:
-                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
+                mbedtls_ssl_pend_fatal_alert( ssl,  alert );
                 MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
                 return( ret );
         }
@@ -6672,8 +6678,7 @@
             alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
         else
             alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        alert );
+        mbedtls_ssl_pend_fatal_alert( ssl, alert );
     }
 
 #if defined(MBEDTLS_DEBUG_C)
@@ -6705,9 +6710,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
                                     sizeof( MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ) ) );
-        mbedtls_ssl_send_alert_message( ssl,
-                                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
 
         return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
     }
@@ -6810,9 +6814,8 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
                                     sizeof( mbedtls_x509_crt ) ) );
-        mbedtls_ssl_send_alert_message( ssl,
-                                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
 
         ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
         goto exit;
@@ -6943,8 +6946,8 @@
     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
@@ -6991,8 +6994,8 @@
         if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
-            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                            MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+            mbedtls_ssl_pend_fatal_alert( ssl,
+                                  MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
         }
     }
@@ -7585,8 +7588,8 @@
     if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                               MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
@@ -7602,8 +7605,8 @@
         ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
     }
 
@@ -7611,8 +7614,8 @@
                       buf, hash_len ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
     }
 
@@ -7783,8 +7786,6 @@
             ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
         else
             ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
-
-        ssl_set_timer( ssl, 0 );
     }
 #endif
 
@@ -7991,6 +7992,8 @@
     if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
         goto error;
 
+    ssl->pending_fatal_alert_msg = MBEDTLS_SSL_ALERT_MSG_NONE;
+
     return( 0 );
 
 error:
@@ -8636,7 +8639,12 @@
 void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
                                   const int *hashes )
 {
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH)
     conf->sig_hashes = hashes;
+#else
+    ((void) conf);
+    ((void) hashes);
+#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */
 }
 #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
 
@@ -9857,6 +9865,7 @@
         ret = mbedtls_ssl_handshake_server_step( ssl );
 #endif
 
+    ssl_send_pending_fatal_alert( ssl );
     return( ret );
 }
 
@@ -10256,12 +10265,11 @@
     defined(MBEDTLS_SSL_PROTO_TLS1_2)
                 if( mbedtls_ssl_get_minor_ver( ssl ) >= MBEDTLS_SSL_MINOR_VERSION_1 )
                 {
-                    if( ( ret = mbedtls_ssl_send_alert_message( ssl,
-                                    MBEDTLS_SSL_ALERT_LEVEL_WARNING,
-                                    MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
-                    {
+                    ret = mbedtls_ssl_send_alert_message( ssl,
+                                             MBEDTLS_SSL_ALERT_LEVEL_WARNING,
+                                             MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION );
+                    if( ret != 0 )
                         return( ret );
-                    }
                 }
                 else
 #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
@@ -11441,6 +11449,7 @@
 }
 
 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH)
 static int ssl_preset_default_hashes[] = {
 #if defined(MBEDTLS_SHA512_C)
     MBEDTLS_MD_SHA512,
@@ -11456,6 +11465,7 @@
     MBEDTLS_MD_NONE
 };
 #endif
+#endif
 
 #if !defined(MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE)
 static int ssl_preset_suiteb_ciphersuites[] = {
@@ -11466,12 +11476,14 @@
 #endif /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */
 
 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH)
 static int ssl_preset_suiteb_hashes[] = {
     MBEDTLS_MD_SHA256,
     MBEDTLS_MD_SHA384,
     MBEDTLS_MD_NONE
 };
 #endif
+#endif
 
 #if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_SSL_CONF_SINGLE_EC)
 static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = {
@@ -11620,8 +11632,10 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH)
             conf->sig_hashes = ssl_preset_suiteb_hashes;
 #endif
+#endif
 
 #if defined(MBEDTLS_ECP_C)
 #if !defined(MBEDTLS_SSL_CONF_SINGLE_EC)
@@ -11670,8 +11684,10 @@
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH)
             conf->sig_hashes = ssl_preset_default_hashes;
 #endif
+#endif
 
 #if defined(MBEDTLS_ECP_C)
 #if !defined(MBEDTLS_SSL_CONF_SINGLE_EC)
@@ -11910,14 +11926,10 @@
 int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
                                 mbedtls_md_type_t md )
 {
-    const int *cur;
-
-    if( ssl->conf->sig_hashes == NULL )
-        return( -1 );
-
-    for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
-        if( *cur == (int) md )
-            return( 0 );
+    MBEDTLS_SSL_BEGIN_FOR_EACH_SIG_HASH( md_alg )
+    if( md_alg == md )
+        return( 0 );
+    MBEDTLS_SSL_END_FOR_EACH_SIG_HASH
 
     return( -1 );
 }
@@ -12014,25 +12026,11 @@
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
 {
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    if( mbedtls_ssl_get_minor_ver( ssl ) != MBEDTLS_SSL_MINOR_VERSION_3 )
-        return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
-
     switch( md )
     {
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-#if defined(MBEDTLS_MD5_C)
-        case MBEDTLS_SSL_HASH_MD5:
-            return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
-#endif
-#if defined(MBEDTLS_SHA1_C)
-        case MBEDTLS_SSL_HASH_SHA1:
-            ssl->handshake->calc_verify = ssl_calc_verify_tls;
-            break;
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
 #if defined(MBEDTLS_SHA512_C)
         case MBEDTLS_SSL_HASH_SHA384:
             ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
@@ -12043,18 +12041,14 @@
             ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256;
             break;
 #endif
+
         default:
-            return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
+            return( MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH );
     }
 
-    return 0;
-#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */
-    (void) ssl;
-    (void) md;
-
-    return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    return( 0 );
 }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
     defined(MBEDTLS_SSL_PROTO_TLS1_1)
@@ -12133,8 +12127,8 @@
     mbedtls_sha1_free( &mbedtls_sha1 );
 
     if( ret != 0 )
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
 
     return( ret );
 
@@ -12193,8 +12187,8 @@
     mbedtls_md_free( &ctx );
 
     if( ret != 0 )
-        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        mbedtls_ssl_pend_fatal_alert( ssl,
+                                      MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
 
     return( ret );
 }
diff --git a/library/version_features.c b/library/version_features.c
index 3753864..51ce780 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -564,6 +564,12 @@
 #if defined(MBEDTLS_X509_REMOVE_INFO)
     "MBEDTLS_X509_REMOVE_INFO",
 #endif /* MBEDTLS_X509_REMOVE_INFO */
+#if defined(MBEDTLS_X509_CRT_REMOVE_TIME)
+    "MBEDTLS_X509_CRT_REMOVE_TIME",
+#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */
+#if defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
+    "MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID",
+#endif /* MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
     "MBEDTLS_X509_RSASSA_PSS_SUPPORT",
 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
diff --git a/library/x509.c b/library/x509.c
index 0d2b9ef..a6c6584 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -1192,21 +1192,7 @@
 
     return( x509_check_time( from, &now ) );
 }
-
-#else  /* MBEDTLS_HAVE_TIME_DATE */
-
-int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
-{
-    ((void) to);
-    return( 0 );
-}
-
-int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
-{
-    ((void) from);
-    return( 0 );
-}
-#endif /* MBEDTLS_HAVE_TIME_DATE */
+#endif  /* MBEDTLS_HAVE_TIME_DATE */
 
 void mbedtls_x509_name_free( mbedtls_x509_name *name )
 {
diff --git a/library/x509_crt.c b/library/x509_crt.c
index eb3ee99..4e5ff43 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -223,16 +223,22 @@
     frame->version = crt->version;
     frame->sig_md = crt->sig_md;
     frame->sig_pk = crt->sig_pk;
+
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
     frame->valid_from = crt->valid_from;
     frame->valid_to = crt->valid_to;
+#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
+
     x509_buf_to_buf_raw( &frame->raw, &crt->raw );
     x509_buf_to_buf_raw( &frame->tbs, &crt->tbs );
     x509_buf_to_buf_raw( &frame->serial, &crt->serial );
     x509_buf_to_buf_raw( &frame->pubkey_raw, &crt->pk_raw );
     x509_buf_to_buf_raw( &frame->issuer_raw, &crt->issuer_raw );
     x509_buf_to_buf_raw( &frame->subject_raw, &crt->subject_raw );
+#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
     x509_buf_to_buf_raw( &frame->subject_id, &crt->subject_id );
     x509_buf_to_buf_raw( &frame->issuer_id, &crt->issuer_id );
+#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
     x509_buf_to_buf_raw( &frame->sig, &crt->sig );
     x509_buf_to_buf_raw( &frame->v3_ext, &crt->v3_ext );
 
@@ -694,6 +700,7 @@
     return( 0 );
 }
 
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
 /*
  *  Validity ::= SEQUENCE {
  *       notBefore      Time,
@@ -725,7 +732,28 @@
 
     return( 0 );
 }
+#else /* !MBEDTLS_X509_CRT_REMOVE_TIME */
+static int x509_skip_dates( unsigned char **p,
+                           const unsigned char *end )
+{
+    int ret;
+    size_t len;
 
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
+
+    end = *p + len;
+
+    if( *p != end )
+        return( MBEDTLS_ERR_X509_INVALID_DATE +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */
+
+#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
 /*
  * X.509 v2/v3 unique identifier (not parsed)
  */
@@ -752,6 +780,30 @@
 
     return( 0 );
 }
+#else /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
+static int x509_skip_uid( unsigned char **p,
+                          const unsigned char *end,
+                          int n )
+{
+    int ret;
+    size_t len;
+
+    if( *p == end )
+        return( 0 );
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+            return( 0 );
+
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    *p += len;
+    return( 0 );
+}
+#endif /* MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
 
 static int x509_get_basic_constraints( unsigned char **p,
                                        const unsigned char *end,
@@ -1293,9 +1345,15 @@
     /*
      * Validity ::= SEQUENCE { ...
      */
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
     ret = x509_get_dates( &p, end, &frame->valid_from, &frame->valid_to );
     if( ret != 0 )
         return( ret );
+#else /* !MBEDTLS_X509_CRT_REMOVE_TIME */
+    ret = x509_skip_dates( &p, end );
+    if( ret != 0 )
+        return( ret );
+#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */
 
     /*
      * subject              Name
@@ -1334,6 +1392,7 @@
 
     if( frame->version != 1 )
     {
+#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
         /*
          *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
          *                       -- If present, version shall be v2 or v3
@@ -1349,6 +1408,14 @@
         ret = x509_get_uid( &p, end, &frame->subject_id, 2 /* implicit tag */ );
         if( ret != 0 )
             return( ret );
+#else /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
+        ret = x509_skip_uid( &p, end, 1 /* implicit tag */ );
+        if( ret != 0 )
+            return( ret );
+        ret = x509_skip_uid( &p, end, 2 /* implicit tag */ );
+        if( ret != 0 )
+            return( ret );
+#endif /* MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
     }
 
     /*
@@ -1531,13 +1598,19 @@
     x509_buf_raw_to_buf( &crt->serial, &frame->serial );
     x509_buf_raw_to_buf( &crt->issuer_raw, &frame->issuer_raw );
     x509_buf_raw_to_buf( &crt->subject_raw, &frame->subject_raw );
+#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
     x509_buf_raw_to_buf( &crt->issuer_id, &frame->issuer_id );
     x509_buf_raw_to_buf( &crt->subject_id, &frame->subject_id );
+#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
     x509_buf_raw_to_buf( &crt->pk_raw, &frame->pubkey_raw );
     x509_buf_raw_to_buf( &crt->sig, &frame->sig );
     x509_buf_raw_to_buf( &crt->v3_ext, &frame->v3_ext );
+
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
     crt->valid_from = frame->valid_from;
     crt->valid_to = frame->valid_to;
+#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
+
     crt->version      = frame->version;
     crt->ca_istrue    = frame->ca_istrue;
     crt->max_pathlen  = frame->max_pathlen;
@@ -2270,6 +2343,7 @@
     ret = mbedtls_x509_dn_gets( p, n, subject );
     MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
 
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
     ret = mbedtls_snprintf( p, n, "\n%sissued  on        : " \
                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
                    frame.valid_from.year, frame.valid_from.mon,
@@ -2283,6 +2357,7 @@
                    frame.valid_to.day,  frame.valid_to.hour,
                    frame.valid_to.min,  frame.valid_to.sec );
     MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
+#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */
 
     ret = mbedtls_snprintf( p, n, "\n%ssigned using      : ", prefix );
     MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
@@ -2844,8 +2919,13 @@
                         mbedtls_x509_crt_restart_ctx *rs_ctx )
 {
     int ret;
-    mbedtls_x509_crt *parent_crt, *fallback_parent;
-    int signature_is_good, fallback_signature_is_good;
+    mbedtls_x509_crt *parent_crt;
+    int signature_is_good;
+
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+    mbedtls_x509_crt *fallback_parent;
+    int fallback_signature_is_good;
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
     /* did we have something in progress? */
@@ -2853,21 +2933,27 @@
     {
         /* restore saved state */
         parent_crt = rs_ctx->parent;
+#if defined(MBEDTLS_HAVE_TIME_DATE)
         fallback_parent = rs_ctx->fallback_parent;
         fallback_signature_is_good = rs_ctx->fallback_signature_is_good;
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
         /* clear saved state */
         rs_ctx->parent = NULL;
+#if defined(MBEDTLS_HAVE_TIME_DATE)
         rs_ctx->fallback_parent = NULL;
         rs_ctx->fallback_signature_is_good = 0;
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
         /* resume where we left */
         goto check_signature;
     }
 #endif
 
+#if defined(MBEDTLS_HAVE_TIME_DATE)
     fallback_parent = NULL;
     fallback_signature_is_good = 0;
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
     for( parent_crt = candidates; parent_crt != NULL;
          parent_crt = parent_crt->next )
@@ -2886,11 +2972,13 @@
             if( ret != 0 )
                 return( MBEDTLS_ERR_X509_FATAL_ERROR );
 
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
             if( !mbedtls_x509_time_is_past( &parent->valid_to ) &&
                 !mbedtls_x509_time_is_future( &parent->valid_from ) )
             {
                 parent_valid = 1;
             }
+#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
 
             /* basic parenting skills (name, CA bit, key usage) */
             if( x509_crt_check_parent( child_sig, parent, top ) == 0 )
@@ -2918,8 +3006,10 @@
         {
             /* save state */
             rs_ctx->parent = parent_crt;
+#if defined(MBEDTLS_HAVE_TIME_DATE)
             rs_ctx->fallback_parent = fallback_parent;
             rs_ctx->fallback_signature_is_good = fallback_signature_is_good;
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
             return( ret );
         }
@@ -2934,11 +3024,13 @@
         /* optional time check */
         if( !parent_valid )
         {
+#if defined(MBEDTLS_HAVE_TIME_DATE)
             if( fallback_parent == NULL )
             {
                 fallback_parent = parent_crt;
                 fallback_signature_is_good = signature_is_good;
             }
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
             continue;
         }
@@ -2953,8 +3045,12 @@
     }
     else
     {
+#if defined(MBEDTLS_HAVE_TIME_DATE)
         *r_parent = fallback_parent;
         *r_signature_is_good = fallback_signature_is_good;
+#else /* MBEDTLS_HAVE_TIME_DATE */
+        *r_parent = NULL;
+#endif /* !MBEDTLS_HAVE_TIME_DATE */
     }
 
     return( 0 );
@@ -3179,11 +3275,13 @@
                 if( ret != 0 )
                     return( MBEDTLS_ERR_X509_FATAL_ERROR );
 
+#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
                 /* Check time-validity (all certificates) */
                 if( mbedtls_x509_time_is_past( &child->valid_to ) )
                     *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
                 if( mbedtls_x509_time_is_future( &child->valid_from ) )
                     *flags |= MBEDTLS_X509_BADCERT_FUTURE;
+#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
 
                 /* Stop here for trusted roots (but not for trusted EE certs) */
                 if( child_is_trusted )
@@ -3643,8 +3741,10 @@
     mbedtls_pk_restart_init( &ctx->pk );
 
     ctx->parent = NULL;
+#if defined(MBEDTLS_HAVE_TIME_DATE)
     ctx->fallback_parent = NULL;
     ctx->fallback_signature_is_good = 0;
+#endif /* MBEDTLS_HAVE_TIME_DATE */
 
     ctx->parent_is_trusted = -1;
 
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index ff30788..0f7251d 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -1546,6 +1546,22 @@
     }
 #endif /* MBEDTLS_X509_REMOVE_INFO */
 
+#if defined(MBEDTLS_X509_CRT_REMOVE_TIME)
+    if( strcmp( "MBEDTLS_X509_CRT_REMOVE_TIME", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_X509_CRT_REMOVE_TIME );
+        return( 0 );
+    }
+#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */
+
+#if defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
+    if( strcmp( "MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID );
+        return( 0 );
+    }
+#endif /* MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
+
 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
     if( strcmp( "MBEDTLS_X509_RSASSA_PSS_SUPPORT", config ) == 0 )
     {
@@ -2834,6 +2850,30 @@
     }
 #endif /* MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID */
 
+#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH)
+    if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_SIG_HASH );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH */
+
+#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID)
+    if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID */
+
+#if defined(MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID)
+    if( strcmp( "MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID */
+
     /* If the symbol is not found, return an error */
     return( 1 );
 }
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 81480b0..f0de381 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -569,6 +569,7 @@
     return( 0 );
 }
 
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH)
 static int ssl_sig_hashes_for_test[] = {
 #if defined(MBEDTLS_SHA512_C)
     MBEDTLS_MD_SHA512,
@@ -584,6 +585,7 @@
 #endif
     MBEDTLS_MD_NONE
 };
+#endif /* !MBEDTLS_SSL_CONF_SINGLE_HASH */
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
 /*
@@ -1697,7 +1699,9 @@
     {
         crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 );
         mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test );
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH)
         mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );
+#endif
     }
 
     mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 996d7f6..747523b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1000,7 +1000,8 @@
 }
 #endif
 
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+    !defined(MBEDTLS_SSL_CONF_SINGLE_HASH)
 static int ssl_sig_hashes_for_test[] = {
 #if defined(MBEDTLS_SHA512_C)
     MBEDTLS_MD_SHA512,
@@ -1016,7 +1017,7 @@
 #endif
     MBEDTLS_MD_NONE
 };
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && !defined(MBEDTLS_SSL_CONF_SINGLE_HASH) */
 
 /** Return true if \p ret is a status code indicating that there is an
  * operation in progress on an SSL connection, and false if it indicates
@@ -2520,7 +2521,9 @@
     {
         crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 );
         mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test );
+#if !defined(MBEDTLS_SSL_CONF_SINGLE_HASH)
         mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );
+#endif
     }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
diff --git a/scripts/config.pl b/scripts/config.pl
index 1c7c736..e4648de 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -39,6 +39,8 @@
 #   MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
 #       - this could be enabled if the respective tests were adapted
 #   MBEDTLS_X509_REMOVE_INFO
+#   MBEDTLS_X509_CRT_REMOVE_TIME
+#   MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID
 #   MBEDTLS_ZLIB_SUPPORT
 #   MBEDTLS_PKCS11_C
 #   and any symbol beginning _ALT
@@ -102,6 +104,8 @@
 MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
 MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
 MBEDTLS_X509_REMOVE_INFO
+MBEDTLS_X509_CRT_REMOVE_TIME
+MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID
 MBEDTLS_ZLIB_SUPPORT
 MBEDTLS_PKCS11_C
 MBEDTLS_NO_UDBL_DIVISION
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 8c53c67..a77fe13 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -762,9 +762,27 @@
 component_test_hardcoded_ciphersuite_cmake_clang() {
     msg "build: cmake, full config + MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE, clang" # ~ 50s
     scripts/config.pl full
-    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
+    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
+    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
     scripts/config.pl set MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
-    CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On .
+    CC=clang cmake -D LINK_WITH_PTHREAD=1 -D CMAKE_BUILD_TYPE:String=ASanDbg -D ENABLE_TESTING=On .
+    make
+
+    msg "test: main suites (full config + MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE)" # ~ 5s
+    make test
+
+    msg "test: ssl-opt.sh default (full config + MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE)" # ~ 5s
+    if_build_succeeded tests/ssl-opt.sh -f '^Default$\|^Default, DTLS$'
+}
+
+component_test_hardcoded_timer_callback_cmake_clang() {
+    msg "build: cmake, full config + MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE, clang" # ~ 50s
+    scripts/config.pl full
+    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
+    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    scripts/config.pl set MBEDTLS_SSL_CONF_GET_TIMER mbedtls_timing_get_delay
+    scripts/config.pl set MBEDTLS_SSL_CONF_SET_TIMER mbedtls_timing_set_delay
+    CC=clang cmake -D LINK_WITH_PTHREAD=1 -D CMAKE_BUILD_TYPE:String=ASanDbg -D ENABLE_TESTING=On .
     make
 
     msg "test: main suites (full config + MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE)" # ~ 5s
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index c170df2..1ea58df 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -3551,7 +3551,6 @@
              key_file=data_files/server6.key \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" \
             0 \
-            -c "Supported Signature Algorithm found: 4," \
             -c "Supported Signature Algorithm found: 5,"
 
 run_test    "Authentication: client SHA384, server required" \
@@ -3560,7 +3559,6 @@
              key_file=data_files/server6.key \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \
             0 \
-            -c "Supported Signature Algorithm found: 4," \
             -c "Supported Signature Algorithm found: 5,"
 
 requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
diff --git a/tests/suites/test_suite_nist_kw.function b/tests/suites/test_suite_nist_kw.function
index f1acde9..9c34ea6 100644
--- a/tests/suites/test_suite_nist_kw.function
+++ b/tests/suites/test_suite_nist_kw.function
@@ -170,10 +170,6 @@
         TEST_ASSERT( ciphertext != NULL );
     }
 
-    memset( plaintext, 0, in_len );
-    memset( ciphertext, 0, output_len );
-
-
     TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
                                          key, 8 * sizeof( key ), 1 ) == 0 );
 
@@ -225,10 +221,6 @@
         TEST_ASSERT( ciphertext != NULL );
     }
 
-    memset( plaintext, 0, output_len );
-    memset( ciphertext, 0, in_len );
-
-
     TEST_ASSERT( mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
                                          key, 8 * sizeof( key ), 0 ) == 0 );
     unwrap_ret = mbedtls_nist_kw_unwrap( &ctx, mode, ciphertext, in_len,