Merge remote-tracking branch 'origin/pr/591' into baremetal
diff --git a/ChangeLog b/ChangeLog
index 19c3b58..b67c2ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -36,6 +36,8 @@
      extension. On the client, fail the handshake if the server doesn't
      consent to the use of the ExtendedMasterSecret extension in its
      ServerHello.
+   * Add new configuration option MBEDTLS_SSL_PROTO_NO_TLS that enables code
+     size savings in configurations where only DTLS is used.
 
 API Changes
    * Add a new X.509 API call `mbedtls_x509_parse_der_nocopy()`.
diff --git a/configs/baremetal.h b/configs/baremetal.h
index 43469b0..ba1a6d8 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -74,6 +74,7 @@
 #define MBEDTLS_SSL_SESSION_TICKETS
 #define MBEDTLS_SSL_COOKIE_C
 #define MBEDTLS_SSL_PROTO_DTLS
+#define MBEDTLS_SSL_PROTO_NO_TLS
 #define MBEDTLS_SSL_DTLS_ANTI_REPLAY
 #define MBEDTLS_SSL_DTLS_HELLO_VERIFY
 #define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
diff --git a/configs/config-ccm-psk-tls1_2.h b/configs/config-ccm-psk-tls1_2.h
index bd2c1a3..c9b58dd 100644
--- a/configs/config-ccm-psk-tls1_2.h
+++ b/configs/config-ccm-psk-tls1_2.h
@@ -41,7 +41,6 @@
 /* mbed TLS feature support */
 #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
 #define MBEDTLS_SSL_PROTO_TLS1_2
-#define MBEDTLS_SSL_PROTO_TLS
 
 /* mbed TLS modules */
 #define MBEDTLS_AES_C
diff --git a/configs/config-mini-tls1_1.h b/configs/config-mini-tls1_1.h
index 349ea8e..013bc03 100644
--- a/configs/config-mini-tls1_1.h
+++ b/configs/config-mini-tls1_1.h
@@ -40,7 +40,6 @@
 #define MBEDTLS_PKCS1_V15
 #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
 #define MBEDTLS_SSL_PROTO_TLS1_1
-#define MBEDTLS_SSL_PROTO_TLS
 
 /* mbed TLS modules */
 #define MBEDTLS_AES_C
diff --git a/configs/config-suite-b.h b/configs/config-suite-b.h
index e6fad1c..18e2c40 100644
--- a/configs/config-suite-b.h
+++ b/configs/config-suite-b.h
@@ -47,7 +47,6 @@
 #define MBEDTLS_ECP_DP_SECP384R1_ENABLED
 #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 #define MBEDTLS_SSL_PROTO_TLS1_2
-#define MBEDTLS_SSL_PROTO_TLS
 
 /* mbed TLS modules */
 #define MBEDTLS_AES_C
diff --git a/configs/config-thread.h b/configs/config-thread.h
index 3166aa9..4fa0b8d 100644
--- a/configs/config-thread.h
+++ b/configs/config-thread.h
@@ -49,6 +49,7 @@
 #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 #define MBEDTLS_SSL_PROTO_TLS1_2
 #define MBEDTLS_SSL_PROTO_DTLS
+#define MBEDTLS_SSL_PROTO_NO_TLS
 #define MBEDTLS_SSL_DTLS_ANTI_REPLAY
 #define MBEDTLS_SSL_DTLS_HELLO_VERIFY
 #define MBEDTLS_SSL_EXPORT_KEYS
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index b3677b5..00fb9b3 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -565,8 +565,14 @@
 #error "MBEDTLS_SSL_TLS_C defined, but no protocol version is active"
 #endif
 
+/* PROTO_TLS is not a documented option so far, but still check for conflicts
+ * involving it, in preparation for making it the documented option later */
+#if defined(MBEDTLS_SSL_PROTO_TLS) && defined(MBEDTLS_SSL_PROTO_NO_TLS)
+#error "MBEDTLS_SSL_PROTO_TLS and MBEDTLS_SSL_PROTO_NO_TLS both defined"
+#endif
+
 #if defined(MBEDTLS_SSL_TLS_C) && \
-    ( !defined(MBEDTLS_SSL_PROTO_TLS) && !defined(MBEDTLS_SSL_PROTO_DTLS) )
+    ( defined(MBEDTLS_SSL_PROTO_NO_TLS) && !defined(MBEDTLS_SSL_PROTO_DTLS) )
 #error "MBEDTLS_SSL_TLS_C defined, but neither TLS or DTLS is active"
 #endif
 
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 99dec91..9fc512e 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1309,6 +1309,33 @@
 //#define MBEDTLS_SSL_ASYNC_PRIVATE
 
 /**
+ * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION
+ *
+ * Enable serialization of the TLS context structures, through use of the
+ * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load().
+ *
+ * This pair of functions allows one side of a connection to serialize the
+ * context associated with the connection, then free or re-use that context
+ * while the serialized state is persisted elsewhere, and finally deserialize
+ * that state to a live context for resuming read/write operations on the
+ * connection. From a protocol perspective, the state of the connection is
+ * unaffected, in particular this is entirely transparent to the peer.
+ *
+ * Note: this is distinct from TLS session resumption, which is part of the
+ * protocol and fully visible by the peer. TLS session resumption enables
+ * establishing new connections associated to a saved session with shorter,
+ * lighter handshakes, while context serialization is a local optimization in
+ * handling a single, potentially long-lived connection.
+ *
+ * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are
+ * saved after the handshake to allow for more efficient serialization, so if
+ * you don't need this feature you'll save RAM by disabling it.
+ *
+ * Comment to disable the context serialization APIs.
+ */
+#define MBEDTLS_SSL_CONTEXT_SERIALIZATION
+
+/**
  * \def MBEDTLS_SSL_DEBUG_ALL
  *
  * Enable the debug messages in SSL module for all issues.
@@ -1508,7 +1535,7 @@
  * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2,
  * and/or this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0.
  *
- * \see MBEDTLS_SSL_PROTO_TLS
+ * \see MBEDTLS_SSL_PROTO_NO_TLS
  *
  * Requires: MBEDTLS_SSL_PROTO_TLS1_1
  *        or MBEDTLS_SSL_PROTO_TLS1_2
@@ -1518,25 +1545,23 @@
 #define MBEDTLS_SSL_PROTO_DTLS
 
 /**
- * \def MBEDTLS_SSL_PROTO_TLS
+ * \def MBEDTLS_SSL_PROTO_NO_TLS
  *
- * Enable support for SSL/TLS (all available versions).
+ * Disable support for SSL/TLS (all available versions) - this doesn't affect
+ * support for DTLS which is controlled by #MBEDTLS_SSL_PROTO_DTLS. This is
+ * useful to reduce code size in configurations where only DTLS is used.
  *
- * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable TLS 1.2;
- * enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable TLS 1.1;
- * enable this and MBEDTLS_SSL_PROTO_TLS1   to enable TLS 1.0;
- * and/or this and MBEDTLS_SSL_PROTO_SSL3   to enable SSL 3.0 (deprecated).
+ * Disable this and enable MBEDTLS_SSL_PROTO_TLS1_2 to enable TLS 1.2;
+ * disable this and enable MBEDTLS_SSL_PROTO_TLS1_1 to enable TLS 1.1;
+ * disable this and enable MBEDTLS_SSL_PROTO_TLS1   to enable TLS 1.0;
+ * disable this and enable MBEDTLS_SSL_PROTO_SSL3   to enable SSL 3.0.
  *
- * \see MBEDTLS_SSL_PROTO_DTLS
+ * Requirements: if this macro is disabled, at least one of the above
+ * TLS versions needs to be enabled.
  *
- * Requires: MBEDTLS_SSL_PROTO_TLS1_2
- *        or MBEDTLS_SSL_PROTO_TLS1_1
- *        or MBEDTLS_SSL_PROTO_TLS1
- *        or MBEDTLS_SSL_PROTO_SSL3 (deprecated)
- *
- * Comment this macro to disable support for TLS
+ * Uncomment this macro to disable support for TLS.
  */
-#define MBEDTLS_SSL_PROTO_TLS
+//#define MBEDTLS_SSL_PROTO_NO_TLS
 
 /**
  * \def MBEDTLS_SSL_ALPN
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 5066807..6e1bb3a 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1343,8 +1343,8 @@
 
 /**
  * \brief           Set the transport type (TLS or DTLS).
- *                  Default: TLS if #MBEDTLS_SSL_PROTO_TLS is defined, else
- *                  DTLS.
+ *                  Default: TLS unless #MBEDTLS_SSL_PROTO_NO_TLS is defined,
+ *                  else DTLS.
  *
  * \note            For DTLS, you must either provide a recv callback that
  *                  doesn't block, or one that handles timeouts, see
@@ -3553,6 +3553,117 @@
 void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
 
 /**
+ * \brief          Save an active connection as serialized data in a buffer.
+ *                 This allows the freeing or re-using of the SSL context
+ *                 while still picking up the connection later in a way that
+ *                 it entirely transparent to the peer.
+ *
+ * \see            mbedtls_ssl_context_load()
+ *
+ * \note           This feature is currently only available under certain
+ *                 conditions, see the documentation of the return value
+ *                 #MBEDTLS_ERR_SSL_BAD_INPUT_DATA for details.
+ *
+ * \note           When this function succeeds, it calls
+ *                 mbedtls_ssl_session_reset() on \p ssl which as a result is
+ *                 no longer associated with the connection that has been
+ *                 serialized. This avoids creating copies of the session
+ *                 state. You're then free to either re-use the context
+ *                 structure for a different connection, or call
+ *                 mbedtls_ssl_session_free() on it. See the documentation of
+ *                 mbedtls_ssl_session_reset() for more details.
+ *
+ * \param ssl      The SSL context to save. On success, it is no longer
+ *                 associated with the connection that has been serialized.
+ * \param buf      The buffer to write the serialized data to. It must be a
+ *                 writeable buffer of at least \p len bytes, or may be \c
+ *                 NULL if \p len is \c 0.
+ * \param buf_len  The number of bytes available for writing in \p buf.
+ * \param olen     The size in bytes of the data that has been or would have
+ *                 been written. It must point to a valid \c size_t.
+ *
+ * \note           \p olen is updated to the correct value regardless of
+ *                 whether \p buf_len was large enough. This makes it possible
+ *                 to determine the necessary size by calling this function
+ *                 with \p buf set to \c NULL and \p buf_len to \c 0.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
+ * \return         #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in
+ *                 progress, or there is pending data for reading or sending,
+ *                 or the connection does not use DTLS 1.2 with and AEAD
+ *                 ciphersuite, or renegotiation is enabled.
+ */
+int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
+                              unsigned char *buf,
+                              size_t buf_len,
+                              size_t *olen );
+/**
+ * \brief          Load serialized connection data to an SSL context.
+ *
+ * \see            mbedtls_ssl_context_save()
+ *
+ * \warning        The same serialized data must never be loaded into more
+ *                 that one context. In order to ensure that, after
+ *                 successfully loading serialized data to an SSL context, you
+ *                 should immediately destroy or invalidate all copies of the
+ *                 serialized data that was loaded. Loading the same data in
+ *                 more than one context would cause severe security failures
+ *                 including but not limited to loss of confidentiality.
+ *
+ * \note           Before calling this function, the SSL context must be
+ *                 prepared in one of the two following ways. The first way is
+ *                 to take a context freshly initialised with
+ *                 mbedtls_ssl_init() and call mbedtls_ssl_setup() on it with
+ *                 the same ::mbedtls_ssl_config structure that was used in
+ *                 the original connection. The second way is to
+ *                 call mbedtls_ssl_session_reset() on a context that was
+ *                 previously prepared as above but used in the meantime.
+ *                 Either way, you must not use the context to perform a
+ *                 handshake between calling mbedtls_ssl_setup() or
+ *                 mbedtls_ssl_session_reset() and calling this function. You
+ *                 may however call other setter functions in that time frame
+ *                 as indicated in the note below.
+ *
+ * \note           Before or after calling this function successfully, you
+ *                 also need to configure some connection-specific callbacks
+ *                 and settings before you can use the connection again
+ *                 (unless they were already set before calling
+ *                 mbedtls_ssl_session_reset() and the values are suitable for
+ *                 the present connection). Specifically, you want to call
+ *                 at least mbedtls_ssl_set_bio(). If you're using a read
+ *                 timeout (that is, you called
+ *                 mbedtls_ssl_conf_read_timeout() with a non-zero timeout)
+ *                 and non-blocking I/O, you also need to set timer callbacks
+ *                 by calling mbedtls_ssl_set_timer_cb(). All other SSL setter
+ *                 functions are not necessary to call, either because they're
+ *                 only used in handshakes, or because the setting is already
+ *                 saved. You might choose to call them anyway, for example in
+ *                 order to share code between the cases of establishing a new
+ *                 connection and the case of loading an already-established
+ *                 connection.
+ *
+ * \note           If you have new information about the path MTU, you want to
+ *                 call mbedtls_ssl_set_mtu() after calling this function, as
+ *                 otherwise this function would overwrite your
+ *                 newly-configured value with the value that was active when
+ *                 the context was saved.
+ *
+ * \param ssl      The SSL context structure to be populated. It must have
+ *                 been prepared as described in the note above.
+ * \param buf      The buffer holding the serialized connection data. It must
+ *                 be a readable buffer of at least \p len bytes.
+ * \param len      The size of the serialized data in bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed.
+ * \return         #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
+ */
+int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
+                              const unsigned char *buf,
+                              size_t len );
+
+/**
  * \brief          Initialize an SSL configuration context
  *                 Just makes the context ready for
  *                 mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free().
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 1c8709f..8089441 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -58,6 +58,12 @@
 #define inline __inline
 #endif
 
+/* The public option is negative for backwards compatibility,
+ * but internally a poisitive option is more convenient. */
+#if !defined(MBEDTLS_SSL_PROTO_NO_TLS)
+#define MBEDTLS_SSL_PROTO_TLS
+#endif
+
 /* Determine minimum supported version */
 #define MBEDTLS_SSL_MIN_MAJOR_VERSION           MBEDTLS_SSL_MAJOR_VERSION_3
 
@@ -963,8 +969,11 @@
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
         return( 12 );
+    MBEDTLS_SSL_TRANSPORT_ELSE
 #endif
-    return( 4 );
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+        return( 4 );
+#endif
 }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
diff --git a/library/pkparse.c b/library/pkparse.c
index ae210bc..4ec63e4 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -1164,7 +1164,11 @@
                   const unsigned char *key, size_t keylen,
                   const unsigned char *pwd, size_t pwdlen )
 {
+#if defined(MBEDTLS_PKCS12_C) || \
+    defined(MBEDTLS_PKCS5_C) || \
+    defined(MBEDTLS_PEM_PARSE_C)
     int ret;
+#endif
     const mbedtls_pk_info_t *pk_info;
 #if defined(MBEDTLS_PEM_PARSE_C)
     size_t len;
@@ -1327,7 +1331,7 @@
     }
 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
 
-    if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
+    if( pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) == 0 )
         return( 0 );
 
     mbedtls_pk_free( pk );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index ca4ab36..a5c8c33 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -68,8 +68,11 @@
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
         return( 2 );
+    MBEDTLS_SSL_TRANSPORT_ELSE
 #endif
+#if defined(MBEDTLS_SSL_PROTO_TLS)
     return( 0 );
+#endif
 }
 
 /*
@@ -8647,25 +8650,29 @@
                 return( "unknown (DTLS)" );
         }
     }
-#endif
-
-    switch( ssl->minor_ver )
+    MBEDTLS_SSL_TRANSPORT_ELSE
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
     {
-        case MBEDTLS_SSL_MINOR_VERSION_0:
-            return( "SSLv3.0" );
+        switch( ssl->minor_ver )
+        {
+            case MBEDTLS_SSL_MINOR_VERSION_0:
+                return( "SSLv3.0" );
 
-        case MBEDTLS_SSL_MINOR_VERSION_1:
-            return( "TLSv1.0" );
+            case MBEDTLS_SSL_MINOR_VERSION_1:
+                return( "TLSv1.0" );
 
-        case MBEDTLS_SSL_MINOR_VERSION_2:
-            return( "TLSv1.1" );
+            case MBEDTLS_SSL_MINOR_VERSION_2:
+                return( "TLSv1.1" );
 
-        case MBEDTLS_SSL_MINOR_VERSION_3:
-            return( "TLSv1.2" );
+            case MBEDTLS_SSL_MINOR_VERSION_3:
+                return( "TLSv1.2" );
 
-        default:
-            return( "unknown" );
+            default:
+                return( "unknown" );
+        }
     }
+#endif /* MBEDTLS_SSL_PROTO_TLS */
 }
 
 int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
@@ -9659,8 +9666,13 @@
                 {
                     continue;
                 }
+                MBEDTLS_SSL_TRANSPORT_ELSE
 #endif
-                return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+                {
+                    return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+                }
+#endif
             }
 #endif /* MBEDTLS_SSL_CLI_C */
 
@@ -9676,8 +9688,13 @@
                 {
                     continue;
                 }
+                MBEDTLS_SSL_TRANSPORT_ELSE
 #endif
-                return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+                {
+                    return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+                }
+#endif
             }
 #endif /* MBEDTLS_SSL_SRV_C */
 
@@ -10214,6 +10231,40 @@
 }
 
 /*
+ * Serialize a full SSL context
+ */
+int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
+                              unsigned char *buf,
+                              size_t buf_len,
+                              size_t *olen )
+{
+    /* Unimplemented */
+    (void) ssl;
+
+    if( buf != NULL )
+        memset( buf, 0, buf_len );
+
+    *olen = 0;
+
+    return( 0 );
+}
+
+/*
+ * Deserialize a full SSL context
+ */
+int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
+                              const unsigned char *buf,
+                              size_t len )
+{
+    /* Unimplemented */
+    (void) ssl;
+    (void) buf;
+    (void) len;
+
+    return( 0 );
+}
+
+/*
  * Free an SSL context
  */
 void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
diff --git a/library/version_features.c b/library/version_features.c
index d47892c..245f957 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -441,6 +441,9 @@
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
     "MBEDTLS_SSL_ASYNC_PRIVATE",
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    "MBEDTLS_SSL_CONTEXT_SERIALIZATION",
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
     "MBEDTLS_SSL_DEBUG_ALL",
 #endif /* MBEDTLS_SSL_DEBUG_ALL */
@@ -486,9 +489,9 @@
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     "MBEDTLS_SSL_PROTO_DTLS",
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
-#if defined(MBEDTLS_SSL_PROTO_TLS)
-    "MBEDTLS_SSL_PROTO_TLS",
-#endif /* MBEDTLS_SSL_PROTO_TLS */
+#if defined(MBEDTLS_SSL_PROTO_NO_TLS)
+    "MBEDTLS_SSL_PROTO_NO_TLS",
+#endif /* MBEDTLS_SSL_PROTO_NO_TLS */
 #if defined(MBEDTLS_SSL_ALPN)
     "MBEDTLS_SSL_ALPN",
 #endif /* MBEDTLS_SSL_ALPN */
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index 815f448..dbb6cc1 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -1218,6 +1218,14 @@
     }
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( strcmp( "MBEDTLS_SSL_CONTEXT_SERIALIZATION", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONTEXT_SERIALIZATION );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
+
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
     if( strcmp( "MBEDTLS_SSL_DEBUG_ALL", config ) == 0 )
     {
@@ -1338,13 +1346,13 @@
     }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
-#if defined(MBEDTLS_SSL_PROTO_TLS)
-    if( strcmp( "MBEDTLS_SSL_PROTO_TLS", config ) == 0 )
+#if defined(MBEDTLS_SSL_PROTO_NO_TLS)
+    if( strcmp( "MBEDTLS_SSL_PROTO_NO_TLS", config ) == 0 )
     {
-        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_PROTO_TLS );
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_PROTO_NO_TLS );
         return( 0 );
     }
-#endif /* MBEDTLS_SSL_PROTO_TLS */
+#endif /* MBEDTLS_SSL_PROTO_NO_TLS */
 
 #if defined(MBEDTLS_SSL_ALPN)
     if( strcmp( "MBEDTLS_SSL_ALPN", config ) == 0 )
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index fc665f9..375e5e3 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -44,14 +44,14 @@
     !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) ||         \
     !defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) || \
     !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
-    !defined(MBEDTLS_SSL_PROTO_TLS)
+    defined(MBEDTLS_SSL_PROTO_NO_TLS)
 int main( void )
 {
     mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
            "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
            "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
            "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or"
-           "MBEDTLS_SSL_PROTO_TLS not defined.\n");
+           "not defined, and/or MBEDTLS_SSL_PROTO_NO_TLS defined.\n");
     return( 0 );
 }
 #else
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 5b74435..9363316 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -122,6 +122,7 @@
 #define DFL_FALLBACK            -1
 #define DFL_EXTENDED_MS         -1
 #define DFL_ETM                 -1
+#define DFL_SERIALIZE           0
 #define DFL_EXTENDED_MS_ENFORCE -1
 
 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
@@ -281,6 +282,15 @@
 #define USAGE_ECRESTART ""
 #endif
 
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+#define USAGE_SERIALIZATION \
+    "    serialize=%%d        default: 0 (do not serialize/deserialize)\n" \
+    "                        options: 1 (serialize)\n"                    \
+    "                                 2 (serialize with re-initialization)\n"
+#else
+#define USAGE_SERIALIZATION ""
+#endif
+
 #define USAGE \
     "\n usage: ssl_client2 param=<>...\n"                   \
     "\n acceptable parameters:\n"                           \
@@ -345,6 +355,7 @@
     "                                configuration macro is defined and 1\n"  \
     "                                otherwise. The expansion of the macro\n" \
     "                                is printed if it is defined\n"     \
+    USAGE_SERIALIZATION                                     \
     " acceptable ciphersuite names:\n"
 
 #define ALPN_LIST_SIZE  10
@@ -421,6 +432,7 @@
     int cid_enabled_renego;     /* whether to use the CID extension or not
                                  * during renegotiation                     */
     const char *cid_val;        /* the CID to use for incoming messages     */
+    int serialize;              /* serialize/deserialize connection         */
     const char *cid_val_renego; /* the CID to use for incoming messages
                                  * after renegotiation                      */
 } opt;
@@ -843,6 +855,7 @@
     opt.enforce_extended_master_secret = DFL_EXTENDED_MS_ENFORCE;
     opt.etm                 = DFL_ETM;
     opt.dgram_packing       = DFL_DGRAM_PACKING;
+    opt.serialize           = DFL_SERIALIZE;
 
     for( i = 1; i < argc; i++ )
     {
@@ -1226,6 +1239,12 @@
         {
             return query_config( q );
         }
+        else if( strcmp( p, "serialize") == 0 )
+        {
+            opt.serialize = atoi( q );
+            if( opt.serialize < 0 || opt.serialize > 2)
+                goto usage;
+        }
         else
             goto usage;
     }
@@ -2373,7 +2392,90 @@
     }
 
     /*
-     * 7c. Continue doing data exchanges?
+     * 7c. Simulate serialize/deserialize and go back to data exchange
+     */
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( opt.serialize != 0 )
+    {
+        size_t buf_len;
+        unsigned char *context_buf = NULL;
+
+        opt.serialize = 0;
+        mbedtls_printf( " Serializing live connection..." );
+
+        ret = mbedtls_ssl_context_save( &ssl, NULL, 0, &buf_len );
+
+        /* Allow stub implementation returning 0 for now */
+        if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL &&
+            ret != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_context_save returned "
+                            "-0x%x\n\n", -ret );
+
+            goto exit;
+        }
+
+        if( ( context_buf = mbedtls_calloc( 1, buf_len ) ) == NULL )
+        {
+            mbedtls_printf( " failed\n  ! Couldn't allocate buffer for "
+                            "serialized context" );
+
+            goto exit;
+        }
+
+        if( ( ret = mbedtls_ssl_context_save( &ssl, context_buf,
+                                              buf_len, &buf_len ) ) != 0 )
+        {
+            mbedtls_printf( "failed\n  ! mbedtls_ssl_context_save returned "
+                            "-0x%x\n\n", -ret );
+
+            goto exit;
+        }
+
+        if( opt.serialize == 2 )
+        {
+            mbedtls_ssl_free( &ssl );
+
+            mbedtls_ssl_init( &ssl );
+
+            if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+            {
+                mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned "
+                                " -0x%x\n\n", -ret );
+                goto exit;
+            }
+
+            if( opt.nbio == 2 )
+                mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv,
+                                     NULL );
+            else
+                mbedtls_ssl_set_bio( &ssl, &server_fd,
+                            mbedtls_net_send, mbedtls_net_recv,
+                            opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
+
+#if defined(MBEDTLS_TIMING_C)
+            if( opt.nbio != 0 && opt.read_timeout != 0 )
+                mbedtls_ssl_set_timer_cb( &ssl, &timer,
+                                          mbedtls_timing_set_delay,
+                                          mbedtls_timing_get_delay );
+#endif /* MBEDTLS_TIMING_C */
+        }
+
+        mbedtls_printf( " Deserializing connection..." );
+
+        if( ( ret = mbedtls_ssl_context_load( &ssl, context_buf,
+                                              buf_len ) ) != 0 )
+        {
+            mbedtls_printf( "failed\n  ! mbedtls_ssl_context_load returned "
+                            "-0x%x\n\n", -ret );
+
+            goto exit;
+        }
+    }
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
+
+    /*
+     * 7d. Continue doing data exchanges?
      */
     if( --opt.exchanges > 0 )
         goto send_request;
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 62b4c40..bbe61fd 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -44,7 +44,7 @@
     !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) ||    \
     !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_TIMING_C) || \
     !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_PEM_PARSE_C) || \
-    !defined(MBEDTLS_SSL_PROTO_TLS)
+    defined(MBEDTLS_SSL_PROTO_NO_TLS)
 int main( int argc, char *argv[] )
 {
     ((void) argc);
@@ -54,8 +54,8 @@
            "and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
            "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
            "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
-           "MBEDTLS_TIMING_C and/or MBEDTLS_PEM_PARSE_C and/or "
-           "MBEDTLS_SSL_PROTO_TLS not defined.\n");
+           "MBEDTLS_TIMING_C and/or MBEDTLS_PEM_PARSE_C not defined, and/or "
+           "MBEDTLS_SSL_PROTO_NO_TLS defined.\n");
     return( 0 );
 }
 #elif defined(_WIN32)
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index b114a7e..e5d9658 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -48,14 +48,14 @@
     !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
     !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) ||         \
     !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
-    !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_SSL_PROTO_TLS)
+    !defined(MBEDTLS_FS_IO) || defined(MBEDTLS_SSL_PROTO_NO_TLS)
 int main( void )
 {
     mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
            "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
            "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
-           "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
-           "MBEDTLS_SSL_PROTO_TLS not defined.\n");
+           "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
+           "not defined, and/or MBEDTLS_SSL_PROTO_NO_TLS defined.\n");
     return( 0 );
 }
 #else
diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index b00f476..17f4584 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -45,7 +45,7 @@
     !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) ||            \
     !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) ||      \
     !defined(MBEDTLS_THREADING_C) || !defined(MBEDTLS_THREADING_PTHREAD) || \
-    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_SSL_PROTO_TLS)
+    !defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_SSL_PROTO_NO_TLS)
 int main( void )
 {
     mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_CERTS_C and/or MBEDTLS_ENTROPY_C "
@@ -53,8 +53,8 @@
            "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
            "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
            "MBEDTLS_THREADING_C and/or MBEDTLS_THREADING_PTHREAD "
-           "and/or MBEDTLS_PEM_PARSE_C and/or "
-           "MBEDTLS_SSL_PROTO_TLS not defined.\n");
+           "and/or MBEDTLS_PEM_PARSE_C not defined, and/or "
+           "MBEDTLS_SSL_PROTO_NO_TLS defined.\n");
     return( 0 );
 }
 #else
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 05d58fa..9791856 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -44,15 +44,15 @@
     !defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_NET_C) ||     \
     !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) ||    \
     !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) || \
-    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_SSL_PROTO_TLS)
+    !defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_SSL_PROTO_NO_TLS)
 int main( void )
 {
     mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_CERTS_C and/or MBEDTLS_ENTROPY_C "
            "and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
            "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
            "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
-           "and/or MBEDTLS_PEM_PARSE_C and/or "
-           "MBEDTLS_SSL_PROTO_TLS not defined.\n");
+           "and/or MBEDTLS_PEM_PARSE_C not defined, and/or "
+           "MBEDTLS_SSL_PROTO_NO_TLS defined.\n");
     return( 0 );
 }
 #else
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 5c9fd2e..8a12de2 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -163,6 +163,7 @@
 #define DFL_DGRAM_PACKING        1
 #define DFL_EXTENDED_MS         -1
 #define DFL_ETM                 -1
+#define DFL_SERIALIZE           0
 #define DFL_EXTENDED_MS_ENFORCE -1
 
 #define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
@@ -386,6 +387,15 @@
 #define USAGE_CURVES ""
 #endif
 
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+#define USAGE_SERIALIZATION \
+    "    serialize=%%d        default: 0 (do not serialize/deserialize)\n" \
+    "                        options: 1 (serialize)\n"                    \
+    "                                 2 (serialize with re-initialization)\n"
+#else
+#define USAGE_SERIALIZATION ""
+#endif
+
 #define USAGE \
     "\n usage: ssl_server2 param=<>...\n"                   \
     "\n acceptable parameters:\n"                           \
@@ -447,6 +457,7 @@
     "                                configuration macro is defined and 1\n"  \
     "                                otherwise. The expansion of the macro\n" \
     "                                is printed if it is defined\n"     \
+    USAGE_SERIALIZATION                                     \
     " acceptable ciphersuite names:\n"
 
 
@@ -544,6 +555,7 @@
     int cid_enabled_renego;     /* whether to use the CID extension or not
                                  * during renegotiation                     */
     const char *cid_val;        /* the CID to use for incoming messages     */
+    int serialize;              /* serialize/deserialize connection         */
     const char *cid_val_renego; /* the CID to use for incoming messages
                                  * after renegotiation                      */
 } opt;
@@ -1502,6 +1514,7 @@
     opt.extended_ms         = DFL_EXTENDED_MS;
     opt.enforce_extended_master_secret = DFL_EXTENDED_MS_ENFORCE;
     opt.etm                 = DFL_ETM;
+    opt.serialize           = DFL_SERIALIZE;
 
     for( i = 1; i < argc; i++ )
     {
@@ -1919,6 +1932,12 @@
         {
             return query_config( q );
         }
+        else if( strcmp( p, "serialize") == 0 )
+        {
+            opt.serialize = atoi( q );
+            if( opt.serialize < 0 || opt.serialize > 2)
+                goto usage;
+        }
         else
             goto usage;
     }
@@ -3349,7 +3368,90 @@
     ret = 0;
 
     /*
-     * 7b. Continue doing data exchanges?
+     * 7b. Simulate serialize/deserialize and go back to data exchange
+     */
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( opt.serialize != 0 )
+    {
+        size_t buf_len;
+        unsigned char *context_buf = NULL;
+
+        opt.serialize = 0;
+        mbedtls_printf( " Serializing live connection..." );
+
+        ret = mbedtls_ssl_context_save( &ssl, NULL, 0, &buf_len );
+
+        /* Allow stub implementation returning 0 for now */
+        if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL &&
+            ret != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_context_save returned "
+                            "-0x%x\n\n", -ret );
+
+            goto exit;
+        }
+
+        if( ( context_buf = mbedtls_calloc( 1, buf_len ) ) == NULL )
+        {
+            mbedtls_printf( " failed\n  ! Couldn't allocate buffer for "
+                            "serialized context" );
+
+            goto exit;
+        }
+
+        if( ( ret = mbedtls_ssl_context_save( &ssl, context_buf,
+                                              buf_len, &buf_len ) ) != 0 )
+        {
+            mbedtls_printf( "failed\n  ! mbedtls_ssl_context_save returned "
+                            "-0x%x\n\n", -ret );
+
+            goto exit;
+        }
+
+        if( opt.serialize == 2 )
+        {
+            mbedtls_ssl_free( &ssl );
+
+            mbedtls_ssl_init( &ssl );
+
+            if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+            {
+                mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned "
+                                "-0x%x\n\n", -ret );
+                goto exit;
+            }
+
+            if( opt.nbio == 2 )
+                mbedtls_ssl_set_bio( &ssl, &client_fd, my_send, my_recv,
+                                     NULL );
+            else
+                mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send,
+                            mbedtls_net_recv,
+                            opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
+
+#if defined(MBEDTLS_TIMING_C)
+            if( opt.nbio != 0 && opt.read_timeout != 0 )
+                mbedtls_ssl_set_timer_cb( &ssl, &timer,
+                                          mbedtls_timing_set_delay,
+                                          mbedtls_timing_get_delay );
+#endif /* MBEDTLS_TIMING_C */
+        }
+
+        mbedtls_printf( " Deserializing connection..." );
+
+        if( ( ret = mbedtls_ssl_context_load( &ssl, context_buf,
+                                              buf_len ) ) != 0 )
+        {
+            mbedtls_printf( "failed\n  ! mbedtls_ssl_context_load returned "
+                            "-0x%x\n\n", -ret );
+
+            goto exit;
+        }
+    }
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
+
+    /*
+     * 7c. Continue doing data exchanges?
      */
     if( --exchanges_left > 0 )
         goto data_exchange;
diff --git a/scripts/baremetal.sh b/scripts/baremetal.sh
index 4b798b9..be5fd04 100755
--- a/scripts/baremetal.sh
+++ b/scripts/baremetal.sh
@@ -75,15 +75,20 @@
     echo "Create 32-bit library-only baremetal build (GCC, config: $BAREMETAL_CONFIG)"
     gcc_ver=$($GCC_CC --version | head -n 1 | sed -n 's/^.*\([0-9]\.[0-9]\.[0-9]\).*$/\1/p')
 
-    CFLAGS_BAREMETAL="-Os -mthumb -mcpu=cortex-m0plus"
+    CFLAGS_BAREMETAL="-Os -mthumb -mcpu=cortex-m0plus --std=c99"
+    if [ $check -ne 0 ]; then
+        CFLAGS_BAREMETAL="$CFLAGS_BAREMETAL -Werror"
+    fi
     CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
 
-    $GCC_CC --version
-
     echo "GCC version: $gcc_ver"
     echo "Flags: $CFLAGS_BAREMETAL"
     make CC=$GCC_CC AR=$GCC_AR CFLAGS="$CFLAGS" lib -j > /dev/null
 
+    if [ $check -ne 0 ]; then
+        return
+    fi
+
     ROM_OUT_FILE="rom_files__${date}__${NAME}__gcc_${gcc_ver}"
     ROM_OUT_SYMS="rom_syms__${date}__${NAME}__gcc_${gcc_ver}"
     echo "Generate file statistics..."
@@ -113,10 +118,18 @@
     CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
     WARNING_CFLAGS="--strict --c99"
 
+    if [ $check -ne 0 ]; then
+        WARNING_CFLAGS="$WARNING_CFLAGS --diag_error=warning"
+    fi
+
     echo "ARMC5 version: $armc5_ver"
     echo "Flags: $WARNING_CFLAGS $CFLAGS_BAREMETAL"
     make WARNING_CFLAGS="$WARNING_CFLAGS" CC=$ARMC5_CC AR=$ARMC5_AR CFLAGS="$CFLAGS" lib -j > /dev/null
 
+    if [ $check -ne 0 ]; then
+        return
+    fi
+
     ROM_OUT_FILE="rom_files__${date}__${NAME}__armc5_${armc5_ver}"
     ROM_OUT_SYMS="rom_syms__${date}__${NAME}__armc5_${armc5_ver}"
     echo "Generate file statistics..."
@@ -142,13 +155,19 @@
     echo "Create 32-bit library-only baremetal build (ARMC6, Config: $BAREMETAL_CONFIG)"
     armc6_ver=$($ARMC6_CC --version | sed -n 's/.*ARM Compiler \([^ ]*\)$/\1/p')
 
-    CFLAGS_BAREMETAL="-Os --target=arm-arm-none-eabi -mthumb -mcpu=cortex-m0plus"
+    CFLAGS_BAREMETAL="-Os --target=arm-arm-none-eabi -mthumb -mcpu=cortex-m0plus -xc --std=c99"
+    if [ $check -ne 0 ]; then
+        CFLAGS_BAREMETAL="$CFLAGS_BAREMETAL -Werror"
+    fi
     CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
-    WARNING_CFLAGS="-xc -std=c99"
 
     echo "ARMC6 version: $armc6_ver"
-    echo "Flags: $WARNING_CFLAGS $CFLAGS_BAREMETAL"
-    make WARNING_CFLAGS="$WARNING_CFLAGS" CC=$ARMC6_CC AR=$ARMC6_AR CFLAGS="$CFLAGS" lib -j > /dev/null
+    echo "Flags: $CFLAGS_BAREMETAL"
+    make CC=$ARMC6_CC AR=$ARMC6_AR CFLAGS="$CFLAGS" lib -j > /dev/null
+
+    if [ $check -ne 0 ]; then
+        return
+    fi
 
     ROM_OUT_FILE="rom_files__${date}__${NAME}__armc6_${armc6_ver}"
     ROM_OUT_SYMS="rom_syms__${date}__${NAME}__armc6_${armc6_ver}"
@@ -299,7 +318,7 @@
 }
 
 show_usage() {
-    echo "Usage: $0 [--rom [--gcc] [--armc5] [--armc6]|--ram [--stack] [--heap]]"
+    echo "Usage: $0 [--rom [--check] [--gcc] [--armc5] [--armc6]|--ram [--stack] [--heap]]"
 }
 
 test_build=0
@@ -312,6 +331,8 @@
 measure_heap=0
 measure_stack=0
 
+check=0
+
 while [ $# -gt 0 ]; do
     case "$1" in
         --gcc)   build_gcc=1;;
@@ -321,6 +342,7 @@
         --rom) raw_build=1;;
         --heap)  measure_heap=1;;
         --stack) measure_stack=1;;
+        --check) check=1;;
         -*)
             echo >&2 "Unknown option: $1"
             show_usage
diff --git a/scripts/config.pl b/scripts/config.pl
index aa9106b..c10a3b3 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -31,6 +31,7 @@
 #   MBEDTLS_REMOVE_ARC4_CIPHERSUITES
 #   MBEDTLS_REMOVE_3DES_CIPHERSUITES
 #   MBEDTLS_SSL_HW_RECORD_ACCEL
+#   MBEDTLS_SSL_PROTO_NO_DTLS
 #   MBEDTLS_RSA_NO_CRT
 #   MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
 #   MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
@@ -93,6 +94,7 @@
 MBEDTLS_REMOVE_ARC4_CIPHERSUITES
 MBEDTLS_REMOVE_3DES_CIPHERSUITES
 MBEDTLS_SSL_HW_RECORD_ACCEL
+MBEDTLS_SSL_PROTO_NO_TLS
 MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
 MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
 MBEDTLS_X509_REMOVE_INFO
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index b55a922..cd6d2da 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1183,6 +1183,12 @@
     armc6_build_test "--target=aarch64-arm-none-eabi -march=armv8.2-a"
 }
 
+# need _armcc in the name for pre_check_tools()
+component_build_baremetal_script_gcc_armcc () {
+    msg "build: scripts/baremetal.sh gcc/armc5/armc6"
+    scripts/baremetal.sh --rom --gcc --armc5 --armc6 --check
+}
+
 component_build_armcc_tinycrypt_baremetal () {
     msg "build: ARM Compiler 5, make with tinycrypt and baremetal"
     scripts/config.pl baremetal
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index a39b5ac..3dd69a5 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -1128,6 +1128,62 @@
             -S "dumping 'expected mac' (20 bytes)" \
             -s "dumping 'expected mac' (10 bytes)"
 
+# Tests for Context serialization
+
+skip_next_test
+requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
+run_test    "(STUB) Context serialization, client serializes" \
+            "$P_SRV serialize=0 exchanges=2" \
+            "$P_CLI serialize=1 exchanges=2" \
+            0 \
+            -c "Deserializing connection..." \
+            -S "Deserializing connection..."
+
+skip_next_test
+requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
+run_test    "(STUB) Context serialization, server serializes" \
+            "$P_SRV serialize=1 exchanges=2" \
+            "$P_CLI serialize=0 exchanges=2" \
+            0 \
+            -C "Deserializing connection..." \
+            -s "Deserializing connection..."
+
+skip_next_test
+requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
+run_test    "(STUB) Context serialization, both serialize" \
+            "$P_SRV serialize=1 exchanges=2" \
+            "$P_CLI serialize=1 exchanges=2" \
+            0 \
+            -c "Deserializing connection..." \
+            -s "Deserializing connection..."
+
+skip_next_test
+requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
+run_test    "(STUB) Context serialization, re-init, client serializes" \
+            "$P_SRV serialize=0 exchanges=2" \
+            "$P_CLI serialize=2 exchanges=2" \
+            0 \
+            -c "Deserializing connection..." \
+            -S "Deserializing connection..."
+
+skip_next_test
+requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
+run_test    "(STUB) Context serialization, re-init, server serializes" \
+            "$P_SRV serialize=2 exchanges=2" \
+            "$P_CLI serialize=0 exchanges=2" \
+            0 \
+            -C "Deserializing connection..." \
+            -s "Deserializing connection..."
+
+skip_next_test
+requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION
+run_test    "(STUB) Context serialization, re-init, both serialize" \
+            "$P_SRV serialize=2 exchanges=2" \
+            "$P_CLI serialize=2 exchanges=2" \
+            0 \
+            -c "Deserializing connection..." \
+            -s "Deserializing connection..."
+
 # Tests for DTLS Connection ID extension
 
 # So far, the CID API isn't implemented, so we can't