Merge branch 'ssl_config' into development

* ssl_config: (45 commits)
  Fix warning in ssl_pthread_server
  Fix dependency issues
  Fix typos in mini_client.c
  Optimize config usage in concurrent server examples
  Fix bug introduced when splitting init functions
  Fix order of ssl_conf vs ssl_setup in programs
  Update Changelog with forgotten change
  Change a few ssl_conf return types to void
  Update Changelog for recent config split
  Fix typos in the Changelog
  Rename ssl_set_xxx() to ssl_conf_xxx()
  Add ssl_set_hs_ca_chain()
  Make conf const inside ssl_context (finally)
  Change ssl_own_cert to work on ssl_config
  Add ssl_set_hs_own_cert()
  Rework ssl_set_own_cert() internals
  Change ssl_set_psk() to act on ssl_config
  Use a specific function in the PSK callback
  Make xxx_drbg_random() thread-safe
  Move ssl_set_rng() to act on config
  ...
diff --git a/ChangeLog b/ChangeLog
index d810504..2b8a438 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,20 +10,36 @@
 
 API Changes
    * All public identifiers moved to the mbedtls_* or MBEDTLS_* namespace.
+     Some names have been further changed to make them more consistent.
      Migration helpers scripts/rename.pl and include/mbedlts/compat-1.3.h are
-     provided.
+     provided. Full list of renamings in scripts/data_files/rename-1.3-2.0.txt
    * Headers are now found in the 'mbedtls' directory (previously 'polarssl').
    * The following _init() functions that could return errors have
-     been split into an _init() that returns void and another function:
+     been split into an _init() that returns void and another function that
+     should generally be the first function called on this context after init:
      mbedtls_ssl_init() -> mbedtls_ssl_setup()
      mbedtls_ccm_init() -> mbedtls_ccm_setkey()
      mbedtls_gcm_init() -> mbedtls_gcm_setkey()
-     mbedtls_hmac_drbg_init() -> mbedtls_hmac_drbg_init(_buf)()
-     mbedtls_ctr_drbg_init()  -> mbedtls_ctr_drbg_init(_buf)()
-   * Renamed mbedtls_pkcs11_priv_key_init() to ..._bind() and
-     mbedtls_pkcs11_x509_cert_init() as well (handled by rename.pl and
-     compat-1.3.h)
-   * mbedtls_memory_bufer_alloc_init() now returns void
+     mbedtls_hmac_drbg_init() -> mbedtls_hmac_drbg_seed(_buf)()
+     mbedtls_ctr_drbg_init()  -> mbedtls_ctr_drbg_seed()
+     Note that for mbetls_ssl_setup(), you need to be done setting up the
+     ssl_config structure before calling it.
+   * Most ssl_set_xxx() functions (all except ssl_set_hostname(),
+     ssl_set_session() and ssl_set_client_transport_id(), plus
+     ssl_legacy_renegotiation()) have been renamed to mbedtls_ssl_conf_xxx()
+     (see rename.pl and compat-1.3.h above) and their first argument's type
+     changed from ssl_context to ssl_config.
+   * The following functions have been introduced and must be used in callback
+     implementations (SNI, PSK) instead of their *conf counterparts:
+     mbedtls_ssl_set_hs_own_cert()
+     mbedtls_ssl_set_hs_ca_chain()
+     mbedtls_ssl_set_hs_psk()
+   * mbedtls_ssl_conf_ca_chain() lost its last argument (peer_cn), now set
+     using mbedtls_ssl_set_hostname().
+   * mbedtls_ssl_conf_session_cache() changed prototype (only one context
+     pointer, parameters reordered).
+   * mbedtls_ssl_conf_truncated_hmac() now returns void.
+   * mbedtls_memory_bufer_alloc_init() now returns void.
    * In the threading layer, mbedtls_mutex_init() and mbedtls_mutex_free() now
      return void.
    * ecdsa_write_signature() gained an addtional md_alg argument and
@@ -39,7 +55,8 @@
      (support for renegotiation now needs explicit enabling in config.h).
    * net_connect() and net_bind() have a new 'proto' argument to choose
      between TCP and UDP, using the macros NET_PROTO_TCP or NET_PROTO_UDP.
-   * ssl_set_bio() now requires that p_send == p_recv.
+   * ssl_set_bio() changed signature (contexts merged, order switched, one
+     additional callback for read-with-timeout).
    * Some constness fixes
 
 Removals
@@ -60,7 +77,6 @@
 New deprecations
    * md_init_ctx() is deprecated in favour of md_setup(), that adds a third
      argument (allowing memory savings if HMAC is not used)
-   * ssl_set_bio() is deprecated in favour of ssl_set_bio_timeout().
 
 Semi-API changes (technically public, morally private)
    * Changed md_info_t into an opaque structure (use md_get_xxx() accessors).
@@ -80,12 +96,26 @@
    * Support for RSA_ALT contexts in the PK layer is now optional. Since is is
      enabled in the default configuration, this is only noticeable if using a
      custom config.h
+   * Default DHM parameters server-side upgraded from 1024 to 2048 bits.
+   * Negotiation of truncated HMAC is now disabled by default on server too.
 
 Reauirement changes
    * The minimum MSVC version required is now 2010 (better C99 support).
    * The NET layer now unconditionnaly relies on getaddrinfo().
    * Compiler is required to support C99 types such as long long and uint32_t.
 
+API changes from the 1.4 preview branch
+   * ssl_set_bio_timeout() was removed, split into mbedtls_ssl_set_bio() with
+     new prototype, and mbedtls_ssl_set_read_timeout().
+   * The following functions now return void:
+     mbedtls_ssl_conf_transport()
+     mbedtls_ssl_conf_max_version()
+     mbedtls_ssl_conf_min_version()
+
+Changes
+   * mbedtls_ctr_drbg_random() and mbedtls_hmac_drbg_random() are now
+     thread-safe if MBEDTLS_THREADING_C is enabled.
+
 = mbed TLS 1.3 branch
 
 Security
diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h
index 10953db..dd03b71 100644
--- a/include/mbedtls/compat-1.3.h
+++ b/include/mbedtls/compat-1.3.h
@@ -1161,10 +1161,10 @@
 #define POLARSSL_ERR_NET_RECV_FAILED MBEDTLS_ERR_NET_RECV_FAILED
 #define POLARSSL_ERR_NET_SEND_FAILED MBEDTLS_ERR_NET_SEND_FAILED
 #define POLARSSL_ERR_NET_SOCKET_FAILED MBEDTLS_ERR_NET_SOCKET_FAILED
-#define POLARSSL_ERR_NET_TIMEOUT MBEDTLS_ERR_NET_TIMEOUT
+#define POLARSSL_ERR_NET_TIMEOUT MBEDTLS_ERR_SSL_TIMEOUT
 #define POLARSSL_ERR_NET_UNKNOWN_HOST MBEDTLS_ERR_NET_UNKNOWN_HOST
-#define POLARSSL_ERR_NET_WANT_READ MBEDTLS_ERR_NET_WANT_READ
-#define POLARSSL_ERR_NET_WANT_WRITE MBEDTLS_ERR_NET_WANT_WRITE
+#define POLARSSL_ERR_NET_WANT_READ MBEDTLS_ERR_SSL_WANT_READ
+#define POLARSSL_ERR_NET_WANT_WRITE MBEDTLS_ERR_SSL_WANT_WRITE
 #define POLARSSL_ERR_OID_BUF_TOO_SMALL MBEDTLS_ERR_OID_BUF_TOO_SMALL
 #define POLARSSL_ERR_OID_NOT_FOUND MBEDTLS_ERR_OID_NOT_FOUND
 #define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED
@@ -2443,7 +2443,7 @@
 #define ssl_hw_record_write mbedtls_ssl_hw_record_write
 #define ssl_init mbedtls_ssl_init
 #define ssl_key_cert mbedtls_ssl_key_cert
-#define ssl_legacy_renegotiation mbedtls_ssl_legacy_renegotiation
+#define ssl_legacy_renegotiation mbedtls_ssl_conf_legacy_renegotiation
 #define ssl_list_ciphersuites mbedtls_ssl_list_ciphersuites
 #define ssl_md_alg_from_hash mbedtls_ssl_md_alg_from_hash
 #define ssl_optimize_checksum mbedtls_ssl_optimize_checksum
@@ -2471,49 +2471,49 @@
 #define ssl_session_free mbedtls_ssl_session_free
 #define ssl_session_init mbedtls_ssl_session_init
 #define ssl_session_reset mbedtls_ssl_session_reset
-#define ssl_set_alpn_protocols mbedtls_ssl_set_alpn_protocols
-#define ssl_set_arc4_support mbedtls_ssl_set_arc4_support
-#define ssl_set_authmode mbedtls_ssl_set_authmode
+#define ssl_set_alpn_protocols mbedtls_ssl_conf_alpn_protocols
+#define ssl_set_arc4_support mbedtls_ssl_conf_arc4_support
+#define ssl_set_authmode mbedtls_ssl_conf_authmode
 #define ssl_set_bio mbedtls_ssl_set_bio
-#define ssl_set_bio_timeout mbedtls_ssl_set_bio_timeout
-#define ssl_set_ca_chain mbedtls_ssl_set_ca_chain
-#define ssl_set_cbc_record_splitting mbedtls_ssl_set_cbc_record_splitting
-#define ssl_set_ciphersuites mbedtls_ssl_set_ciphersuites
-#define ssl_set_ciphersuites_for_version mbedtls_ssl_set_ciphersuites_for_version
+#define ssl_set_bio mbedtls_ssl_set_bio_timeout
+#define ssl_set_ca_chain mbedtls_ssl_conf_ca_chain
+#define ssl_set_cbc_record_splitting mbedtls_ssl_conf_cbc_record_splitting
+#define ssl_set_ciphersuites mbedtls_ssl_conf_ciphersuites
+#define ssl_set_ciphersuites_for_version mbedtls_ssl_conf_ciphersuites_for_version
 #define ssl_set_client_transport_id mbedtls_ssl_set_client_transport_id
-#define ssl_set_curves mbedtls_ssl_set_curves
-#define ssl_set_dbg mbedtls_ssl_set_dbg
-#define ssl_set_dh_param mbedtls_ssl_set_dh_param
-#define ssl_set_dh_param_ctx mbedtls_ssl_set_dh_param_ctx
-#define ssl_set_dtls_anti_replay mbedtls_ssl_set_dtls_anti_replay
-#define ssl_set_dtls_badmac_limit mbedtls_ssl_set_dtls_badmac_limit
-#define ssl_set_dtls_cookies mbedtls_ssl_set_dtls_cookies
-#define ssl_set_encrypt_then_mac mbedtls_ssl_set_encrypt_then_mac
-#define ssl_set_endpoint mbedtls_ssl_set_endpoint
-#define ssl_set_extended_master_secret mbedtls_ssl_set_extended_master_secret
-#define ssl_set_fallback mbedtls_ssl_set_fallback
-#define ssl_set_handshake_timeout mbedtls_ssl_set_handshake_timeout
+#define ssl_set_curves mbedtls_ssl_conf_curves
+#define ssl_set_dbg mbedtls_ssl_conf_dbg
+#define ssl_set_dh_param mbedtls_ssl_conf_dh_param
+#define ssl_set_dh_param_ctx mbedtls_ssl_conf_dh_param_ctx
+#define ssl_set_dtls_anti_replay mbedtls_ssl_conf_dtls_anti_replay
+#define ssl_set_dtls_badmac_limit mbedtls_ssl_conf_dtls_badmac_limit
+#define ssl_set_dtls_cookies mbedtls_ssl_conf_dtls_cookies
+#define ssl_set_encrypt_then_mac mbedtls_ssl_conf_encrypt_then_mac
+#define ssl_set_endpoint mbedtls_ssl_conf_endpoint
+#define ssl_set_extended_master_secret mbedtls_ssl_conf_extended_master_secret
+#define ssl_set_fallback mbedtls_ssl_conf_fallback
+#define ssl_set_handshake_timeout mbedtls_ssl_conf_handshake_timeout
 #define ssl_set_hostname mbedtls_ssl_set_hostname
-#define ssl_set_max_frag_len mbedtls_ssl_set_max_frag_len
-#define ssl_set_max_version mbedtls_ssl_set_max_version
-#define ssl_set_min_version mbedtls_ssl_set_min_version
-#define ssl_set_own_cert mbedtls_ssl_set_own_cert
+#define ssl_set_max_frag_len mbedtls_ssl_conf_max_frag_len
+#define ssl_set_max_version mbedtls_ssl_conf_max_version
+#define ssl_set_min_version mbedtls_ssl_conf_min_version
+#define ssl_set_own_cert mbedtls_ssl_conf_own_cert
 #define ssl_set_own_cert_alt mbedtls_ssl_set_own_cert_alt
 #define ssl_set_own_cert_rsa mbedtls_ssl_set_own_cert_rsa
-#define ssl_set_psk mbedtls_ssl_set_psk
-#define ssl_set_psk_cb mbedtls_ssl_set_psk_cb
-#define ssl_set_renegotiation mbedtls_ssl_set_renegotiation
-#define ssl_set_renegotiation_enforced mbedtls_ssl_set_renegotiation_enforced
-#define ssl_set_renegotiation_period mbedtls_ssl_set_renegotiation_period
-#define ssl_set_rng mbedtls_ssl_set_rng
+#define ssl_set_psk mbedtls_ssl_conf_psk
+#define ssl_set_psk_cb mbedtls_ssl_conf_psk_cb
+#define ssl_set_renegotiation mbedtls_ssl_conf_renegotiation
+#define ssl_set_renegotiation_enforced mbedtls_ssl_conf_renegotiation_enforced
+#define ssl_set_renegotiation_period mbedtls_ssl_conf_renegotiation_period
+#define ssl_set_rng mbedtls_ssl_conf_rng
 #define ssl_set_session mbedtls_ssl_set_session
-#define ssl_set_session_cache mbedtls_ssl_set_session_cache
-#define ssl_set_session_ticket_lifetime mbedtls_ssl_set_session_ticket_lifetime
-#define ssl_set_session_tickets mbedtls_ssl_set_session_tickets
-#define ssl_set_sni mbedtls_ssl_set_sni
-#define ssl_set_transport mbedtls_ssl_set_transport
-#define ssl_set_truncated_hmac mbedtls_ssl_set_truncated_hmac
-#define ssl_set_verify mbedtls_ssl_set_verify
+#define ssl_set_session_cache mbedtls_ssl_conf_session_cache
+#define ssl_set_session_ticket_lifetime mbedtls_ssl_conf_session_ticket_lifetime
+#define ssl_set_session_tickets mbedtls_ssl_conf_session_tickets
+#define ssl_set_sni mbedtls_ssl_conf_sni
+#define ssl_set_transport mbedtls_ssl_conf_transport
+#define ssl_set_truncated_hmac mbedtls_ssl_conf_truncated_hmac
+#define ssl_set_verify mbedtls_ssl_conf_verify
 #define ssl_sig_from_pk mbedtls_ssl_sig_from_pk
 #define ssl_states mbedtls_ssl_states
 #define ssl_ticket_keys mbedtls_ssl_ticket_keys
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 46cc7ae..0c72da9 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -361,7 +361,7 @@
  * Remove RC4 ciphersuites by default in SSL / TLS.
  * This flag removes the ciphersuites based on RC4 from the default list as
  * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to
- * enable (some of) them with mbedtls_ssl_set_ciphersuites() by including them
+ * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them
  * explicitly.
  *
  * Uncomment this macro to remove RC4 ciphersuites by default.
@@ -1064,7 +1064,7 @@
  *           MBEDTLS_SSL_PROTO_DTLS
  *
  * \warning Disabling this is often a security risk!
- * See mbedtls_ssl_set_dtls_anti_replay() for details.
+ * See mbedtls_ssl_conf_dtls_anti_replay() for details.
  *
  * Comment this to disable anti-replay in DTLS.
  */
@@ -1094,7 +1094,7 @@
  *
  * Enable support for a limit of records with bad MAC.
  *
- * See mbedtls_ssl_set_dtls_badmac_limit().
+ * See mbedtls_ssl_conf_dtls_badmac_limit().
  *
  * Requires: MBEDTLS_SSL_PROTO_DTLS
  */
@@ -1136,14 +1136,14 @@
 /**
  * \def MBEDTLS_SSL_SET_CURVES
  *
- * Enable mbedtls_ssl_set_curves().
+ * Enable mbedtls_ssl_conf_curves().
  *
  * This is disabled by default since it breaks binary compatibility with the
  * 1.3.x line. If you choose to enable it, you will need to rebuild your
  * application against the new header files, relinking will not be enough.
  * It will be enabled by default, or no longer an option, in the 1.4 branch.
  *
- * Uncomment to make mbedtls_ssl_set_curves() available.
+ * Uncomment to make mbedtls_ssl_conf_curves() available.
  */
 //#define MBEDTLS_SSL_SET_CURVES
 
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 3ea4af2..cebf43b 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -26,6 +26,10 @@
 
 #include "aes.h"
 
+#if defined(MBEDTLS_THREADING_C)
+#include "mbedtls/threading.h"
+#endif
+
 #define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED        -0x0034  /**< The entropy source failed. */
 #define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG              -0x0036  /**< Too many random requested in single call. */
 #define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG                -0x0038  /**< Input too large (Entropy + additional). */
@@ -99,6 +103,10 @@
     int (*f_entropy)(void *, unsigned char *, size_t);
 
     void *p_entropy;            /*!<  context for the entropy function */
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+#endif
 }
 mbedtls_ctr_drbg_context;
 
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 099fa42..c3b0b15 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -62,7 +62,7 @@
  * DES       1  0x0032-0x0032
  * CTR_DBRG  4  0x0034-0x003A
  * ENTROPY   3  0x003C-0x0040
- * NET      12  0x0042-0x0056   0x0011-0x0011
+ * NET       9  0x0042-0x0052
  * ENTROPY   1  0x0058-0x0058
  * ASN1      7  0x0060-0x006C
  * MD2       1  0x0070-0x0070
@@ -88,7 +88,7 @@
  * ECP       4   8 (Started from top)
  * MD        5   4
  * CIPHER    6   6
- * SSL       6   13 (Started from top)
+ * SSL       6   16 (Started from top)
  * SSL       7   31
  *
  * Module dependent error code (5 bits 0x.00.-0x.F8.)
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index fb2ee0e..eeac3e3 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -26,6 +26,10 @@
 
 #include "md.h"
 
+#if defined(MBEDTLS_THREADING_C)
+#include "mbedtls/threading.h"
+#endif
+
 /*
  * Error codes
  */
@@ -87,6 +91,10 @@
     /* Callbacks */
     int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */
     void *p_entropy;            /*!< context for the entropy function        */
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+#endif
 } mbedtls_hmac_drbg_context;
 
 /**
diff --git a/include/mbedtls/net.h b/include/mbedtls/net.h
index 85fa3e7..077fa3d 100644
--- a/include/mbedtls/net.h
+++ b/include/mbedtls/net.h
@@ -30,6 +30,8 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
+#include "ssl.h"
+
 #include <stddef.h>
 #include <stdint.h>
 
@@ -41,10 +43,7 @@
 #define MBEDTLS_ERR_NET_RECV_FAILED                       -0x004C  /**< Reading information from the socket failed. */
 #define MBEDTLS_ERR_NET_SEND_FAILED                       -0x004E  /**< Sending information through the socket failed. */
 #define MBEDTLS_ERR_NET_CONN_RESET                        -0x0050  /**< Connection was reset by peer. */
-#define MBEDTLS_ERR_NET_WANT_READ                         -0x0052  /**< Connection requires a read call. */
-#define MBEDTLS_ERR_NET_WANT_WRITE                        -0x0054  /**< Connection requires a write call. */
-#define MBEDTLS_ERR_NET_UNKNOWN_HOST                      -0x0056  /**< Failed to get an IP address for the given hostname. */
-#define MBEDTLS_ERR_NET_TIMEOUT                           -0x0011  /**< The operation timed out. */
+#define MBEDTLS_ERR_NET_UNKNOWN_HOST                      -0x0052  /**< Failed to get an IP address for the given hostname. */
 
 #define MBEDTLS_NET_LISTEN_BACKLOG         10 /**< The backlog that listen() should use. */
 
@@ -100,7 +99,7 @@
  *                  Must be at least 4 bytes, or 16 if IPv6 is supported
  *
  * \return          0 if successful, MBEDTLS_ERR_NET_ACCEPT_FAILED, or
- *                  MBEDTLS_ERR_NET_WANT_READ is bind_fd was set to
+ *                  MBEDTLS_ERR_SSL_WANT_READ is bind_fd was set to
  *                  non-blocking and accept() is blocking.
  *
  * \note            With UDP, connects the bind_fd to the client and just copy
@@ -148,8 +147,9 @@
  * \param len      Maximum length of the buffer
  *
  * \return         This function returns the number of bytes received,
- *                 or a non-zero error code; MBEDTLS_ERR_NET_WANT_READ
- *                 indicates read() is blocking.
+ *                 or a non-zero error code; with a non-blocking socket,
+ *                 MBEDTLS_ERR_SSL_WANT_READ indicates read() would be
+ *                 blocking.
  */
 int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len );
 
@@ -162,8 +162,9 @@
  * \param len      The length of the buffer
  *
  * \return         This function returns the number of bytes sent,
- *                 or a non-zero error code; MBEDTLS_ERR_NET_WANT_WRITE
- *                 indicates write() is blocking.
+ *                 or a non-zero error code; with a non-blocking socket,
+ *                 MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would be
+ *                 blocking.
  */
 int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
 
@@ -180,8 +181,8 @@
  *
  * \return         This function returns the number of bytes received,
  *                 or a non-zero error code:
- *                 MBEDTLS_ERR_NET_TIMEOUT if the operation timed out,
- *                 MBEDTLS_ERR_NET_WANT_READ if interrupted by a signal.
+ *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ *                 MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
  *
  * \note           This function will block (until data becomes available or
  *                 timeout is reached) even if the socket is set to
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 5f4e46e..1efb6a8 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -30,7 +30,6 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#include "net.h"
 #include "bignum.h"
 #include "ecp.h"
 
@@ -151,6 +150,9 @@
 #define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED             -0x6A80  /**< DTLS client must retry for hello verification */
 #define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL                  -0x6A00  /**< A buffer is too small to receive or write a message */
 #define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE             -0x6980  /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */
+#define MBEDTLS_ERR_SSL_WANT_READ                         -0x6900  /**< Connection requires a read call. */
+#define MBEDTLS_ERR_SSL_WANT_WRITE                        -0x6880  /**< Connection requires a write call. */
+#define MBEDTLS_ERR_SSL_TIMEOUT                           -0x6800  /**< The operation timed out. */
 
 /*
  * Various constants
@@ -258,8 +260,8 @@
 #define MBEDTLS_SSL_SESSION_TICKETS_DISABLED     0
 #define MBEDTLS_SSL_SESSION_TICKETS_ENABLED      1
 
-#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED   -1
-#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED     0
+#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED    0
+#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED     1
 
 #define MBEDTLS_SSL_ARC4_ENABLED                0
 #define MBEDTLS_SSL_ARC4_DISABLED               1
@@ -670,16 +672,16 @@
 #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
     const mbedtls_ecp_curve_info **curves;      /*!<  Supported elliptic curves */
 #endif
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    unsigned char *psk;                 /*!<  PSK from the callback         */
+    size_t psk_len;                     /*!<  Length of PSK from callback   */
+#endif
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
-    /**
-     * Current key/cert or key/cert list.
-     * On client: pointer to ssl->key_cert, only the first entry used.
-     * On server: starts as a pointer to ssl->key_cert, then becomes
-     * a pointer to the chosen key from this list or the SNI list.
-     */
-    mbedtls_ssl_key_cert *key_cert;
+    mbedtls_ssl_key_cert *key_cert;     /*!< chosen key/cert pair (server)  */
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-    mbedtls_ssl_key_cert *sni_key_cert;         /*!<  key/cert list from SNI  */
+    mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI         */
+    mbedtls_x509_crt *sni_ca_chain;     /*!< trusted CAs from SNI callback  */
+    mbedtls_x509_crl *sni_ca_crl;       /*!< trusted CAs CRLs from SNI      */
 #endif
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -786,13 +788,171 @@
 };
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
+/**
+ * SSL/TLS configuration to be shared between mbedtls_ssl_context structures.
+ */
+typedef struct
+{
+    /* Group items by size (largest first) to minimize padding overhead */
+
+    /*
+     * Pointers
+     */
+
+    const int *ciphersuite_list[4]; /*!< allowed ciphersuites per version   */
+
+    /** Callback for printing debug output                                  */
+    void (*f_dbg)(void *, int, const char *);
+    void *p_dbg;                    /*!< context for the debug function     */
+
+    /** Callback for getting (pseudo-)random numbers                        */
+    int  (*f_rng)(void *, unsigned char *, size_t);
+    void *p_rng;                    /*!< context for the RNG function       */
+
+    /** Callback to retrieve a session from the cache                       */
+    int (*f_get_cache)(void *, mbedtls_ssl_session *);
+    /** Callback to store a session into the cache                          */
+    int (*f_set_cache)(void *, const mbedtls_ssl_session *);
+    void *p_cache;                  /*!< context for cache callbacks        */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    /** Callback for setting cert according to SNI extension                */
+    int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
+    void *p_sni;                    /*!< context for SNI callback           */
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    /** Callback to customize X.509 certificate chain verification          */
+    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, int *);
+    void *p_vrfy;                   /*!< context for X.509 verify calllback */
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    /** Callback to retrieve PSK key from identity                          */
+    int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
+    void *p_psk;                    /*!< context for PSK callback           */
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+    /** Callback to create & write a cookie for ClientHello veirifcation    */
+    int (*f_cookie_write)( void *, unsigned char **, unsigned char *,
+                           const unsigned char *, size_t );
+    /** Callback to verify validity of a ClientHello cookie                 */
+    int (*f_cookie_check)( void *, const unsigned char *, size_t,
+                           const unsigned char *, size_t );
+    void *p_cookie;                 /*!< context for the cookie callbacks   */
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s)        */
+    mbedtls_x509_crt *ca_chain;     /*!< trusted CAs                        */
+    mbedtls_x509_crl *ca_crl;       /*!< trusted CAs CRLs                   */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_SET_CURVES)
+    const mbedtls_ecp_group_id *curve_list; /*!< allowed curves             */
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+    mbedtls_mpi dhm_P;              /*!< prime modulus for DHM              */
+    mbedtls_mpi dhm_G;              /*!< generator for DHM                  */
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    unsigned char *psk;             /*!< pre-shared key                     */
+    size_t         psk_len;         /*!< length of the pre-shared key       */
+    unsigned char *psk_identity;    /*!< identity for PSK negotiation       */
+    size_t         psk_identity_len;/*!< length of identity                 */
+#endif
+
+#if defined(MBEDTLS_SSL_ALPN)
+    const char **alpn_list;         /*!< ordered list of protocols          */
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    mbedtls_ssl_ticket_keys *ticket_keys;       /*!<  keys for ticket encryption */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+    /*
+     * Numerical settings (int then char)
+     */
+
+    uint32_t read_timeout;          /*!< timeout for mbedtls_ssl_read (ms)  */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    uint32_t hs_timeout_min;        /*!< initial value of the handshake
+                                         retransmission timeout (ms)        */
+    uint32_t hs_timeout_max;        /*!< maximum value of the handshake
+                                         retransmission timeout (ms)        */
+#endif
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    int renego_max_records;         /*!< grace period for renegotiation     */
+    unsigned char renego_period[8]; /*!< value of the record counters
+                                         that triggers renegotiation        */
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+    unsigned int badmac_limit;      /*!< limit of records with a bad MAC    */
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    int ticket_lifetime;            /*!< session ticket lifetime (seconds)  */
+#endif
+
+    unsigned char max_major_ver;    /*!< max. major version used            */
+    unsigned char max_minor_ver;    /*!< max. minor version used            */
+    unsigned char min_major_ver;    /*!< min. major version used            */
+    unsigned char min_minor_ver;    /*!< min. minor version used            */
+
+    /*
+     * Flags (bitfields)
+     */
+
+    unsigned int endpoint : 1;      /*!< 0: client, 1: server               */
+    unsigned int transport : 1;     /*!< stream (TLS) or datagram (DTLS)    */
+    unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites?        */
+    unsigned int authmode : 2;      /*!< MBEDTLS_SSL_VERIFY_XXX             */
+    /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE          */
+    unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX   */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    unsigned int mfl_code : 3;      /*!< desired fragment length            */
+#endif
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac?    */
+#endif
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    unsigned int extended_ms : 1;   /*!< negotiate extended master secret?  */
+#endif
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    unsigned int anti_replay : 1;   /*!< detect and prevent replay?         */
+#endif
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+    unsigned int cbc_record_splitting : 1;  /*!< do cbc record splitting    */
+#endif
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    unsigned int disable_renegotiation : 1; /*!< disable renegotiation?     */
+#endif
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+    unsigned int trunc_hmac : 1;    /*!< negotiate truncated hmac?          */
+#endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    unsigned int session_tickets : 1;   /*!< use session tickets?           */
+#endif
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
+    unsigned int fallback : 1;      /*!< is this a fallback?                */
+#endif
+}
+mbedtls_ssl_config;
+
 struct mbedtls_ssl_context
 {
+    const mbedtls_ssl_config *conf; /*!< configuration information          */
+
     /*
      * Miscellaneous
      */
     int state;                  /*!< SSL handshake: current state     */
-    int transport;              /*!< Transport: stream or datagram    */
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
     int renego_status;          /*!< Initial, in progress, pending?   */
     int renego_records_seen;    /*!< Records since renego request, or with DTLS,
@@ -803,61 +963,17 @@
     int major_ver;              /*!< equal to  MBEDTLS_SSL_MAJOR_VERSION_3    */
     int minor_ver;              /*!< either 0 (SSL3) or 1 (TLS1.0)    */
 
-    int max_major_ver;          /*!< max. major version used          */
-    int max_minor_ver;          /*!< max. minor version used          */
-    int min_major_ver;          /*!< min. major version used          */
-    int min_minor_ver;          /*!< min. minor version used          */
-
-    uint32_t read_timeout;      /*!< timeout for mbedtls_ssl_read in milliseconds */
-
 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
-    unsigned badmac_limit;      /*!< limit of records with a bad MAC    */
     unsigned badmac_seen;       /*!< records with a bad MAC received    */
 #endif
 
-#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
-    char fallback;              /*!< flag for fallback connections    */
-#endif
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    char encrypt_then_mac;      /*!< flag for encrypt-then-mac        */
-#endif
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    char extended_ms;           /*!< flag for extended master secret  */
-#endif
-    char arc4_disabled;         /*!< flag for disabling RC4           */
-
     /*
-     * Callbacks (RNG, debug, I/O, verification)
+     * Callbacks
      */
-    int  (*f_rng)(void *, unsigned char *, size_t);
-    void (*f_dbg)(void *, int, const char *);
     int (*f_send)(void *, const unsigned char *, size_t);
     int (*f_recv)(void *, unsigned char *, size_t);
     int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t);
-    int (*f_get_cache)(void *, mbedtls_ssl_session *);
-    int (*f_set_cache)(void *, const mbedtls_ssl_session *);
-
-    void *p_rng;                /*!< context for the RNG function     */
-    void *p_dbg;                /*!< context for the debug function   */
     void *p_bio;                /*!< context for I/O operations   */
-    void *p_get_cache;          /*!< context for cache retrieval      */
-    void *p_set_cache;          /*!< context for cache store          */
-    void *p_hw_data;            /*!< context for HW acceleration      */
-
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-    int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
-    void *p_sni;                /*!< context for SNI extension        */
-#endif
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, int *);
-    void *p_vrfy;               /*!< context for verification         */
-#endif
-
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
-    void *p_psk;               /*!< context for PSK retrieval         */
-#endif
 
     /*
      * Session layer
@@ -884,10 +1000,6 @@
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     struct mbedtls_timing_hr_time time_info;   /*!< timer context                      */
     unsigned long time_limit;   /*!< limit for the running timer        */
-    uint32_t hs_timeout_min;    /*!< initial value of the handshake
-                                     retransmission timeout             */
-    uint32_t hs_timeout_max;    /*!< maximum value of the handshake
-                                     retransmission timeout             */
 #endif
 
     /*
@@ -914,7 +1026,6 @@
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
     uint64_t in_window_top;     /*!< last validated record seq_num    */
     uint64_t in_window;         /*!< bitmask for replay detection     */
-    char anti_replay;           /*!< is anti-replay on?               */
 #endif
 
     size_t in_hslen;            /*!< current handshake message length,
@@ -939,87 +1050,25 @@
 #if defined(MBEDTLS_ZLIB_SUPPORT)
     unsigned char *compress_buf;        /*!<  zlib data buffer        */
 #endif
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-    unsigned char mfl_code;     /*!< MaxFragmentLength chosen by us   */
-#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
-    signed char split_done;     /*!< flag for record splitting:
-                                     -1 disabled, 0 todo, 1 done      */
+    signed char split_done;     /*!< current record already splitted? */
 #endif
 
     /*
      * PKI layer
      */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-    mbedtls_ssl_key_cert *key_cert;             /*!<  own certificate(s)/key(s) */
-
-    mbedtls_x509_crt *ca_chain;                 /*!<  own trusted CA chain      */
-    mbedtls_x509_crl *ca_crl;                   /*!<  trusted CA CRLs           */
-    const char *peer_cn;                /*!<  expected peer CN          */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
-    /*
-     * Support for generating and checking session tickets
-     */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    mbedtls_ssl_ticket_keys *ticket_keys;       /*!<  keys for ticket encryption */
-#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+    int client_auth;                    /*!<  flag for client auth.   */
+    int verify_result;                  /*!<  verification result     */
 
     /*
      * User settings
      */
-    int endpoint;                       /*!<  0: client, 1: server    */
-    int authmode;                       /*!<  verification mode       */
-    int client_auth;                    /*!<  flag for client auth.   */
-    int verify_result;                  /*!<  verification result     */
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
-    int disable_renegotiation;          /*!<  enable/disable renegotiation   */
-    int renego_max_records;             /*!<  grace period for renegotiation */
-    unsigned char renego_period[8];     /*!<  value of the record counters
-                                              that triggers renegotiation    */
-#endif
-    /* needed for option break handshake with insecure peers */
-    int allow_legacy_renegotiation;     /*!<  allow legacy renegotiation     */
-    const int *ciphersuite_list[4];     /*!<  allowed ciphersuites / version */
-#if defined(MBEDTLS_SSL_SET_CURVES)
-    const mbedtls_ecp_group_id *curve_list;     /*!<  allowed curves                 */
-#endif
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-    int trunc_hmac;                     /*!<  negotiate truncated hmac?      */
-#endif
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    int session_tickets;                /*!<  use session tickets?    */
-    int ticket_lifetime;                /*!<  session ticket lifetime */
-#endif
-
-#if defined(MBEDTLS_DHM_C)
-    mbedtls_mpi dhm_P;                          /*!<  prime modulus for DHM   */
-    mbedtls_mpi dhm_G;                          /*!<  generator for DHM       */
-#endif
-
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    /*
-     * PSK values
-     */
-    unsigned char *psk;
-    size_t         psk_len;
-    unsigned char *psk_identity;
-    size_t         psk_identity_len;
-#endif
-
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-    /*
-     * SNI extension
-     */
-    unsigned char *hostname;
-    size_t         hostname_len;
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    char *hostname;             /*!< expected peer CN for verification
+                                     (and SNI if available)                 */
 #endif
 
 #if defined(MBEDTLS_SSL_ALPN)
-    /*
-     * ALPN extension
-     */
-    const char **alpn_list;     /*!<  ordered list of supported protocols   */
     const char *alpn_chosen;    /*!<  negotiated protocol                   */
 #endif
 
@@ -1029,11 +1078,6 @@
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
     unsigned char  *cli_id;         /*!<  transport-level ID of the client  */
     size_t          cli_id_len;     /*!<  length of cli_id                  */
-    int (*f_cookie_write)( void *, unsigned char **, unsigned char *,
-                           const unsigned char *, size_t );
-    int (*f_cookie_check)( void *, const unsigned char *, size_t,
-                           const unsigned char *, size_t );
-    void *p_cookie;                 /*!<  context for the cookie callbacks  */
 #endif
 
     /*
@@ -1108,12 +1152,20 @@
 /**
  * \brief          Set up an SSL context for use
  *
+ * \note           No copy of the configuration context is made, it can be
+ *                 shared by many ssl_context structures.
+ *
+ * \warning        Modifying the conf structure after is has been used in this
+ *                 function is unsupported!
+ *
  * \param ssl      SSL context
+ * \param conf     SSL configuration to use
  *
  * \return         0 if successful, or MBEDTLS_ERR_SSL_MALLOC_FAILED if
  *                 memory allocation failed
  */
-int mbedtls_ssl_setup( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
+                       const mbedtls_ssl_config *conf );
 
 /**
  * \brief          Reset an already initialized SSL context for re-use
@@ -1130,37 +1182,31 @@
 /**
  * \brief          Set the current endpoint type
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER
- *
- * \note           This function should be called right after mbedtls_ssl_init() since
- *                 some other ssl_set_foo() functions depend on it.
  */
-void mbedtls_ssl_set_endpoint( mbedtls_ssl_context *ssl, int endpoint );
+void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint );
 
 /**
  * \brief           Set the transport type (TLS or DTLS).
  *                  Default: TLS
  *
- * \param ssl       SSL context
+ * \note            For DTLS, you must either provide a recv callback that
+ *                  doesn't block, or one that handles timeouts, see
+ *                  mbedtls_ssl_conf_bio()
+ *
+ * \param conf      SSL configuration
  * \param transport transport type:
  *                  MBEDTLS_SSL_TRANSPORT_STREAM for TLS,
  *                  MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS.
- * \return          0 on success or MBEDTLS_ERR_SSL_BAD_INPUT_DATA
- *
- * \note            If DTLS is selected and max and/or min version are less
- *                  than TLS 1.1 (DTLS 1.0) they are upped to that value.
- *
- * \note            For DTLS, you must either provide a recv callback that
- *                  doesn't block, or one that handles timeouts, see
- *                  mbedtls_ssl_set_bio_timeout()
  */
-int mbedtls_ssl_set_transport( mbedtls_ssl_context *ssl, int transport );
+void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport );
 
 /**
  * \brief          Set the certificate verification mode
+ *                 Default: NONE on server, REQUIRED on client
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param authmode can be:
  *
  *  MBEDTLS_SSL_VERIFY_NONE:      peer certificate is not checked
@@ -1181,7 +1227,7 @@
  * the verification as soon as possible. For example, REQUIRED was protecting
  * against the "triple handshake" attack even before it was found.
  */
-void mbedtls_ssl_set_authmode( mbedtls_ssl_context *ssl, int authmode );
+void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode );
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 /**
@@ -1191,11 +1237,11 @@
  *                 certificate in the chain. For implementation
  *                 information, please see \c x509parse_verify()
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param f_vrfy   verification function
  * \param p_vrfy   verification parameter
  */
-void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, int *),
                      void *p_vrfy );
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
@@ -1203,53 +1249,25 @@
 /**
  * \brief          Set the random number generator callback
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param f_rng    RNG function
  * \param p_rng    RNG parameter
  */
-void mbedtls_ssl_set_rng( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
                   int (*f_rng)(void *, unsigned char *, size_t),
                   void *p_rng );
 
 /**
  * \brief          Set the debug callback
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param f_dbg    debug function
  * \param p_dbg    debug parameter
  */
-void mbedtls_ssl_set_dbg( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
                   void (*f_dbg)(void *, int, const char *),
                   void  *p_dbg );
 
-#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
-#if defined(MBEDTLS_DEPRECATED_WARNING)
-#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
-#else
-#define MBEDTLS_DEPRECATED
-#endif
-/**
- * \brief          Set the underlying BIO read and write callbacks
- *
- * \param ssl      SSL context
- * \param f_recv   read callback
- * \param p_recv   read parameter (must be equal to write parameter)
- * \param f_send   write callback
- * \param p_send   write parameter (must be equal to read parameter)
- *
- * \warning        It is required that p_recv == p_send. Otherwise, the first
- *                 attempt at sending or receiving will result in a
- *                 MBEDTLS_ERR_SSL_BAD_INPUT_DATA error.
- *
- * \deprecated     Superseded by mbedtls_ssl_set_bio_timeout() in 2.0.0
- */
-void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
-        int (*f_recv)(void *, unsigned char *, size_t), void *p_recv,
-        int (*f_send)(void *, const unsigned char *, size_t), void *p_send ) MBEDTLS_DEPRECATED;
-#undef MBEDTLS_DEPRECATED
-#endif /* MBEDTLS_DEPRECATED_REMOVED */
-
-#if defined(MBEDTLS_SSL_SRV_C)
 /**
  * \brief          Set the underlying BIO callbacks for write, read and
  *                 read-with-timeout.
@@ -1258,21 +1276,32 @@
  * \param p_bio    parameter (context) shared by BIO callbacks
  * \param f_send   write callback
  * \param f_recv   read callback
- * \param f_recv_timeout read callback with timeout.
+ * \param f_recv_timeout blocking read callback with timeout.
  *                 The last argument of the callback is the timeout in seconds
- * \param timeout  value of the mbedtls_ssl_read() timeout in milliseconds
  *
  * \note           f_recv_timeout is required for DTLS, unless f_recv performs
  *                 non-blocking reads.
  *
  * \note           TODO: timeout not supported with TLS yet
  */
-void mbedtls_ssl_set_bio_timeout( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
         void *p_bio,
         int (*f_send)(void *, const unsigned char *, size_t),
         int (*f_recv)(void *, unsigned char *, size_t),
-        int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t),
-        uint32_t timeout );
+        int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) );
+
+/**
+ * \brief          Set the timeout period for mbedtls_ssl_read()
+ *                 (Default: no timeout.)
+ *
+ * \param conf     SSL configuration context
+ * \param timeout  Timeout value in milliseconds.
+ *                 Use 0 for no timeout (default).
+ *
+ * \note           With blocking I/O, this will only work if a non-NULL
+ *                 \c f_recv_timeout was set with \c mbedtls_ssl_set_bio().
+ */
+void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
 /**
@@ -1347,12 +1376,12 @@
  *                  Only disable if you known this can't happen in your
  *                  particular environment.
  *
- * \param ssl               SSL context
+ * \param conf              SSL configuration
  * \param f_cookie_write    Cookie write callback
  * \param f_cookie_check    Cookie check callback
  * \param p_cookie          Context for both callbacks
  */
-void mbedtls_ssl_set_dtls_cookies( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
                            mbedtls_ssl_cookie_write_t *f_cookie_write,
                            mbedtls_ssl_cookie_check_t *f_cookie_check,
                            void *p_cookie );
@@ -1364,7 +1393,7 @@
  *                 (DTLS only, no effect on TLS.)
  *                 Default: enabled.
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param mode     MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED.
  *
  * \warning        Disabling this is a security risk unless the application
@@ -1374,7 +1403,7 @@
  *                 packets and needs information about them to adjust its
  *                 transmission strategy, then you'll want to disable this.
  */
-void mbedtls_ssl_set_dtls_anti_replay( mbedtls_ssl_context *ssl, char mode );
+void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode );
 #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
 
 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
@@ -1384,7 +1413,7 @@
  *                 (DTLS only, no effect on TLS.)
  *                 Default: 0 (disabled).
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param limit    Limit, or 0 to disable.
  *
  * \note           If the limit is N, then the connection is terminated when
@@ -1401,7 +1430,7 @@
  *                 might make us waste resources checking authentication on
  *                 many bogus packets.
  */
-void mbedtls_ssl_set_dtls_badmac_limit( mbedtls_ssl_context *ssl, unsigned limit );
+void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit );
 #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -1409,7 +1438,7 @@
  * \brief          Set retransmit timeout values for the DTLS handshale.
  *                 (DTLS only, no effect on TLS.)
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param min      Initial timeout value in milliseconds.
  *                 Default: 1000 (1 second).
  * \param max      Maximum timeout value in milliseconds.
@@ -1421,9 +1450,10 @@
  *                 handshake latency. Lower values may increase the risk of
  *                 network congestion by causing more retransmissions.
  */
-void mbedtls_ssl_set_handshake_timeout( mbedtls_ssl_context *ssl, uint32_t min, uint32_t max );
+void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max );
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
+#if defined(MBEDTLS_SSL_SRV_C)
 /**
  * \brief          Set the session cache callbacks (server-side only)
  *                 If not set, no session resuming is done (except if session
@@ -1456,15 +1486,15 @@
  *                 an entry is still valid in the future. Return 0 if
  *                 successfully cached, return 1 otherwise.
  *
- * \param ssl            SSL context
+ * \param conf           SSL configuration
+ * \param p_cache        parmater (context) for both callbacks
  * \param f_get_cache    session get callback
- * \param p_get_cache    session get parameter
  * \param f_set_cache    session set callback
- * \param p_set_cache    session set parameter
  */
-void mbedtls_ssl_set_session_cache( mbedtls_ssl_context *ssl,
-        int (*f_get_cache)(void *, mbedtls_ssl_session *), void *p_get_cache,
-        int (*f_set_cache)(void *, const mbedtls_ssl_session *), void *p_set_cache );
+void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
+        void *p_cache,
+        int (*f_get_cache)(void *, mbedtls_ssl_session *),
+        int (*f_set_cache)(void *, const mbedtls_ssl_session *) );
 #endif /* MBEDTLS_SSL_SRV_C */
 
 #if defined(MBEDTLS_SSL_CLI_C)
@@ -1494,17 +1524,18 @@
  *                      over the preference of the client unless
  *                      MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined!
  *
- * \param ssl           SSL context
+ * \param conf          SSL configuration
  * \param ciphersuites  0-terminated list of allowed ciphersuites
  */
-void mbedtls_ssl_set_ciphersuites( mbedtls_ssl_context *ssl, const int *ciphersuites );
+void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
+                                   const int *ciphersuites );
 
 /**
  * \brief               Set the list of allowed ciphersuites and the
  *                      preference order for a specific version of the protocol.
  *                      (Only useful on the server side)
  *
- * \param ssl           SSL context
+ * \param conf          SSL configuration
  * \param ciphersuites  0-terminated list of allowed ciphersuites
  * \param major         Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3
  *                      supported)
@@ -1515,7 +1546,7 @@
  * \note                With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0
  *                      and MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
  */
-void mbedtls_ssl_set_ciphersuites_for_version( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
                                        const int *ciphersuites,
                                        int major, int minor );
 
@@ -1523,13 +1554,13 @@
 /**
  * \brief          Set the data required to verify peer certificate
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs)
  * \param ca_crl   trusted CA CRLs
- * \param peer_cn  expected peer CommonName (or NULL)
  */
-void mbedtls_ssl_set_ca_chain( mbedtls_ssl_context *ssl, mbedtls_x509_crt *ca_chain,
-                       mbedtls_x509_crl *ca_crl, const char *peer_cn );
+void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
+                               mbedtls_x509_crt *ca_chain,
+                               mbedtls_x509_crl *ca_crl );
 
 /**
  * \brief          Set own certificate chain and private key
@@ -1538,27 +1569,35 @@
  *                 certificate chain. The top certificate (self-signed)
  *                 can be omitted.
  *
- * \note           This function may be called more than once if you want to
- *                 support multiple certificates (eg, one using RSA and one
- *                 using ECDSA). However, on client, currently only the first
- *                 certificate is used (subsequent calls have no effect).
+ * \note           On server, this function can be called multiple times to
+ *                 provision more than one cert/key pair (eg one ECDSA, one
+ *                 RSA with SHA-256, one RSA with SHA-1). An adequate
+ *                 certificate will be selected according to the client's
+ *                 advertised capabilities. In case mutliple certificates are
+ *                 adequate, preference is given to the one set by the first
+ *                 call to this function, then second, etc.
  *
- * \param ssl      SSL context
+ * \note           On client, only the first call has any effect.
+ *
+ * \param conf     SSL configuration
  * \param own_cert own public certificate chain
  * \param pk_key   own private key
  *
  * \return         0 on success or MBEDTLS_ERR_SSL_MALLOC_FAILED
  */
-int mbedtls_ssl_set_own_cert( mbedtls_ssl_context *ssl, mbedtls_x509_crt *own_cert,
-                       mbedtls_pk_context *pk_key );
+int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
+                              mbedtls_x509_crt *own_cert,
+                              mbedtls_pk_context *pk_key );
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
 /**
- * \brief          Set the Pre Shared Key (PSK) and the identity name connected
- *                 to it.
+ * \brief          Set the Pre Shared Key (PSK) and the expected identity name
  *
- * \param ssl      SSL context
+ * \note           This is mainly useful for clients. Servers will usually
+ *                 want to use \c mbedtls_ssl_conf_psk_cb() instead.
+ *
+ * \param conf     SSL configuration
  * \param psk      pointer to the pre-shared key
  * \param psk_len  pre-shared key length
  * \param psk_identity      pointer to the pre-shared key identity
@@ -1566,11 +1605,28 @@
  *
  * \return         0 if successful or MBEDTLS_ERR_SSL_MALLOC_FAILED
  */
-int mbedtls_ssl_set_psk( mbedtls_ssl_context *ssl, const unsigned char *psk, size_t psk_len,
-                 const unsigned char *psk_identity, size_t psk_identity_len );
+int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
+                const unsigned char *psk, size_t psk_len,
+                const unsigned char *psk_identity, size_t psk_identity_len );
+
 
 /**
- * \brief          Set the PSK callback (server-side only) (Optional).
+ * \brief          Set the Pre Shared Key (PSK) for the current handshake
+ *
+ * \note           This should only be called inside the PSK callback,
+ *                 ie the function passed to \c mbedtls_ssl_conf_psk_cb().
+ *
+ * \param ssl      SSL context
+ * \param psk      pointer to the pre-shared key
+ * \param psk_len  pre-shared key length
+ *
+ * \return         0 if successful or MBEDTLS_ERR_SSL_MALLOC_FAILED
+ */
+int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
+                            const unsigned char *psk, size_t psk_len );
+
+/**
+ * \brief          Set the PSK callback (server-side only).
  *
  *                 If set, the PSK callback is called for each
  *                 handshake where a PSK ciphersuite was negotiated.
@@ -1581,44 +1637,48 @@
  *                 mbedtls_ssl_context *ssl, const unsigned char *psk_identity,
  *                 size_t identity_len)
  *                 If a valid PSK identity is found, the callback should use
- *                 mbedtls_ssl_set_psk() on the ssl context to set the correct PSK and
- *                 identity and return 0.
+ *                 \c mbedtls_ssl_set_hs_psk() on the ssl context to set the
+ *                 correct PSK and return 0.
  *                 Any other return value will result in a denied PSK identity.
  *
- * \param ssl      SSL context
+ * \note           If you set a PSK callback using this function, then you
+ *                 don't need to set a PSK key and identity using
+ *                 \c mbedtls_ssl_conf_psk().
+ *
+ * \param conf     SSL configuration
  * \param f_psk    PSK identity function
  * \param p_psk    PSK identity parameter
  */
-void mbedtls_ssl_set_psk_cb( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
                      int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
                                   size_t),
                      void *p_psk );
 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
-#if defined(MBEDTLS_DHM_C)
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
 /**
  * \brief          Set the Diffie-Hellman public P and G values,
  *                 read as hexadecimal strings (server-side only)
- *                 (Default: MBEDTLS_DHM_RFC5114_MODP_1024_[PG])
+ *                 (Default: MBEDTLS_DHM_RFC5114_MODP_2048_[PG])
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param dhm_P    Diffie-Hellman-Merkle modulus
  * \param dhm_G    Diffie-Hellman-Merkle generator
  *
  * \return         0 if successful
  */
-int mbedtls_ssl_set_dh_param( mbedtls_ssl_context *ssl, const char *dhm_P, const char *dhm_G );
+int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G );
 
 /**
  * \brief          Set the Diffie-Hellman public P and G values,
  *                 read from existing context (server-side only)
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param dhm_ctx  Diffie-Hellman-Merkle context
  *
  * \return         0 if successful
  */
-int mbedtls_ssl_set_dh_param_ctx( mbedtls_ssl_context *ssl, mbedtls_dhm_context *dhm_ctx );
+int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx );
 #endif /* MBEDTLS_DHM_C */
 
 #if defined(MBEDTLS_SSL_SET_CURVES)
@@ -1636,14 +1696,14 @@
  *                 Both sides: limits the set of curves used by peer to the
  *                 listed curves for any use (ECDH(E), certificates).
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param curves   Ordered list of allowed curves,
  *                 terminated by MBEDTLS_ECP_DP_NONE.
  */
-void mbedtls_ssl_set_curves( mbedtls_ssl_context *ssl, const mbedtls_ecp_group_id *curves );
+void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, const mbedtls_ecp_group_id *curves );
 #endif /* MBEDTLS_SSL_SET_CURVES */
 
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
 /**
  * \brief          Set hostname for ServerName TLS extension
  *                 (client-side only)
@@ -1655,6 +1715,39 @@
  * \return         0 if successful or MBEDTLS_ERR_SSL_MALLOC_FAILED
  */
 int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+/**
+ * \brief          Set own certificate and key for the current handshake
+ *
+ * \note           Same as \c mbedtls_ssl_conf_own_cert() but for use within
+ *                 the SNI callback.
+ *
+ * \param ssl      SSL context
+ * \param own_cert own public certificate chain
+ * \param pk_key   own private key
+ *
+ * \return         0 on success or MBEDTLS_ERR_SSL_MALLOC_FAILED
+ */
+int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl,
+                                 mbedtls_x509_crt *own_cert,
+                                 mbedtls_pk_context *pk_key );
+
+/**
+ * \brief          Set the data required to verify peer certificate for the
+ *                 current handshake
+ *
+ * \note           Same as \c mbedtls_ssl_conf_ca_chain() but for use within
+ *                 the SNI callback.
+ *
+ * \param ssl      SSL context
+ * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs)
+ * \param ca_crl   trusted CA CRLs
+ */
+void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
+                                  mbedtls_x509_crt *ca_chain,
+                                  mbedtls_x509_crl *ca_crl );
 
 /**
  * \brief          Set server side ServerName TLS extension callback
@@ -1666,16 +1759,17 @@
  *                 following parameters: (void *parameter, mbedtls_ssl_context *ssl,
  *                 const unsigned char *hostname, size_t len). If a suitable
  *                 certificate is found, the callback should set the
- *                 certificate and key to use with mbedtls_ssl_set_own_cert() (and
- *                 possibly adjust the CA chain as well) and return 0. The
- *                 callback should return -1 to abort the handshake at this
- *                 point.
+ *                 certificate(s) and key(s) to use with \c
+ *                 mbedtls_ssl_set_hs_own_cert() (can be called repeatedly),
+ *                 and optionally adjust the CA with \c
+ *                 mbedtls_ssl_set_hs_ca_chain() and return 0. The callback
+ *                 should return -1 to abort the handshake at this point.
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param f_sni    verification function
  * \param p_sni    verification parameter
  */
-void mbedtls_ssl_set_sni( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
                   int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *,
                                size_t),
                   void *p_sni );
@@ -1685,13 +1779,13 @@
 /**
  * \brief          Set the supported Application Layer Protocols.
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param protos   NULL-terminated list of supported protocols,
  *                 in decreasing preference order.
  *
  * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
  */
-int mbedtls_ssl_set_alpn_protocols( mbedtls_ssl_context *ssl, const char **protos );
+int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos );
 
 /**
  * \brief          Get the name of the negotiated Application Layer Protocol.
@@ -1710,19 +1804,18 @@
  *                 and/or accepted at the server side
  *                 (Default: MBEDTLS_SSL_MAX_MAJOR_VERSION, MBEDTLS_SSL_MAX_MINOR_VERSION)
  *
- *                 Note: This ignores ciphersuites from 'higher' versions.
+ * \note           This ignores ciphersuites from higher versions.
  *
- * \param ssl      SSL context
+ * \note           With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and
+ *                 MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
+ *
+ * \param conf     SSL configuration
  * \param major    Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
  * \param minor    Minor version number (MBEDTLS_SSL_MINOR_VERSION_0,
  *                 MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
  *                 MBEDTLS_SSL_MINOR_VERSION_3 supported)
- * \return         0 on success or MBEDTLS_ERR_SSL_BAD_INPUT_DATA
- *
- * \note           With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and
- *                 MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
  */
-int mbedtls_ssl_set_max_version( mbedtls_ssl_context *ssl, int major, int minor );
+void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor );
 
 /**
  * \brief          Set the minimum accepted SSL/TLS protocol version
@@ -1733,17 +1826,16 @@
  *
  * \note           MBEDTLS_SSL_MINOR_VERSION_0 (SSL v3) should be avoided.
  *
- * \param ssl      SSL context
+ * \note           With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and
+ *                 MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
+ *
+ * \param conf     SSL configuration
  * \param major    Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
  * \param minor    Minor version number (MBEDTLS_SSL_MINOR_VERSION_0,
  *                 MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
  *                 MBEDTLS_SSL_MINOR_VERSION_3 supported)
- * \return         0 on success or MBEDTLS_ERR_SSL_BAD_INPUT_DATA
- *
- * \note           With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and
- *                 MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
  */
-int mbedtls_ssl_set_min_version( mbedtls_ssl_context *ssl, int major, int minor );
+void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor );
 
 #if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
 /**
@@ -1762,10 +1854,10 @@
  *                 while, then cause failures when the server is upgraded to
  *                 support a newer TLS version.
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param fallback MBEDTLS_SSL_IS_NOT_FALLBACK or MBEDTLS_SSL_IS_FALLBACK
  */
-void mbedtls_ssl_set_fallback( mbedtls_ssl_context *ssl, char fallback );
+void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback );
 #endif /* MBEDTLS_SSL_FALLBACK_SCSV && MBEDTLS_SSL_CLI_C */
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
@@ -1777,10 +1869,10 @@
  *                  improvement, and should not cause any interoperability
  *                  issue (used only if the peer supports it too).
  *
- * \param ssl       SSL context
+ * \param conf      SSL configuration
  * \param etm       MBEDTLS_SSL_ETM_ENABLED or MBEDTLS_SSL_ETM_DISABLED
  */
-void mbedtls_ssl_set_encrypt_then_mac( mbedtls_ssl_context *ssl, char etm );
+void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm );
 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
@@ -1792,10 +1884,10 @@
  *                  protocol, and should not cause any interoperability issue
  *                  (used only if the peer supports it too).
  *
- * \param ssl       SSL context
+ * \param conf      SSL configuration
  * \param ems       MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED
  */
-void mbedtls_ssl_set_extended_master_secret( mbedtls_ssl_context *ssl, char ems );
+void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems );
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
 /**
@@ -1808,10 +1900,10 @@
  * \note           This function will likely be removed in future versions as
  *                 RC4 will then be disabled by default at compile time.
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param arc4     MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED
  */
-void mbedtls_ssl_set_arc4_support( mbedtls_ssl_context *ssl, char arc4 );
+void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 );
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 /**
@@ -1822,29 +1914,26 @@
  *                 (Client: set maximum fragment length to emit *and*
  *                 negotiate with the server during handshake)
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param mfl_code Code for maximum fragment length (allowed values:
  *                 MBEDTLS_SSL_MAX_FRAG_LEN_512,  MBEDTLS_SSL_MAX_FRAG_LEN_1024,
  *                 MBEDTLS_SSL_MAX_FRAG_LEN_2048, MBEDTLS_SSL_MAX_FRAG_LEN_4096)
  *
  * \return         O if successful or MBEDTLS_ERR_SSL_BAD_INPUT_DATA
  */
-int mbedtls_ssl_set_max_frag_len( mbedtls_ssl_context *ssl, unsigned char mfl_code );
+int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code );
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
 /**
  * \brief          Activate negotiation of truncated HMAC
- *                 (Default: MBEDTLS_SSL_TRUNC_HMAC_DISABLED on client,
- *                           MBEDTLS_SSL_TRUNC_HMAC_ENABLED on server.)
+ *                 (Default: MBEDTLS_SSL_TRUNC_HMAC_DISABLED)
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param truncate Enable or disable (MBEDTLS_SSL_TRUNC_HMAC_ENABLED or
  *                                    MBEDTLS_SSL_TRUNC_HMAC_DISABLED)
- *
- * \return         Always 0.
  */
-int mbedtls_ssl_set_truncated_hmac( mbedtls_ssl_context *ssl, int truncate );
+void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate );
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
 
 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
@@ -1855,11 +1944,11 @@
  * \note           Only affects SSLv3 and TLS 1.0, not higher versions.
  *                 Does not affect non-CBC ciphersuites in any version.
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param split    MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED or
  *                 MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED
  */
-void mbedtls_ssl_set_cbc_record_splitting( mbedtls_ssl_context *ssl, char split );
+void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split );
 #endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@@ -1868,27 +1957,27 @@
  *                 (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED on client,
  *                           MBEDTLS_SSL_SESSION_TICKETS_DISABLED on server)
  *
- * \note           On server, mbedtls_ssl_set_rng() must be called before this function
+ * \note           On server, mbedtls_ssl_conf_rng() must be called before this function
  *                 to allow generating the ticket encryption and
  *                 authentication keys.
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param use_tickets   Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or
  *                                         MBEDTLS_SSL_SESSION_TICKETS_DISABLED)
  *
  * \return         O if successful,
  *                 or a specific error code (server only).
  */
-int mbedtls_ssl_set_session_tickets( mbedtls_ssl_context *ssl, int use_tickets );
+int mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets );
 
 /**
  * \brief          Set session ticket lifetime (server only)
  *                 (Default: MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME (86400 secs / 1 day))
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param lifetime session ticket lifetime
  */
-void mbedtls_ssl_set_session_ticket_lifetime( mbedtls_ssl_context *ssl, int lifetime );
+void mbedtls_ssl_conf_session_ticket_lifetime( mbedtls_ssl_config *conf, int lifetime );
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -1901,11 +1990,11 @@
  *                 resource DoS by a malicious client. You should enable this on
  *                 a client to enable server-initiated renegotiation.
  *
- * \param ssl      SSL context
+ * \param conf    SSL configuration
  * \param renegotiation     Enable or disable (MBEDTLS_SSL_RENEGOTIATION_ENABLED or
  *                                             MBEDTLS_SSL_RENEGOTIATION_DISABLED)
  */
-void mbedtls_ssl_set_renegotiation( mbedtls_ssl_context *ssl, int renegotiation );
+void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation );
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
 
 /**
@@ -1930,12 +2019,12 @@
  *                 that do not support renegotiation altogether.
  *                 (Most secure option, interoperability issues)
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param allow_legacy  Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION,
  *                                        SSL_ALLOW_LEGACY_RENEGOTIATION or
  *                                        MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE)
  */
-void mbedtls_ssl_legacy_renegotiation( mbedtls_ssl_context *ssl, int allow_legacy );
+void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy );
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
 /**
@@ -1970,12 +2059,12 @@
  *                 if we receive application data from the server, we need a
  *                 place to write it, which only happens during mbedtls_ssl_read().
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param max_records Use MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to
  *                 enforce renegotiation, or a non-negative value to enforce
  *                 it but allow for a grace period of max_records records.
  */
-void mbedtls_ssl_set_renegotiation_enforced( mbedtls_ssl_context *ssl, int max_records );
+void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records );
 
 /**
  * \brief          Set record counter threshold for periodic renegotiation.
@@ -1990,11 +2079,11 @@
  *                 Lower values can be used to enforce policies such as "keys
  *                 must be refreshed every N packets with cipher X".
  *
- * \param ssl      SSL context
+ * \param conf     SSL configuration
  * \param period   The threshold value: a big-endian 64-bit number.
  *                 Set to 2^64 - 1 to disable periodic renegotiation
  */
-void mbedtls_ssl_set_renegotiation_period( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
                                    const unsigned char period[8] );
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
 
@@ -2093,8 +2182,8 @@
  *
  * \param ssl      SSL context
  *
- * \return         0 if successful, MBEDTLS_ERR_NET_WANT_READ,
- *                 MBEDTLS_ERR_NET_WANT_WRITE, or a specific SSL error code.
+ * \return         0 if successful, MBEDTLS_ERR_SSL_WANT_READ,
+ *                 MBEDTLS_ERR_SSL_WANT_WRITE, or a specific SSL error code.
  */
 int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
 
@@ -2107,8 +2196,8 @@
  *
  * \param ssl      SSL context
  *
- * \return         0 if successful, MBEDTLS_ERR_NET_WANT_READ,
- *                 MBEDTLS_ERR_NET_WANT_WRITE, or a specific SSL error code.
+ * \return         0 if successful, MBEDTLS_ERR_SSL_WANT_READ,
+ *                 MBEDTLS_ERR_SSL_WANT_WRITE, or a specific SSL error code.
  */
 int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl );
 
@@ -2148,7 +2237,7 @@
  * \return         This function returns the number of bytes written,
  *                 or a negative error code.
  *
- * \note           When this function returns MBEDTLS_ERR_NET_WANT_WRITE,
+ * \note           When this function returns MBEDTLS_ERR_SSL_WANT_WRITE,
  *                 it must be called later with the *same* arguments,
  *                 until it returns a positive value.
  *
@@ -2190,6 +2279,39 @@
 void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
 
 /**
+ * \brief          Initialize an SSL configuration context
+ *                 Just makes the context ready for
+ *                 mbedtls_ssl_config_defaults() or mbedtls_ssl_free()
+ *
+ * \note           You need to call mbedtls_ssl_config_defaults() unless you
+ *                 manually set all of the relevent fields yourself.
+ *
+ * \param conf     SSL configuration context
+ */
+void mbedtls_ssl_config_init( mbedtls_ssl_config *conf );
+
+/**
+ * \brief          Load reasonnable default SSL configuration values.
+ *                 (You need to call mbedtls_ssl_config_init() first.)
+ *
+ * \param conf     SSL configuration context
+ *
+ * \note           See \c mbedtls_ssl_conf_transport() for notes on DTLS.
+ *
+ * \return         0 if successful, or
+ *                 MBEDTLS_ERR_XXX_ALLOC_FAILED on memorr allocation error.
+ */
+int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
+                                 int endpoint, int transport );
+
+/**
+ * \brief          Free an SSL configuration context
+ *
+ * \param conf     SSL configuration context
+ */
+void mbedtls_ssl_config_free( mbedtls_ssl_config *conf );
+
+/**
  * \brief          Initialize SSL session structure
  *
  * \param session  SSL session
@@ -2268,14 +2390,26 @@
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl )
 {
-    return( ssl->handshake->key_cert == NULL ? NULL
-            : ssl->handshake->key_cert->key );
+    mbedtls_ssl_key_cert *key_cert;
+
+    if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL )
+        key_cert = ssl->handshake->key_cert;
+    else
+        key_cert = ssl->conf->key_cert;
+
+    return( key_cert == NULL ? NULL : key_cert->key );
 }
 
 static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl )
 {
-    return( ssl->handshake->key_cert == NULL ? NULL
-            : ssl->handshake->key_cert->cert );
+    mbedtls_ssl_key_cert *key_cert;
+
+    if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL )
+        key_cert = ssl->handshake->key_cert;
+    else
+        key_cert = ssl->conf->key_cert;
+
+    return( key_cert == NULL ? NULL : key_cert->cert );
 }
 
 /*
@@ -2301,7 +2435,7 @@
 static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl )
 {
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         return( 13 );
 #else
     ((void) ssl);
@@ -2312,7 +2446,7 @@
 static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl )
 {
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         return( 12 );
 #else
     ((void) ssl);
diff --git a/library/ccm.c b/library/ccm.c
index 957fda9..109927e 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -74,10 +74,6 @@
     int ret;
     const mbedtls_cipher_info_t *cipher_info;
 
-    memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
-
-    mbedtls_cipher_init( &ctx->cipher_ctx );
-
     cipher_info = mbedtls_cipher_info_from_values( cipher, keysize, MBEDTLS_MODE_ECB );
     if( cipher_info == NULL )
         return( MBEDTLS_ERR_CCM_BAD_INPUT );
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index ec7d9a7..00b50d2 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -61,6 +61,10 @@
 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
 }
 
 /*
@@ -78,7 +82,6 @@
     int ret;
     unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
 
-    memset( ctx, 0, sizeof(mbedtls_ctr_drbg_context) );
     memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
 
     mbedtls_aes_init( &ctx->aes_ctx );
@@ -115,6 +118,9 @@
     if( ctx == NULL )
         return;
 
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &ctx->mutex );
+#endif
     mbedtls_aes_free( &ctx->aes_ctx );
     mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
 }
@@ -392,7 +398,22 @@
 
 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
 {
-    return mbedtls_ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 );
+    int ret;
+    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
 }
 
 #if defined(MBEDTLS_FS_IO)
@@ -537,6 +558,8 @@
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
     CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
 
+    mbedtls_ctr_drbg_free( &ctx );
+
     if( verbose != 0 )
         mbedtls_printf( "passed\n" );
 
@@ -546,6 +569,8 @@
     if( verbose != 0 )
         mbedtls_printf( "  CTR_DRBG (PR = FALSE): " );
 
+    mbedtls_ctr_drbg_init( &ctx );
+
     test_offset = 0;
     CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
                             (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
@@ -554,6 +579,8 @@
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
     CHK( memcmp( buf, result_nopr, 16 ) );
 
+    mbedtls_ctr_drbg_free( &ctx );
+
     if( verbose != 0 )
         mbedtls_printf( "passed\n" );
 
diff --git a/library/debug.c b/library/debug.c
index 8dae2ed..3164ad7 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -83,18 +83,18 @@
     char str[512];
     int maxlen = sizeof( str ) - 1;
 
-    if( ssl->f_dbg == NULL || level > debug_threshold )
+    if( ssl->conf->f_dbg == NULL || level > debug_threshold )
         return;
 
     if( debug_log_mode == MBEDTLS_DEBUG_LOG_RAW )
     {
-        ssl->f_dbg( ssl->p_dbg, level, text );
+        ssl->conf->f_dbg( ssl->conf->p_dbg, level, text );
         return;
     }
 
     mbedtls_snprintf( str, maxlen, "%s(%04d): %s\n", file, line, text );
     str[maxlen] = '\0';
-    ssl->f_dbg( ssl->p_dbg, level, str );
+    ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
 }
 
 void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
@@ -105,7 +105,7 @@
     int maxlen = sizeof( str ) - 1;
     size_t idx = 0;
 
-    if( ssl->f_dbg == NULL || level > debug_threshold )
+    if( ssl->conf->f_dbg == NULL || level > debug_threshold )
         return;
 
     if( debug_log_mode == MBEDTLS_DEBUG_LOG_FULL )
@@ -115,7 +115,7 @@
               text, ret, -ret );
 
     str[maxlen] = '\0';
-    ssl->f_dbg( ssl->p_dbg, level, str );
+    ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
 }
 
 void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
@@ -126,7 +126,7 @@
     char txt[17];
     size_t i, maxlen = sizeof( str ) - 1, idx = 0;
 
-    if( ssl->f_dbg == NULL || level > debug_threshold )
+    if( ssl->conf->f_dbg == NULL || level > debug_threshold )
         return;
 
     if( debug_log_mode == MBEDTLS_DEBUG_LOG_FULL )
@@ -136,7 +136,7 @@
               text, (unsigned int) len );
 
     str[maxlen] = '\0';
-    ssl->f_dbg( ssl->p_dbg, level, str );
+    ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
 
     idx = 0;
     memset( txt, 0, sizeof( txt ) );
@@ -150,7 +150,7 @@
             if( i > 0 )
             {
                 mbedtls_snprintf( str + idx, maxlen - idx, "  %s\n", txt );
-                ssl->f_dbg( ssl->p_dbg, level, str );
+                ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
 
                 idx = 0;
                 memset( txt, 0, sizeof( txt ) );
@@ -175,7 +175,7 @@
             idx += mbedtls_snprintf( str + idx, maxlen - idx, "   " );
 
         mbedtls_snprintf( str + idx, maxlen - idx, "  %s\n", txt );
-        ssl->f_dbg( ssl->p_dbg, level, str );
+        ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
     }
 }
 
@@ -187,7 +187,7 @@
     char str[512];
     int maxlen = sizeof( str ) - 1;
 
-    if( ssl->f_dbg == NULL || level > debug_threshold )
+    if( ssl->conf->f_dbg == NULL || level > debug_threshold )
         return;
 
     mbedtls_snprintf( str, maxlen, "%s(X)", text );
@@ -209,7 +209,7 @@
     int j, k, maxlen = sizeof( str ) - 1, zeros = 1;
     size_t i, n, idx = 0;
 
-    if( ssl->f_dbg == NULL || X == NULL || level > debug_threshold )
+    if( ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold )
         return;
 
     for( n = X->n - 1; n > 0; n-- )
@@ -227,7 +227,7 @@
               text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) );
 
     str[maxlen] = '\0';
-    ssl->f_dbg( ssl->p_dbg, level, str );
+    ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
 
     idx = 0;
     for( i = n + 1, j = 0; i > 0; i-- )
@@ -247,7 +247,7 @@
                 if( j > 0 )
                 {
                     mbedtls_snprintf( str + idx, maxlen - idx, "\n" );
-                    ssl->f_dbg( ssl->p_dbg, level, str );
+                    ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
                     idx = 0;
                 }
 
@@ -274,7 +274,7 @@
     }
 
     mbedtls_snprintf( str + idx, maxlen - idx, "\n" );
-    ssl->f_dbg( ssl->p_dbg, level, str );
+    ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
 }
 #endif /* MBEDTLS_BIGNUM_C */
 
@@ -322,7 +322,7 @@
     char str[1024], prefix[64];
     int i = 0, maxlen = sizeof( prefix ) - 1, idx = 0;
 
-    if( ssl->f_dbg == NULL || crt == NULL || level > debug_threshold )
+    if( ssl->conf->f_dbg == NULL || crt == NULL || level > debug_threshold )
         return;
 
     if( debug_log_mode == MBEDTLS_DEBUG_LOG_FULL )
@@ -347,7 +347,7 @@
                   text, ++i, buf );
 
         str[maxlen] = '\0';
-        ssl->f_dbg( ssl->p_dbg, level, str );
+        ssl->conf->f_dbg( ssl->conf->p_dbg, level, str );
 
         debug_print_pk( ssl, level, file, line, "crt->", &crt->pk );
 
diff --git a/library/error.c b/library/error.c
index 4281e89..1a82cc9 100644
--- a/library/error.c
+++ b/library/error.c
@@ -457,6 +457,12 @@
             mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
         if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
             mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
+            mbedtls_snprintf( buf, buflen, "SSL - Connection requires a read call" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
+            mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
+            mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
 #endif /* MBEDTLS_SSL_TLS_C */
 
 #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
@@ -675,14 +681,8 @@
         mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" );
     if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) )
         mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" );
-    if( use_ret == -(MBEDTLS_ERR_NET_WANT_READ) )
-        mbedtls_snprintf( buf, buflen, "NET - Connection requires a read call" );
-    if( use_ret == -(MBEDTLS_ERR_NET_WANT_WRITE) )
-        mbedtls_snprintf( buf, buflen, "NET - Connection requires a write call" );
     if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) )
         mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
-    if( use_ret == -(MBEDTLS_ERR_NET_TIMEOUT) )
-        mbedtls_snprintf( buf, buflen, "NET - The operation timed out" );
 #endif /* MBEDTLS_NET_C */
 
 #if defined(MBEDTLS_OID_C)
diff --git a/library/gcm.c b/library/gcm.c
index 58cb4f2..39648b4 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -167,10 +167,6 @@
     int ret;
     const mbedtls_cipher_info_t *cipher_info;
 
-    memset( ctx, 0, sizeof(mbedtls_gcm_context) );
-
-    mbedtls_cipher_init( &ctx->cipher_ctx );
-
     cipher_info = mbedtls_cipher_info_from_values( cipher, keysize, MBEDTLS_MODE_ECB );
     if( cipher_info == NULL )
         return( MBEDTLS_ERR_GCM_BAD_INPUT );
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 710eb84..5c4ee6d 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -62,6 +62,10 @@
 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
 }
 
 /*
@@ -101,10 +105,6 @@
 {
     int ret;
 
-    memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
-
-    mbedtls_md_init( &ctx->md_ctx );
-
     if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
@@ -175,10 +175,6 @@
     int ret;
     size_t entropy_len, md_size;
 
-    memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
-
-    mbedtls_md_init( &ctx->md_ctx );
-
     if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
@@ -313,7 +309,22 @@
  */
 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
 {
-    return( mbedtls_hmac_drbg_random_with_add( p_rng, output, out_len, NULL, 0 ) );
+    int ret;
+    mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
 }
 
 /*
@@ -324,8 +335,10 @@
     if( ctx == NULL )
         return;
 
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &ctx->mutex );
+#endif
     mbedtls_md_free( &ctx->md_ctx );
-
     mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
 }
 
@@ -481,6 +494,8 @@
     CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
     mbedtls_hmac_drbg_free( &ctx );
 
+    mbedtls_hmac_drbg_free( &ctx );
+
     if( verbose != 0 )
         mbedtls_printf( "passed\n" );
 
@@ -490,6 +505,8 @@
     if( verbose != 0 )
         mbedtls_printf( "  HMAC_DRBG (PR = False) : " );
 
+    mbedtls_hmac_drbg_init( &ctx );
+
     test_offset = 0;
     CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
                          hmac_drbg_self_test_entropy, (void *) entropy_nopr,
@@ -500,6 +517,8 @@
     CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
     mbedtls_hmac_drbg_free( &ctx );
 
+    mbedtls_hmac_drbg_free( &ctx );
+
     if( verbose != 0 )
         mbedtls_printf( "passed\n" );
 
diff --git a/library/net.c b/library/net.c
index 0db8834..a372134 100644
--- a/library/net.c
+++ b/library/net.c
@@ -338,7 +338,7 @@
     if( ret < 0 )
     {
         if( net_would_block( bind_fd ) != 0 )
-            return( MBEDTLS_ERR_NET_WANT_READ );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
 
         return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
     }
@@ -425,7 +425,7 @@
     if( ret < 0 )
     {
         if( net_would_block( fd ) != 0 )
-            return( MBEDTLS_ERR_NET_WANT_READ );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
 
 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
     !defined(EFI32)
@@ -436,7 +436,7 @@
             return( MBEDTLS_ERR_NET_CONN_RESET );
 
         if( errno == EINTR )
-            return( MBEDTLS_ERR_NET_WANT_READ );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
 #endif
 
         return( MBEDTLS_ERR_NET_RECV_FAILED );
@@ -467,17 +467,17 @@
 
     /* Zero fds ready means we timed out */
     if( ret == 0 )
-        return( MBEDTLS_ERR_NET_TIMEOUT );
+        return( MBEDTLS_ERR_SSL_TIMEOUT );
 
     if( ret < 0 )
     {
 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
     !defined(EFI32)
         if( WSAGetLastError() == WSAEINTR )
-            return( MBEDTLS_ERR_NET_WANT_READ );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
 #else
         if( errno == EINTR )
-            return( MBEDTLS_ERR_NET_WANT_READ );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
 #endif
 
         return( MBEDTLS_ERR_NET_RECV_FAILED );
@@ -499,7 +499,7 @@
     if( ret < 0 )
     {
         if( net_would_block( fd ) != 0 )
-            return( MBEDTLS_ERR_NET_WANT_WRITE );
+            return( MBEDTLS_ERR_SSL_WANT_WRITE );
 
 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
     !defined(EFI32)
@@ -510,7 +510,7 @@
             return( MBEDTLS_ERR_NET_CONN_RESET );
 
         if( errno == EINTR )
-            return( MBEDTLS_ERR_NET_WANT_WRITE );
+            return( MBEDTLS_ERR_SSL_WANT_WRITE );
 #endif
 
         return( MBEDTLS_ERR_NET_SEND_FAILED );
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 9f04b2b..c16b6e7 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -65,6 +65,7 @@
                                     size_t *olen )
 {
     unsigned char *p = buf;
+    size_t hostname_len;
 
     *olen = 0;
 
@@ -74,6 +75,8 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
                    ssl->hostname ) );
 
+    hostname_len = strlen( ssl->hostname );
+
     /*
      * struct {
      *     NameType name_type;
@@ -95,19 +98,19 @@
     *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
     *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME      ) & 0xFF );
 
-    *p++ = (unsigned char)( ( (ssl->hostname_len + 5) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( (ssl->hostname_len + 5)      ) & 0xFF );
+    *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( (hostname_len + 5)      ) & 0xFF );
 
-    *p++ = (unsigned char)( ( (ssl->hostname_len + 3) >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( (ssl->hostname_len + 3)      ) & 0xFF );
+    *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( (hostname_len + 3)      ) & 0xFF );
 
     *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
-    *p++ = (unsigned char)( ( ssl->hostname_len >> 8 ) & 0xFF );
-    *p++ = (unsigned char)( ( ssl->hostname_len      ) & 0xFF );
+    *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( hostname_len      ) & 0xFF );
 
-    memcpy( p, ssl->hostname, ssl->hostname_len );
+    memcpy( p, ssl->hostname, hostname_len );
 
-    *olen = ssl->hostname_len + 9;
+    *olen = hostname_len + 9;
 }
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 
@@ -158,7 +161,7 @@
 
     *olen = 0;
 
-    if( ssl->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
+    if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
         return;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
@@ -262,7 +265,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
 
 #if defined(MBEDTLS_SSL_SET_CURVES)
-    for( grp_id = ssl->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
+    for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
     {
         info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
 #else
@@ -320,7 +323,7 @@
 {
     unsigned char *p = buf;
 
-    if( ssl->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
+    if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
         *olen = 0;
         return;
     }
@@ -333,7 +336,7 @@
     *p++ = 0x00;
     *p++ = 1;
 
-    *p++ = ssl->mfl_code;
+    *p++ = ssl->conf->mfl_code;
 
     *olen = 5;
 }
@@ -345,7 +348,7 @@
 {
     unsigned char *p = buf;
 
-    if( ssl->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
+    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
     {
         *olen = 0;
         return;
@@ -369,8 +372,8 @@
 {
     unsigned char *p = buf;
 
-    if( ssl->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
-        ssl->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
+        ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         *olen = 0;
         return;
@@ -395,8 +398,8 @@
 {
     unsigned char *p = buf;
 
-    if( ssl->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
-        ssl->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+        ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         *olen = 0;
         return;
@@ -422,7 +425,7 @@
     unsigned char *p = buf;
     size_t tlen = ssl->session_negotiate->ticket_len;
 
-    if( ssl->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
+    if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
     {
         *olen = 0;
         return;
@@ -459,7 +462,7 @@
     unsigned char *p = buf;
     const char **cur;
 
-    if( ssl->alpn_list == NULL )
+    if( ssl->conf->alpn_list == NULL )
     {
         *olen = 0;
         return;
@@ -481,7 +484,7 @@
     /* Skip writing extension and list length for now */
     p += 4;
 
-    for( cur = ssl->alpn_list; *cur != NULL; cur++ )
+    for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
     {
         *p = (unsigned char)( strlen( *cur ) & 0xFF );
         memcpy( p + 1, *cur, *p );
@@ -515,7 +518,7 @@
      * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
      */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake->verify_cookie != NULL )
     {
         return( 0 );
@@ -531,13 +534,13 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
 #else
-    if( ( ret = ssl->f_rng( ssl->p_rng, p, 4 ) ) != 0 )
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
         return( ret );
 
     p += 4;
 #endif /* MBEDTLS_HAVE_TIME */
 
-    if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 )
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
         return( ret );
 
     return( 0 );
@@ -555,7 +558,7 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
 
-    if( ssl->f_rng == NULL )
+    if( ssl->conf->f_rng == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
         return( MBEDTLS_ERR_SSL_NO_RNG );
@@ -565,14 +568,15 @@
     if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
 #endif
     {
-        ssl->major_ver = ssl->min_major_ver;
-        ssl->minor_ver = ssl->min_minor_ver;
+        ssl->major_ver = ssl->conf->min_major_ver;
+        ssl->minor_ver = ssl->conf->min_minor_ver;
     }
 
-    if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 )
+    if( ssl->conf->max_major_ver == 0 )
     {
-        ssl->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
-        ssl->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, "
+                            "consider using mbedtls_ssl_config_defaults()" ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
     /*
@@ -585,8 +589,8 @@
     buf = ssl->out_msg;
     p = buf + 4;
 
-    mbedtls_ssl_write_version( ssl->max_major_ver, ssl->max_minor_ver,
-                       ssl->transport, p );
+    mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
+                       ssl->conf->transport, p );
     p += 2;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
@@ -637,7 +641,7 @@
         if( ssl->session_negotiate->ticket != NULL &&
                 ssl->session_negotiate->ticket_len != 0 )
         {
-            ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id, 32 );
+            ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
 
             if( ret != 0 )
                 return( ret );
@@ -659,7 +663,7 @@
      * DTLS cookie
      */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         if( ssl->handshake->verify_cookie == NULL )
         {
@@ -683,7 +687,7 @@
     /*
      * Ciphersuite list
      */
-    ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
+    ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
 
     /* Skip writing ciphersuite length for now */
     n = 0;
@@ -697,17 +701,17 @@
         if( ciphersuite_info == NULL )
             continue;
 
-        if( ciphersuite_info->min_minor_ver > ssl->max_minor_ver ||
-            ciphersuite_info->max_minor_ver < ssl->min_minor_ver )
+        if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
+            ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
             continue;
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-        if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
             ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
             continue;
 #endif
 
-        if( ssl->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
+        if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
             ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
             continue;
 
@@ -733,7 +737,7 @@
 
     /* Some versions of OpenSSL don't handle it correctly if not at end */
 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
-    if( ssl->fallback == MBEDTLS_SSL_IS_FALLBACK )
+    if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
         *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
@@ -760,7 +764,7 @@
      * an actual need for it.
      */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         offer_compress = 0;
 #endif
 
@@ -860,7 +864,7 @@
     ssl->state++;
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         mbedtls_ssl_send_flight_completed( ssl );
 #endif
 
@@ -928,9 +932,9 @@
      * server should use the extension only if we did,
      * and if so the server's value should match ours (and len is always 1)
      */
-    if( ssl->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
+    if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
         len != 1 ||
-        buf[0] != ssl->mfl_code )
+        buf[0] != ssl->conf->mfl_code )
     {
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
@@ -944,7 +948,7 @@
                                          const unsigned char *buf,
                                          size_t len )
 {
-    if( ssl->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
+    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
         len != 0 )
     {
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
@@ -963,7 +967,7 @@
                                          const unsigned char *buf,
                                          size_t len )
 {
-    if( ssl->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
+    if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
         ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
         len != 0 )
     {
@@ -983,7 +987,7 @@
                                          const unsigned char *buf,
                                          size_t len )
 {
-    if( ssl->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
         ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
         len != 0 )
     {
@@ -1003,7 +1007,7 @@
                                          const unsigned char *buf,
                                          size_t len )
 {
-    if( ssl->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
+    if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
         len != 0 )
     {
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
@@ -1060,7 +1064,7 @@
     const char **p;
 
     /* If we didn't send it, the server shouldn't send it */
-    if( ssl->alpn_list == NULL )
+    if( ssl->conf->alpn_list == NULL )
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 
     /*
@@ -1086,7 +1090,7 @@
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
 
     /* Check that the server chosen protocol was in our list and save it */
-    for( p = ssl->alpn_list; *p != NULL; p++ )
+    for( p = ssl->conf->alpn_list; *p != NULL; p++ )
     {
         if( name_len == strlen( *p ) &&
             memcmp( buf + 3, *p, name_len ) == 0 )
@@ -1119,7 +1123,7 @@
      * } HelloVerifyRequest;
      */
     MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
-    mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->transport, p );
+    mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p );
     p += 2;
 
     /*
@@ -1128,8 +1132,8 @@
      */
     if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
         minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ||
-        major_ver > ssl->max_major_ver  ||
-        minor_ver > ssl->max_minor_ver  )
+        major_ver > ssl->conf->max_major_ver  ||
+        minor_ver > ssl->conf->max_minor_ver  )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
 
@@ -1199,8 +1203,8 @@
         {
             ssl->renego_records_seen++;
 
-            if( ssl->renego_max_records >= 0 &&
-                ssl->renego_records_seen > ssl->renego_max_records )
+            if( ssl->conf->renego_max_records >= 0 &&
+                ssl->renego_records_seen > ssl->conf->renego_max_records )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
                                     "but not honored by server" ) );
@@ -1217,7 +1221,7 @@
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
         {
@@ -1257,18 +1261,18 @@
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
     mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
-                      ssl->transport, buf + 0 );
+                      ssl->conf->transport, buf + 0 );
 
-    if( ssl->major_ver < ssl->min_major_ver ||
-        ssl->minor_ver < ssl->min_minor_ver ||
-        ssl->major_ver > ssl->max_major_ver ||
-        ssl->minor_ver > ssl->max_minor_ver )
+    if( ssl->major_ver < ssl->conf->min_major_ver ||
+        ssl->minor_ver < ssl->conf->min_minor_ver ||
+        ssl->major_ver > ssl->conf->max_major_ver ||
+        ssl->minor_ver > ssl->conf->max_minor_ver )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
                             " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
-                            ssl->min_major_ver, ssl->min_minor_ver,
+                            ssl->conf->min_major_ver, ssl->conf->min_minor_ver,
                             ssl->major_ver, ssl->minor_ver,
-                            ssl->max_major_ver, ssl->max_minor_ver ) );
+                            ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) );
 
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
@@ -1334,7 +1338,7 @@
 
     /* See comments in ssl_write_client_hello() */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         accept_comp = 0;
 #endif
 
@@ -1402,7 +1406,7 @@
 
     suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
     if( suite_info == NULL ||
-        ( ssl->arc4_disabled &&
+        ( ssl->conf->arc4_disabled &&
           suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
@@ -1413,13 +1417,13 @@
     i = 0;
     while( 1 )
     {
-        if( ssl->ciphersuite_list[ssl->minor_ver][i] == 0 )
+        if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
             return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
         }
 
-        if( ssl->ciphersuite_list[ssl->minor_ver][i++] ==
+        if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] ==
             ssl->session_negotiate->ciphersuite )
         {
             break;
@@ -1575,7 +1579,7 @@
      * Renegotiation security checks
      */
     if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
-        ssl->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
+        ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
         handshake_failure = 1;
@@ -1590,7 +1594,7 @@
     }
     else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
              ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
-             ssl->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
+             ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
         handshake_failure = 1;
@@ -1779,10 +1783,10 @@
      *      opaque random[46];
      *  } PreMasterSecret;
      */
-    mbedtls_ssl_write_version( ssl->max_major_ver, ssl->max_minor_ver,
-                       ssl->transport, p );
+    mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
+                       ssl->conf->transport, p );
 
-    if( ( ret = ssl->f_rng( ssl->p_rng, p + 2, 46 ) ) != 0 )
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
         return( ret );
@@ -1804,7 +1808,7 @@
                             p, ssl->handshake->pmslen,
                             ssl->out_msg + offset + len_bytes, olen,
                             MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes,
-                            ssl->f_rng, ssl->p_rng ) ) != 0 )
+                            ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
         return( ret );
@@ -2426,7 +2430,7 @@
     ssl->state++;
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         mbedtls_ssl_recv_flight_completed( ssl );
 #endif
 
@@ -2458,7 +2462,7 @@
         ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
                                 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
                                &ssl->out_msg[i], n,
-                                ssl->f_rng, ssl->p_rng );
+                                ssl->conf->f_rng, ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
@@ -2473,7 +2477,7 @@
         if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
                                       ssl->handshake->premaster,
                                      &ssl->handshake->pmslen,
-                                      ssl->f_rng, ssl->p_rng ) ) != 0 )
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
             return( ret );
@@ -2500,7 +2504,7 @@
         ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
                                 &n,
                                 &ssl->out_msg[i], 1000,
-                                ssl->f_rng, ssl->p_rng );
+                                ssl->conf->f_rng, ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
@@ -2513,7 +2517,7 @@
                                       &ssl->handshake->pmslen,
                                        ssl->handshake->premaster,
                                        MBEDTLS_MPI_MAX_SIZE,
-                                       ssl->f_rng, ssl->p_rng ) ) != 0 )
+                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
             return( ret );
@@ -2535,16 +2539,16 @@
         /*
          * opaque psk_identity<0..2^16-1>;
          */
-        if( ssl->psk == NULL || ssl->psk_identity == NULL )
+        if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
             return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
 
         i = 4;
-        n = ssl->psk_identity_len;
+        n = ssl->conf->psk_identity_len;
         ssl->out_msg[i++] = (unsigned char)( n >> 8 );
         ssl->out_msg[i++] = (unsigned char)( n      );
 
-        memcpy( ssl->out_msg + i, ssl->psk_identity, ssl->psk_identity_len );
-        i += ssl->psk_identity_len;
+        memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
+        i += ssl->conf->psk_identity_len;
 
 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
         if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
@@ -2574,7 +2578,7 @@
             ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
                     (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
                     &ssl->out_msg[i], n,
-                    ssl->f_rng, ssl->p_rng );
+                    ssl->conf->f_rng, ssl->conf->p_rng );
             if( ret != 0 )
             {
                 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
@@ -2591,7 +2595,7 @@
              */
             ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
                     &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i,
-                    ssl->f_rng, ssl->p_rng );
+                    ssl->conf->f_rng, ssl->conf->p_rng );
             if( ret != 0 )
             {
                 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
@@ -2801,7 +2805,7 @@
 
     if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen,
                          ssl->out_msg + 6 + offset, &n,
-                         ssl->f_rng, ssl->p_rng ) ) != 0 )
+                         ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
         return( ret );
@@ -2944,7 +2948,7 @@
         return( ret );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake != NULL &&
         ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
     {
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 3a6a3fe..b442e65 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -189,15 +189,15 @@
 
     *tlen = 0;
 
-    if( ssl->ticket_keys == NULL )
+    if( ssl->conf->ticket_keys == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
     /* Write key name */
-    memcpy( p, ssl->ticket_keys->key_name, 16 );
+    memcpy( p, ssl->conf->ticket_keys->key_name, 16 );
     p += 16;
 
     /* Generate and write IV (with a copy for aes_crypt) */
-    if( ( ret = ssl->f_rng( ssl->p_rng, p, 16 ) ) != 0 )
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 16 ) ) != 0 )
         return( ret );
     memcpy( iv, p, 16 );
     p += 16;
@@ -224,7 +224,7 @@
         state[i] = (unsigned char) pad_len;
 
     /* Encrypt */
-    if( ( ret = mbedtls_aes_crypt_cbc( &ssl->ticket_keys->enc, MBEDTLS_AES_ENCRYPT,
+    if( ( ret = mbedtls_aes_crypt_cbc( &ssl->conf->ticket_keys->enc, MBEDTLS_AES_ENCRYPT,
                                enc_len, iv, state, state ) ) != 0 )
     {
         return( ret );
@@ -237,7 +237,7 @@
 
     /* Compute and write MAC( key_name + iv + enc_state_len + enc_state ) */
     if( ( ret = mbedtls_md_hmac( mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
-                         ssl->ticket_keys->mac_key, 16,
+                         ssl->conf->ticket_keys->mac_key, 16,
                          start, p - start, p ) ) != 0 )
     {
         return( ret );
@@ -271,7 +271,7 @@
 
     MBEDTLS_SSL_DEBUG_BUF( 3, "session ticket structure", buf, len );
 
-    if( len < 34 || ssl->ticket_keys == NULL )
+    if( len < 34 || ssl->conf->ticket_keys == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
     enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1];
@@ -283,12 +283,12 @@
     /* Check name, in constant time though it's not a big secret */
     diff = 0;
     for( i = 0; i < 16; i++ )
-        diff |= key_name[i] ^ ssl->ticket_keys->key_name[i];
+        diff |= key_name[i] ^ ssl->conf->ticket_keys->key_name[i];
     /* don't return yet, check the MAC anyway */
 
     /* Check mac, with constant-time buffer comparison */
     if( ( ret = mbedtls_md_hmac( mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
-                         ssl->ticket_keys->mac_key, 16,
+                         ssl->conf->ticket_keys->mac_key, 16,
                          buf, len - 32, computed_mac ) ) != 0 )
     {
         return( ret );
@@ -303,7 +303,7 @@
         return( MBEDTLS_ERR_SSL_INVALID_MAC );
 
     /* Decrypt */
-    if( ( ret = mbedtls_aes_crypt_cbc( &ssl->ticket_keys->dec, MBEDTLS_AES_DECRYPT,
+    if( ( ret = mbedtls_aes_crypt_cbc( &ssl->conf->ticket_keys->dec, MBEDTLS_AES_DECRYPT,
                                enc_len, iv, ticket, ticket ) ) != 0 )
     {
         return( ret );
@@ -333,7 +333,7 @@
 
 #if defined(MBEDTLS_HAVE_TIME)
     /* Check if still valid */
-    if( (int) ( time( NULL) - session.start ) > ssl->ticket_lifetime )
+    if( (int) ( time( NULL) - session.start ) > ssl->conf->ticket_lifetime )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "session ticket expired" ) );
         mbedtls_ssl_session_free( &session );
@@ -363,7 +363,7 @@
                                  const unsigned char *info,
                                  size_t ilen )
 {
-    if( ssl->endpoint != MBEDTLS_SSL_IS_SERVER )
+    if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
     mbedtls_free( ssl->cli_id );
@@ -377,37 +377,18 @@
     return( 0 );
 }
 
-void mbedtls_ssl_set_dtls_cookies( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
                            mbedtls_ssl_cookie_write_t *f_cookie_write,
                            mbedtls_ssl_cookie_check_t *f_cookie_check,
                            void *p_cookie )
 {
-    ssl->f_cookie_write = f_cookie_write;
-    ssl->f_cookie_check = f_cookie_check;
-    ssl->p_cookie       = p_cookie;
+    conf->f_cookie_write = f_cookie_write;
+    conf->f_cookie_check = f_cookie_check;
+    conf->p_cookie       = p_cookie;
 }
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-/*
- * Wrapper around f_sni, allowing use of mbedtls_ssl_set_own_cert() but
- * making it act on ssl->handshake->sni_key_cert instead.
- */
-static int ssl_sni_wrapper( mbedtls_ssl_context *ssl,
-                            const unsigned char* name, size_t len )
-{
-    int ret;
-    mbedtls_ssl_key_cert *key_cert_ori = ssl->key_cert;
-
-    ssl->key_cert = NULL;
-    ret = ssl->f_sni( ssl->p_sni, ssl, name, len );
-    ssl->handshake->sni_key_cert = ssl->key_cert;
-
-    ssl->key_cert = key_cert_ori;
-
-    return( ret );
-}
-
 static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
                                      const unsigned char *buf,
                                      size_t len )
@@ -437,7 +418,8 @@
 
         if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME )
         {
-            ret = ssl_sni_wrapper( ssl, p + 3, hostname_len );
+            ret = ssl->conf->f_sni( ssl->conf->p_sni,
+                                    ssl, p + 3, hostname_len );
             if( ret != 0 )
             {
                 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
@@ -670,7 +652,7 @@
 
     ((void) buf);
 
-    if( ssl->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
+    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
         ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
 
     return( 0 );
@@ -690,7 +672,7 @@
 
     ((void) buf);
 
-    if( ssl->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED &&
+    if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED &&
         ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
@@ -713,7 +695,7 @@
 
     ((void) buf);
 
-    if( ssl->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED &&
+    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED &&
         ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
@@ -730,7 +712,7 @@
 {
     int ret;
 
-    if( ssl->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
+    if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
         return( 0 );
 
     /* Remember the client asked us to send a new ticket */
@@ -778,7 +760,7 @@
     const char **ours;
 
     /* If ALPN not configured, just ignore the extension */
-    if( ssl->alpn_list == NULL )
+    if( ssl->conf->alpn_list == NULL )
         return( 0 );
 
     /*
@@ -802,7 +784,7 @@
      */
     start = buf + 2;
     end = buf + len;
-    for( ours = ssl->alpn_list; *ours != NULL; ours++ )
+    for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ )
     {
         ours_len = strlen( *ours );
         for( theirs = start; theirs != end; theirs += cur_len )
@@ -875,7 +857,7 @@
         list = ssl->handshake->sni_key_cert;
     else
 #endif
-        list = ssl->handshake->key_cert;
+        list = ssl->conf->key_cert;
 
     if( pk_alg == MBEDTLS_PK_NONE )
         return( 0 );
@@ -943,7 +925,7 @@
         cur = fallback;
 
 
-    /* Do not update ssl->handshake->key_cert unless the is a match */
+    /* Do not update ssl->handshake->key_cert unless there is a match */
     if( cur != NULL )
     {
         ssl->handshake->key_cert = cur;
@@ -982,12 +964,12 @@
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
         return( 0 );
 #endif
 
-    if( ssl->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
+    if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
             suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) );
@@ -1009,9 +991,9 @@
     /* If the ciphersuite requires a pre-shared key and we don't
      * have one, skip it now rather than failing later */
     if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
-        ssl->f_psk == NULL &&
-        ( ssl->psk == NULL || ssl->psk_identity == NULL ||
-          ssl->psk_identity_len == 0 || ssl->psk_len == 0 ) )
+        ssl->conf->f_psk == NULL &&
+        ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
+          ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) );
         return( 0 );
@@ -1100,15 +1082,15 @@
     }
 
     ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
-    ssl->minor_ver = ( buf[4] <= ssl->max_minor_ver )
-                     ? buf[4]  : ssl->max_minor_ver;
+    ssl->minor_ver = ( buf[4] <= ssl->conf->max_minor_ver )
+                     ? buf[4]  : ssl->conf->max_minor_ver;
 
-    if( ssl->minor_ver < ssl->min_minor_ver )
+    if( ssl->minor_ver < ssl->conf->min_minor_ver )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
                             " [%d:%d] < [%d:%d]",
                             ssl->major_ver, ssl->minor_ver,
-                            ssl->min_major_ver, ssl->min_minor_ver ) );
+                            ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
 
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
@@ -1224,7 +1206,7 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) );
 
-            if( ssl->minor_ver < ssl->max_minor_ver )
+            if( ssl->minor_ver < ssl->conf->max_minor_ver )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) );
 
@@ -1240,7 +1222,7 @@
 #endif /* MBEDTLS_SSL_FALLBACK_SCSV */
 
     got_common_suite = 0;
-    ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
+    ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
     ciphersuite_info = NULL;
 #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
     for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
@@ -1291,7 +1273,7 @@
      * SSLv2 Client Hello relevant renegotiation security checks
      */
     if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
-        ssl->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
+        ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
 
@@ -1353,7 +1335,7 @@
 
 #if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
 #endif
         if( ( buf[0] & 0x80 ) != 0 )
             return ssl_parse_client_hello_v2( ssl );
@@ -1385,7 +1367,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]",
                    buf[1], buf[2] ) );
 
-    mbedtls_ssl_read_version( &major, &minor, ssl->transport, buf + 1 );
+    mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 );
 
     /* According to RFC 5246 Appendix E.1, the version here is typically
      * "{03,00}, the lowest version number supported by the client, [or] the
@@ -1400,7 +1382,7 @@
     /* For DTLS if this is the initial handshake, remember the client sequence
      * number to use it in our next message (RFC 6347 4.2.1) */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM 
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
         && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
 #endif
@@ -1455,7 +1437,7 @@
 
     /* Done reading this record, get ready for the next one */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-        if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
             ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl );
         else
 #endif
@@ -1502,7 +1484,7 @@
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         /*
          * Copy the client's handshake message_seq on initial handshakes,
@@ -1583,18 +1565,18 @@
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, version", buf, 2 );
 
     mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
-                      ssl->transport, buf );
+                      ssl->conf->transport, buf );
 
     ssl->handshake->max_major_ver = ssl->major_ver;
     ssl->handshake->max_minor_ver = ssl->minor_ver;
 
-    if( ssl->major_ver < ssl->min_major_ver ||
-        ssl->minor_ver < ssl->min_minor_ver )
+    if( ssl->major_ver < ssl->conf->min_major_ver ||
+        ssl->minor_ver < ssl->conf->min_minor_ver )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
                             " [%d:%d] < [%d:%d]",
                             ssl->major_ver, ssl->minor_ver,
-                            ssl->min_major_ver, ssl->min_minor_ver ) );
+                            ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
 
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                                      MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
@@ -1602,13 +1584,13 @@
         return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
     }
 
-    if( ssl->major_ver > ssl->max_major_ver )
+    if( ssl->major_ver > ssl->conf->max_major_ver )
     {
-        ssl->major_ver = ssl->max_major_ver;
-        ssl->minor_ver = ssl->max_minor_ver;
+        ssl->major_ver = ssl->conf->max_major_ver;
+        ssl->minor_ver = ssl->conf->max_minor_ver;
     }
-    else if( ssl->minor_ver > ssl->max_minor_ver )
-        ssl->minor_ver = ssl->max_minor_ver;
+    else if( ssl->minor_ver > ssl->conf->max_minor_ver )
+        ssl->minor_ver = ssl->conf->max_minor_ver;
 
     /*
      * Save client random (inc. Unix time)
@@ -1641,7 +1623,7 @@
      * Check the cookie length and content
      */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         cookie_offset = 35 + sess_len;
         cookie_len = buf[cookie_offset];
@@ -1656,13 +1638,13 @@
                        buf + cookie_offset + 1, cookie_len );
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
-        if( ssl->f_cookie_check != NULL
+        if( ssl->conf->f_cookie_check != NULL
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
             && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
 #endif
             )
         {
-            if( ssl->f_cookie_check( ssl->p_cookie,
+            if( ssl->conf->f_cookie_check( ssl->conf->p_cookie,
                                      buf + cookie_offset + 1, cookie_len,
                                      ssl->cli_id, ssl->cli_id_len ) != 0 )
             {
@@ -1743,7 +1725,7 @@
 
     /* See comments in ssl_write_client_hello() */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
 #endif
 
@@ -1793,7 +1775,7 @@
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
         case MBEDTLS_TLS_EXT_SERVERNAME:
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
-            if( ssl->f_sni == NULL )
+            if( ssl->conf->f_sni == NULL )
                 break;
 
             ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
@@ -1931,7 +1913,7 @@
         {
             MBEDTLS_SSL_DEBUG_MSG( 0, ( "received FALLBACK_SCSV" ) );
 
-            if( ssl->minor_ver < ssl->max_minor_ver )
+            if( ssl->minor_ver < ssl->conf->max_minor_ver )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 0, ( "inapropriate fallback" ) );
 
@@ -1974,7 +1956,7 @@
      * Renegotiation security checks
      */
     if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION &&
-        ssl->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
+        ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
         handshake_failure = 1;
@@ -1989,7 +1971,7 @@
     }
     else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
              ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
-             ssl->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
+             ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
         handshake_failure = 1;
@@ -2017,7 +1999,7 @@
      * and certificate from the SNI callback triggered by the SNI extension.)
      */
     got_common_suite = 0;
-    ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
+    ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
     ciphersuite_info = NULL;
 #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
     for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
@@ -2068,7 +2050,7 @@
     ssl->state++;
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         mbedtls_ssl_recv_flight_completed( ssl );
 #endif
 
@@ -2351,12 +2333,12 @@
     /* The RFC is not clear on this point, but sending the actual negotiated
      * version looks like the most interoperable thing to do. */
     mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
-                       ssl->transport, p );
+                       ssl->conf->transport, p );
     MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
     p += 2;
 
     /* If we get here, f_cookie_check is not null */
-    if( ssl->f_cookie_write == NULL )
+    if( ssl->conf->f_cookie_write == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "inconsistent cookie callbacks" ) );
         return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -2365,7 +2347,7 @@
     /* Skip length byte until we know the length */
     cookie_len_byte = p++;
 
-    if( ( ret = ssl->f_cookie_write( ssl->p_cookie,
+    if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie,
                                      &p, ssl->out_buf + MBEDTLS_SSL_BUFFER_LEN,
                                      ssl->cli_id, ssl->cli_id_len ) ) != 0 )
     {
@@ -2407,7 +2389,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) );
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake->verify_cookie_len != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) );
@@ -2417,7 +2399,7 @@
     }
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
 
-    if( ssl->f_rng == NULL )
+    if( ssl->conf->f_rng == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
         return( MBEDTLS_ERR_SSL_NO_RNG );
@@ -2434,7 +2416,7 @@
     p = buf + 4;
 
     mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
-                       ssl->transport, p );
+                       ssl->conf->transport, p );
     p += 2;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
@@ -2449,13 +2431,13 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
 #else
-    if( ( ret = ssl->f_rng( ssl->p_rng, p, 4 ) ) != 0 )
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
         return( ret );
 
     p += 4;
 #endif /* MBEDTLS_HAVE_TIME */
 
-    if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 )
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
         return( ret );
 
     p += 28;
@@ -2474,8 +2456,8 @@
         ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE &&
 #endif
         ssl->session_negotiate->length != 0 &&
-        ssl->f_get_cache != NULL &&
-        ssl->f_get_cache( ssl->p_get_cache, ssl->session_negotiate ) == 0 )
+        ssl->conf->f_get_cache != NULL &&
+        ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
         ssl->handshake->resume = 1;
@@ -2503,7 +2485,7 @@
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
         {
             ssl->session_negotiate->length = n = 32;
-            if( ( ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id,
+            if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id,
                                     n ) ) != 0 )
                 return( ret );
         }
@@ -2651,7 +2633,7 @@
         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
-        ssl->authmode == MBEDTLS_SSL_VERIFY_NONE )
+        ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
         return( 0 );
@@ -2743,7 +2725,12 @@
      * opaque DistinguishedName<1..2^16-1>;
      */
     p += 2;
-    crt = ssl->ca_chain;
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    if( ssl->handshake->sni_ca_chain != NULL )
+        crt = ssl->handshake->sni_ca_chain;
+    else
+#endif
+        crt = ssl->conf->ca_chain;
 
     total_dn_size = 0;
     while( crt != NULL && crt->version != 0 )
@@ -2871,6 +2858,12 @@
     if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
     {
+        if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) );
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+        }
+
         /*
          * Ephemeral DH parameters:
          *
@@ -2880,8 +2873,8 @@
          *     opaque dh_Ys<1..2^16-1>;
          * } ServerDHParams;
          */
-        if( ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->dhm_P ) ) != 0 ||
-            ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->dhm_G ) ) != 0 )
+        if( ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->conf->dhm_P ) ) != 0 ||
+            ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->conf->dhm_G ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_copy", ret );
             return( ret );
@@ -2889,7 +2882,7 @@
 
         if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx,
                         (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
-                        p, &len, ssl->f_rng, ssl->p_rng ) ) != 0 )
+                        p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret );
             return( ret );
@@ -2927,7 +2920,7 @@
         const mbedtls_ecp_group_id *gid;
 
         /* Match our preference list against the offered curves */
-        for( gid = ssl->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
+        for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
             for( curve = ssl->handshake->curves; *curve != NULL; curve++ )
                 if( (*curve)->grp_id == *gid )
                     goto curve_matching_done;
@@ -2954,7 +2947,7 @@
 
         if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len,
                                       p, MBEDTLS_SSL_MAX_CONTENT_LEN - n,
-                                      ssl->f_rng, ssl->p_rng ) ) != 0 )
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
             return( ret );
@@ -3118,7 +3111,7 @@
 
         if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen,
                         p + 2 , &signature_len,
-                        ssl->f_rng, ssl->p_rng ) ) != 0 )
+                        ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
             return( ret );
@@ -3167,7 +3160,7 @@
     ssl->state++;
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         mbedtls_ssl_send_flight_completed( ssl );
 #endif
 
@@ -3268,7 +3261,7 @@
 
     mbedtls_ssl_write_version( ssl->handshake->max_major_ver,
                        ssl->handshake->max_minor_ver,
-                       ssl->transport, ver );
+                       ssl->conf->transport, ver );
     /*
      * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
      * must not cause the connection to end immediately; instead, send a
@@ -3276,14 +3269,14 @@
      * Also, avoid data-dependant branches here to protect against
      * timing-based variants.
      */
-    ret = ssl->f_rng( ssl->p_rng, fake_pms, sizeof( fake_pms ) );
+    ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
     if( ret != 0 )
         return( ret );
 
     ret = mbedtls_pk_decrypt( mbedtls_ssl_own_key( ssl ), p, len,
                       peer_pms, &peer_pmslen,
                       sizeof( peer_pms ),
-                      ssl->f_rng, ssl->p_rng );
+                      ssl->conf->f_rng, ssl->conf->p_rng );
 
     diff  = (size_t) ret;
     diff |= peer_pmslen ^ 48;
@@ -3320,9 +3313,9 @@
     int ret = 0;
     size_t n;
 
-    if( ssl->f_psk == NULL &&
-        ( ssl->psk == NULL || ssl->psk_identity == NULL ||
-          ssl->psk_identity_len == 0 || ssl->psk_len == 0 ) )
+    if( ssl->conf->f_psk == NULL &&
+        ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
+          ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) );
         return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
@@ -3346,17 +3339,17 @@
         return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
     }
 
-    if( ssl->f_psk != NULL )
+    if( ssl->conf->f_psk != NULL )
     {
-        if( ssl->f_psk( ssl->p_psk, ssl, *p, n ) != 0 )
+        if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 )
             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
     }
     else
     {
         /* Identity is not a big secret since clients send it in the clear,
          * but treat it carefully anyway, just in case */
-        if( n != ssl->psk_identity_len ||
-            mbedtls_ssl_safer_memcmp( ssl->psk_identity, *p, n ) != 0 )
+        if( n != ssl->conf->psk_identity_len ||
+            mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
         {
             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
         }
@@ -3432,7 +3425,7 @@
         if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
                                       ssl->handshake->premaster,
                                      &ssl->handshake->pmslen,
-                                      ssl->f_rng, ssl->p_rng ) ) != 0 )
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
@@ -3464,7 +3457,7 @@
                                       &ssl->handshake->pmslen,
                                        ssl->handshake->premaster,
                                        MBEDTLS_MPI_MAX_SIZE,
-                                       ssl->f_rng, ssl->p_rng ) ) != 0 )
+                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
             return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
@@ -3796,7 +3789,7 @@
 {
     int ret;
     size_t tlen;
-    uint32_t lifetime = (uint32_t) ssl->ticket_lifetime;
+    uint32_t lifetime = (uint32_t) ssl->conf->ticket_lifetime;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) );
 
@@ -3864,7 +3857,7 @@
         return( ret );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake != NULL &&
         ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
     {
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 9fb2c97..0a8119e 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -68,7 +68,7 @@
 static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
 {
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         return( 2 );
 #else
     ((void) ssl);
@@ -111,16 +111,16 @@
 {
     uint32_t new_timeout;
 
-    if( ssl->handshake->retransmit_timeout >= ssl->hs_timeout_max )
+    if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
         return( -1 );
 
     new_timeout = 2 * ssl->handshake->retransmit_timeout;
 
     /* Avoid arithmetic overflow and range overflow */
     if( new_timeout < ssl->handshake->retransmit_timeout ||
-        new_timeout > ssl->hs_timeout_max )
+        new_timeout > ssl->conf->hs_timeout_max )
     {
-        new_timeout = ssl->hs_timeout_max;
+        new_timeout = ssl->conf->hs_timeout_max;
     }
 
     ssl->handshake->retransmit_timeout = new_timeout;
@@ -132,7 +132,7 @@
 
 static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
 {
-    ssl->handshake->retransmit_timeout = ssl->hs_timeout_min;
+    ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
                         ssl->handshake->retransmit_timeout ) );
 }
@@ -772,7 +772,7 @@
      * Finally setup the cipher contexts, IVs and MAC secrets.
      */
 #if defined(MBEDTLS_SSL_CLI_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
     {
         key1 = keyblk + transform->maclen * 2;
         key2 = keyblk + transform->maclen * 2 + transform->keylen;
@@ -792,7 +792,7 @@
     else
 #endif /* MBEDTLS_SSL_CLI_C */
 #if defined(MBEDTLS_SSL_SRV_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER )
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
     {
         key1 = keyblk + transform->maclen * 2 + transform->keylen;
         key2 = keyblk + transform->maclen * 2;
@@ -1066,6 +1066,15 @@
 {
     unsigned char *p = ssl->handshake->premaster;
     unsigned char *end = p + sizeof( ssl->handshake->premaster );
+    const unsigned char *psk = ssl->conf->psk;
+    size_t psk_len = ssl->conf->psk_len;
+
+    /* If the psk callback was called, use its result */
+    if( ssl->handshake->psk != NULL )
+    {
+        psk = ssl->handshake->psk;
+        psk_len = ssl->handshake->psk_len;
+    }
 
     /*
      * PMS = struct {
@@ -1077,12 +1086,12 @@
 #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
     if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK )
     {
-        if( end - p < 2 + (int) ssl->psk_len )
+        if( end - p < 2 + (int) psk_len )
             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-        *(p++) = (unsigned char)( ssl->psk_len >> 8 );
-        *(p++) = (unsigned char)( ssl->psk_len      );
-        p += ssl->psk_len;
+        *(p++) = (unsigned char)( psk_len >> 8 );
+        *(p++) = (unsigned char)( psk_len      );
+        p += psk_len;
     }
     else
 #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
@@ -1108,7 +1117,7 @@
         /* Write length only when we know the actual value */
         if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
                                       p + 2, &len,
-                                      ssl->f_rng, ssl->p_rng ) ) != 0 )
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
             return( ret );
@@ -1129,7 +1138,7 @@
 
         if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
                                        p + 2, end - ( p + 2 ),
-                                       ssl->f_rng, ssl->p_rng ) ) != 0 )
+                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
             return( ret );
@@ -1149,13 +1158,13 @@
     }
 
     /* opaque psk<0..2^16-1>; */
-    if( end - p < 2 + (int) ssl->psk_len )
+    if( end - p < 2 + (int) psk_len )
             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-    *(p++) = (unsigned char)( ssl->psk_len >> 8 );
-    *(p++) = (unsigned char)( ssl->psk_len      );
-    memcpy( p, ssl->psk, ssl->psk_len );
-    p += ssl->psk_len;
+    *(p++) = (unsigned char)( psk_len >> 8 );
+    *(p++) = (unsigned char)( psk_len      );
+    memcpy( p, psk, psk_len );
+    p += psk_len;
 
     ssl->handshake->pmslen = p - ssl->handshake->premaster;
 
@@ -1327,7 +1336,7 @@
         memcpy( add_data, ssl->out_ctr, 8 );
         add_data[8]  = ssl->out_msgtype;
         mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
-                           ssl->transport, add_data + 9 );
+                           ssl->conf->transport, add_data + 9 );
         add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF;
         add_data[12] = ssl->out_msglen & 0xFF;
 
@@ -1338,7 +1347,7 @@
          * Generate IV
          */
 #if defined(MBEDTLS_SSL_AEAD_RANDOM_IV)
-        ret = ssl->f_rng( ssl->p_rng,
+        ret = ssl->conf->f_rng( ssl->conf->p_rng,
                 ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
                 ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
         if( ret != 0 )
@@ -1434,7 +1443,7 @@
             /*
              * Generate IV
              */
-            int ret = ssl->f_rng( ssl->p_rng, ssl->transform_out->iv_enc,
+            int ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc,
                                   ssl->transform_out->ivlen );
             if( ret != 0 )
                 return( ret );
@@ -1622,7 +1631,7 @@
         memcpy( add_data, ssl->in_ctr, 8 );
         add_data[8]  = ssl->in_msgtype;
         mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
-                           ssl->transport, add_data + 9 );
+                           ssl->conf->transport, add_data + 9 );
         add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
         add_data[12] = ssl->in_msglen & 0xFF;
 
@@ -1943,7 +1952,7 @@
                              ssl->in_msglen );
             mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec,
                              ssl->in_msg + ssl->in_msglen );
-            /* Call md_process at least once due to cache attacks */
+            /* Call mbedtls_md_process at least once due to cache attacks */
             for( j = 0; j < extra_run + 1; j++ )
                 mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
 
@@ -2005,7 +2014,7 @@
         ssl->nb_zero = 0;
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         ; /* in_ctr read from peer, not maintained internally */
     }
@@ -2138,9 +2147,9 @@
 {
     /* If renegotiation is not enforced, retransmit until we would reach max
      * timeout if we were using the usual handshake doubling scheme */
-    if( ssl->renego_max_records < 0 )
+    if( ssl->conf->renego_max_records < 0 )
     {
-        uint32_t ratio = ssl->hs_timeout_max / ssl->hs_timeout_min + 1;
+        uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
         unsigned char doublings = 1;
 
         while( ratio != 0 )
@@ -2186,7 +2195,7 @@
     if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
-                            "or mbedtls_ssl_set_bio_timeout()" ) );
+                            "or mbedtls_ssl_set_bio()" ) );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
@@ -2197,7 +2206,7 @@
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         uint32_t timeout;
 
@@ -2264,7 +2273,7 @@
          * that will end up being dropped.
          */
         if( ssl_check_timer( ssl ) != 0 )
-            ret = MBEDTLS_ERR_NET_TIMEOUT;
+            ret = MBEDTLS_ERR_SSL_TIMEOUT;
         else
         {
             len = MBEDTLS_SSL_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
@@ -2272,7 +2281,7 @@
             if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
                 timeout = ssl->handshake->retransmit_timeout;
             else
-                timeout = ssl->read_timeout;
+                timeout = ssl->conf->read_timeout;
 
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
 
@@ -2288,7 +2297,7 @@
                 return( MBEDTLS_ERR_SSL_CONN_EOF );
         }
 
-        if( ret == MBEDTLS_ERR_NET_TIMEOUT )
+        if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
         {
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
             ssl_set_timer( ssl, 0 );
@@ -2298,7 +2307,7 @@
                 if( ssl_double_retransmit_timeout( ssl ) != 0 )
                 {
                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
-                    return( MBEDTLS_ERR_NET_TIMEOUT );
+                    return( MBEDTLS_ERR_SSL_TIMEOUT );
                 }
 
                 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
@@ -2307,10 +2316,10 @@
                     return( ret );
                 }
 
-                return( MBEDTLS_ERR_NET_WANT_READ );
+                return( MBEDTLS_ERR_SSL_WANT_READ );
             }
 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
-            else if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER &&
+            else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
                      ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
             {
                 if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
@@ -2319,7 +2328,7 @@
                     return( ret );
                 }
 
-                return( MBEDTLS_ERR_NET_WANT_READ );
+                return( MBEDTLS_ERR_SSL_WANT_READ );
             }
 #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
         }
@@ -2372,7 +2381,7 @@
     if( ssl->f_send == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
-                            "or mbedtls_ssl_set_bio_timeout()" ) );
+                            "or mbedtls_ssl_set_bio()" ) );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
@@ -2655,7 +2664,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake != NULL &&
         ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
     {
@@ -2677,7 +2686,7 @@
          *      uint24 fragment_length;
          */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-        if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         {
             /* Make room for the additional DTLS fields */
             memmove( ssl->out_msg + 12, ssl->out_msg + 4, len - 4 );
@@ -2709,7 +2718,7 @@
 
     /* Save handshake and CCS messages for resending */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake != NULL &&
         ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING &&
         ( ssl->out_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ||
@@ -2757,7 +2766,7 @@
     {
         ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
         mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
-                           ssl->transport, ssl->out_hdr + 1 );
+                           ssl->conf->transport, ssl->out_hdr + 1 );
 
         ssl->out_len[0] = (unsigned char)( len >> 8 );
         ssl->out_len[1] = (unsigned char)( len      );
@@ -2964,7 +2973,7 @@
     if( ssl_bitmask_check( bitmask, msg_len ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 2, ( "message is not complete yet" ) );
-        return( MBEDTLS_ERR_NET_WANT_READ );
+        return( MBEDTLS_ERR_SSL_WANT_READ );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake message completed" ) );
@@ -3036,7 +3045,7 @@
                         ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         int ret;
         unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
@@ -3070,7 +3079,7 @@
                                     ssl->handshake->in_msg_seq ) );
             }
 
-            return( MBEDTLS_ERR_NET_WANT_READ );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
         }
         /* Wait until message completion to increment in_msg_seq */
 
@@ -3104,7 +3113,7 @@
 
     /* Handshake message is complete, increment counter */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake != NULL )
     {
         ssl->handshake->in_msg_seq++;
@@ -3149,7 +3158,7 @@
     uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
     uint64_t bit;
 
-    if( ssl->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
+    if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
         return( 0 );
 
     if( rec_seqnum > ssl->in_window_top )
@@ -3173,7 +3182,7 @@
 {
     uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
 
-    if( ssl->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
+    if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
         return;
 
     if( rec_seqnum > ssl->in_window_top )
@@ -3218,7 +3227,7 @@
 
     ssl->in_msgtype =  ssl->in_hdr[0];
     ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
-    mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->transport, ssl->in_hdr + 1 );
+    mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 );
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
                         "version = [%d:%d], msglen = %d",
@@ -3244,7 +3253,7 @@
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         /* Drop unexpected ChangeCipherSpec messages */
         if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
@@ -3278,7 +3287,7 @@
         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
     }
 
-    if( minor_ver > ssl->max_minor_ver )
+    if( minor_ver > ssl->conf->max_minor_ver )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
         return( MBEDTLS_ERR_SSL_INVALID_RECORD );
@@ -3286,7 +3295,7 @@
 
     /* Check epoch (and sequence number) with DTLS */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
 
@@ -3421,7 +3430,7 @@
 #endif /* MBEDTLS_ZLIB_SUPPORT */
 
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         mbedtls_ssl_dtls_replay_update( ssl );
     }
@@ -3480,7 +3489,7 @@
     if( ( ret = ssl_parse_record_header( ssl ) ) != 0 )
     {
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-        if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         {
             /* Ignore bad record and get next one; drop the whole datagram
              * since current header cannot be trusted to find the next record
@@ -3507,7 +3516,7 @@
 
     /* Done reading this record, get ready for the next one */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl );
     else
 #endif
@@ -3516,15 +3525,15 @@
     if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 )
     {
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-        if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         {
             /* Silently discard invalid records */
             if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD ||
                 ret == MBEDTLS_ERR_SSL_INVALID_MAC )
             {
 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
-                if( ssl->badmac_limit != 0 &&
-                    ++ssl->badmac_seen >= ssl->badmac_limit )
+                if( ssl->conf->badmac_limit != 0 &&
+                    ++ssl->badmac_seen >= ssl->conf->badmac_limit )
                 {
                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
                     return( MBEDTLS_ERR_SSL_INVALID_MAC );
@@ -3569,7 +3578,7 @@
      * being mistaken for an ancient message in the current handshake.
      */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake != NULL &&
         ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
     {
@@ -3584,7 +3593,7 @@
                 return( ret );
             }
 
-            return( MBEDTLS_ERR_NET_WANT_READ );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
         }
         else
         {
@@ -3735,7 +3744,7 @@
     }
 
 #if defined(MBEDTLS_SSL_CLI_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
     {
         if( ssl->client_auth == 0 )
         {
@@ -3764,7 +3773,7 @@
     }
 #endif /* MBEDTLS_SSL_CLI_C */
 #if defined(MBEDTLS_SSL_SRV_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER )
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
     {
         if( mbedtls_ssl_own_cert( ssl ) == NULL )
         {
@@ -3849,8 +3858,8 @@
     }
 
 #if defined(MBEDTLS_SSL_SRV_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER &&
-        ( ssl->authmode == MBEDTLS_SSL_VERIFY_NONE ||
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+        ( ssl->conf->authmode == MBEDTLS_SSL_VERIFY_NONE ||
           ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) )
     {
         ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY;
@@ -3873,7 +3882,7 @@
     /*
      * Check if the client sent an empty certificate
      */
-    if( ssl->endpoint  == MBEDTLS_SSL_IS_SERVER &&
+    if( ssl->conf->endpoint  == MBEDTLS_SSL_IS_SERVER &&
         ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         if( ssl->in_msglen  == 2                        &&
@@ -3884,7 +3893,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
 
             ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
-            if( ssl->authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
+            if( ssl->conf->authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
                 return( 0 );
             else
                 return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
@@ -3894,7 +3903,7 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
     defined(MBEDTLS_SSL_PROTO_TLS1_2)
-    if( ssl->endpoint  == MBEDTLS_SSL_IS_SERVER &&
+    if( ssl->conf->endpoint  == MBEDTLS_SSL_IS_SERVER &&
         ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         if( ssl->in_hslen   == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
@@ -3905,7 +3914,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
 
             ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
-            if( ssl->authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
+            if( ssl->conf->authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
                 return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
             else
                 return( 0 );
@@ -3997,7 +4006,7 @@
      * avoid "triple handshake" attack: https://secure-resumption.com/
      */
 #if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
         ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
     {
         if( ssl->session->peer_cert == NULL )
@@ -4018,9 +4027,25 @@
     }
 #endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
 
-    if( ssl->authmode != MBEDTLS_SSL_VERIFY_NONE )
+    if( ssl->conf->authmode != MBEDTLS_SSL_VERIFY_NONE )
     {
-        if( ssl->ca_chain == NULL )
+        mbedtls_x509_crt *ca_chain;
+        mbedtls_x509_crl *ca_crl;
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+        if( ssl->handshake->sni_ca_chain != NULL )
+        {
+            ca_chain = ssl->handshake->sni_ca_chain;
+            ca_crl   = ssl->handshake->sni_ca_crl;
+        }
+        else
+#endif
+        {
+            ca_chain = ssl->conf->ca_chain;
+            ca_crl   = ssl->conf->ca_crl;
+        }
+
+        if( ca_chain == NULL )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
             return( MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED );
@@ -4030,9 +4055,9 @@
          * Main check: verify certificate
          */
         ret = mbedtls_x509_crt_verify( ssl->session_negotiate->peer_cert,
-                               ssl->ca_chain, ssl->ca_crl, ssl->peer_cn,
+                               ca_chain, ca_crl, ssl->hostname,
                               &ssl->session_negotiate->verify_result,
-                               ssl->f_vrfy, ssl->p_vrfy );
+                               ssl->conf->f_vrfy, ssl->conf->p_vrfy );
 
         if( ret != 0 )
         {
@@ -4060,7 +4085,7 @@
 
         if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
                                   ciphersuite_info,
-                                  ! ssl->endpoint,
+                                  ! ssl->conf->endpoint,
                                  &ssl->session_negotiate->verify_result ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
@@ -4068,7 +4093,7 @@
                 ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
         }
 
-        if( ssl->authmode != MBEDTLS_SSL_VERIFY_REQUIRED )
+        if( ssl->conf->authmode != MBEDTLS_SSL_VERIFY_REQUIRED )
             ret = 0;
     }
 
@@ -4140,7 +4165,7 @@
     ssl->session_in = ssl->session_negotiate;
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
         ssl_dtls_replay_reset( ssl );
@@ -4571,16 +4596,16 @@
     /*
      * Add cache entry
      */
-    if( ssl->f_set_cache != NULL &&
+    if( ssl->conf->f_set_cache != NULL &&
         ssl->session->length != 0 &&
         resume == 0 )
     {
-        if( ssl->f_set_cache( ssl->p_set_cache, ssl->session ) != 0 )
+        if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 )
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) );
     }
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->handshake->flight != NULL )
     {
         /* Cancel handshake timer */
@@ -4616,7 +4641,7 @@
     else
         ssl->out_msg = ssl->out_iv;
 
-    ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->endpoint );
+    ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
 
     // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
     hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12;
@@ -4637,11 +4662,11 @@
     if( ssl->handshake->resume != 0 )
     {
 #if defined(MBEDTLS_SSL_CLI_C)
-        if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT )
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
             ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
 #endif
 #if defined(MBEDTLS_SSL_SRV_C)
-        if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER )
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
             ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
 #endif
     }
@@ -4655,7 +4680,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         unsigned char i;
 
@@ -4697,7 +4722,7 @@
 #endif
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         mbedtls_ssl_send_flight_completed( ssl );
 #endif
 
@@ -4726,7 +4751,7 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
 
-    ssl->handshake->calc_finished( ssl, buf, ssl->endpoint ^ 1 );
+    ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
 
     if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
     {
@@ -4770,11 +4795,11 @@
     if( ssl->handshake->resume != 0 )
     {
 #if defined(MBEDTLS_SSL_CLI_C)
-        if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT )
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
             ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
 #endif
 #if defined(MBEDTLS_SSL_SRV_C)
-        if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER )
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
             ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
 #endif
     }
@@ -4782,7 +4807,7 @@
         ssl->state++;
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         mbedtls_ssl_recv_flight_completed( ssl );
 #endif
 
@@ -4892,22 +4917,16 @@
     ssl_transform_init( ssl->transform_negotiate );
     ssl_handshake_params_init( ssl->handshake );
 
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-    ssl->handshake->key_cert = ssl->key_cert;
-#endif
-
-    /*
-     * We may not know yet if we're using DTLS,
-     * so always initiliase DTLS-specific fields.
-     */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    ssl->handshake->alt_transform_out = ssl->transform_out;
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->handshake->alt_transform_out = ssl->transform_out;
 
-    // TODO: not the right place, we may not know endpoint yet
-    if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT )
-        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
-    else
-        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+            ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
+        else
+            ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+    }
 #endif
 
     return( 0 );
@@ -4953,44 +4972,18 @@
 /*
  * Setup an SSL context
  */
-int mbedtls_ssl_setup( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
+                       const mbedtls_ssl_config *conf )
 {
     int ret;
-    int len = MBEDTLS_SSL_BUFFER_LEN;
+    const size_t len = MBEDTLS_SSL_BUFFER_LEN;
 
-    /*
-     * Sane defaults
-     */
-    ssl->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
-    ssl->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS 1.0 */
-    ssl->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
-    ssl->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
-
-    mbedtls_ssl_set_ciphersuites( ssl, mbedtls_ssl_list_ciphersuites() );
-
-    mbedtls_ssl_set_arc4_support( ssl, MBEDTLS_SSL_ARC4_DISABLED );
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
-    ssl->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT;
-    memset( ssl->renego_period, 0xFF, 7 );
-    ssl->renego_period[7] = 0x00;
-#endif
-
-#if defined(MBEDTLS_DHM_C)
-    if( ( ret = mbedtls_mpi_read_string( &ssl->dhm_P, 16,
-                                 MBEDTLS_DHM_RFC5114_MODP_1024_P) ) != 0 ||
-        ( ret = mbedtls_mpi_read_string( &ssl->dhm_G, 16,
-                                 MBEDTLS_DHM_RFC5114_MODP_1024_G) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_read_string", ret );
-        return( ret );
-    }
-#endif
+    ssl->conf = conf;
 
     /*
      * Prepare base structures
      */
-    if( ( ssl->in_buf = mbedtls_malloc( len ) ) == NULL ||
+    if( ( ssl-> in_buf = mbedtls_malloc( len ) ) == NULL ||
         ( ssl->out_buf = mbedtls_malloc( len ) ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) );
@@ -4999,41 +4992,39 @@
         return( MBEDTLS_ERR_SSL_MALLOC_FAILED );
     }
 
-    memset( ssl-> in_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
-    memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
-
-    /* No error is possible, MBEDTLS_SSL_TRANSPORT_STREAM always valid */
-    (void) mbedtls_ssl_set_transport( ssl, MBEDTLS_SSL_TRANSPORT_STREAM );
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-    ssl->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
-#endif
-
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    ssl->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
-#endif
-
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    ssl->ticket_lifetime = MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME;
-#endif
-
-#if defined(MBEDTLS_SSL_SET_CURVES)
-    ssl->curve_list = mbedtls_ecp_grp_id_list( );
-#endif
-
-#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
-    ssl->f_cookie_write = ssl_cookie_write_dummy;
-    ssl->f_cookie_check = ssl_cookie_check_dummy;
-#endif
-
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-    ssl->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED;
-#endif
+    memset( ssl-> in_buf, 0, len );
+    memset( ssl->out_buf, 0, len );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    ssl->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
-    ssl->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
+    if( conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->out_hdr = ssl->out_buf;
+        ssl->out_ctr = ssl->out_buf +  3;
+        ssl->out_len = ssl->out_buf + 11;
+        ssl->out_iv  = ssl->out_buf + 13;
+        ssl->out_msg = ssl->out_buf + 13;
+
+        ssl->in_hdr = ssl->in_buf;
+        ssl->in_ctr = ssl->in_buf +  3;
+        ssl->in_len = ssl->in_buf + 11;
+        ssl->in_iv  = ssl->in_buf + 13;
+        ssl->in_msg = ssl->in_buf + 13;
+    }
+    else
 #endif
+    {
+        ssl->out_ctr = ssl->out_buf;
+        ssl->out_hdr = ssl->out_buf +  8;
+        ssl->out_len = ssl->out_buf + 11;
+        ssl->out_iv  = ssl->out_buf + 13;
+        ssl->out_msg = ssl->out_buf + 13;
+
+        ssl->in_ctr = ssl->in_buf;
+        ssl->in_hdr = ssl->in_buf +  8;
+        ssl->in_len = ssl->in_buf + 11;
+        ssl->in_iv  = ssl->in_buf + 13;
+        ssl->in_msg = ssl->in_buf + 13;
+    }
 
     if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
         return( ret );
@@ -5148,13 +5139,13 @@
 /*
  * Allocate and initialize ticket keys
  */
-static int ssl_ticket_keys_init( mbedtls_ssl_context *ssl )
+static int ssl_ticket_keys_init( mbedtls_ssl_config *conf )
 {
     int ret;
     mbedtls_ssl_ticket_keys *tkeys;
     unsigned char buf[16];
 
-    if( ssl->ticket_keys != NULL )
+    if( conf->ticket_keys != NULL )
         return( 0 );
 
     tkeys = mbedtls_malloc( sizeof(mbedtls_ssl_ticket_keys) );
@@ -5164,15 +5155,15 @@
     mbedtls_aes_init( &tkeys->enc );
     mbedtls_aes_init( &tkeys->dec );
 
-    if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->key_name, 16 ) ) != 0 )
-    {
-        ssl_ticket_keys_free( tkeys );
-        mbedtls_free( tkeys );
-        return( ret );
-    }
+    /* Temporary WIP! Using hardcoded keys. This is to remove the dependency
+     * on the RNG and allow puttint the keys in conf. Key generation will soon
+     * be move outside the main SSL module anyway. */
 
-    if( ( ret = ssl->f_rng( ssl->p_rng, buf, 16 ) ) != 0 ||
-        ( ret = mbedtls_aes_setkey_enc( &tkeys->enc, buf, 128 ) ) != 0 ||
+    memset( tkeys->key_name, 'x', 16 );
+    memset( tkeys->mac_key, 0x2a, 16 );
+    memset( buf, 0x2a, 16 );
+
+    if( ( ret = mbedtls_aes_setkey_enc( &tkeys->enc, buf, 128 ) ) != 0 ||
         ( ret = mbedtls_aes_setkey_dec( &tkeys->dec, buf, 128 ) ) != 0 )
     {
         ssl_ticket_keys_free( tkeys );
@@ -5180,14 +5171,7 @@
         return( ret );
     }
 
-    if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->mac_key, 16 ) ) != 0 )
-    {
-        ssl_ticket_keys_free( tkeys );
-        mbedtls_free( tkeys );
-        return( ret );
-    }
-
-    ssl->ticket_keys = tkeys;
+    conf->ticket_keys = tkeys;
 
     return( 0 );
 }
@@ -5196,172 +5180,95 @@
 /*
  * SSL set accessors
  */
-void mbedtls_ssl_set_endpoint( mbedtls_ssl_context *ssl, int endpoint )
+void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint )
 {
-    ssl->endpoint   = endpoint;
-
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
-    defined(MBEDTLS_SSL_CLI_C)
-    if( endpoint == MBEDTLS_SSL_IS_CLIENT )
-    {
-        ssl->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
-        ssl->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
-    }
-#endif
-
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-    if( endpoint == MBEDTLS_SSL_IS_SERVER )
-        ssl->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
-#endif
+    conf->endpoint   = endpoint;
 }
 
-int mbedtls_ssl_set_transport( mbedtls_ssl_context *ssl, int transport )
+void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport )
 {
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-    {
-        ssl->transport = transport;
-
-        ssl->out_hdr = ssl->out_buf;
-        ssl->out_ctr = ssl->out_buf +  3;
-        ssl->out_len = ssl->out_buf + 11;
-        ssl->out_iv  = ssl->out_buf + 13;
-        ssl->out_msg = ssl->out_buf + 13;
-
-        ssl->in_hdr = ssl->in_buf;
-        ssl->in_ctr = ssl->in_buf +  3;
-        ssl->in_len = ssl->in_buf + 11;
-        ssl->in_iv  = ssl->in_buf + 13;
-        ssl->in_msg = ssl->in_buf + 13;
-
-        /* DTLS starts with TLS1.1 */
-        if( ssl->min_minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
-            ssl->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
-
-        if( ssl->max_minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
-            ssl->max_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
-
-        return( 0 );
-    }
-#endif
-
-    if( transport == MBEDTLS_SSL_TRANSPORT_STREAM )
-    {
-        ssl->transport = transport;
-
-        ssl->out_ctr = ssl->out_buf;
-        ssl->out_hdr = ssl->out_buf +  8;
-        ssl->out_len = ssl->out_buf + 11;
-        ssl->out_iv  = ssl->out_buf + 13;
-        ssl->out_msg = ssl->out_buf + 13;
-
-        ssl->in_ctr = ssl->in_buf;
-        ssl->in_hdr = ssl->in_buf +  8;
-        ssl->in_len = ssl->in_buf + 11;
-        ssl->in_iv  = ssl->in_buf + 13;
-        ssl->in_msg = ssl->in_buf + 13;
-
-        return( 0 );
-    }
-
-    return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    conf->transport = transport;
 }
 
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-void mbedtls_ssl_set_dtls_anti_replay( mbedtls_ssl_context *ssl, char mode )
+void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode )
 {
-    ssl->anti_replay = mode;
+    conf->anti_replay = mode;
 }
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
-void mbedtls_ssl_set_dtls_badmac_limit( mbedtls_ssl_context *ssl, unsigned limit )
+void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit )
 {
-    ssl->badmac_limit = limit;
+    conf->badmac_limit = limit;
 }
 #endif
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-void mbedtls_ssl_set_handshake_timeout( mbedtls_ssl_context *ssl, uint32_t min, uint32_t max )
+void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max )
 {
-    ssl->hs_timeout_min = min;
-    ssl->hs_timeout_max = max;
+    conf->hs_timeout_min = min;
+    conf->hs_timeout_max = max;
 }
 #endif
 
-void mbedtls_ssl_set_authmode( mbedtls_ssl_context *ssl, int authmode )
+void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode )
 {
-    ssl->authmode   = authmode;
+    conf->authmode   = authmode;
 }
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
-void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, int *),
                      void *p_vrfy )
 {
-    ssl->f_vrfy      = f_vrfy;
-    ssl->p_vrfy      = p_vrfy;
+    conf->f_vrfy      = f_vrfy;
+    conf->p_vrfy      = p_vrfy;
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
-void mbedtls_ssl_set_rng( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
                   int (*f_rng)(void *, unsigned char *, size_t),
                   void *p_rng )
 {
-    ssl->f_rng      = f_rng;
-    ssl->p_rng      = p_rng;
+    conf->f_rng      = f_rng;
+    conf->p_rng      = p_rng;
 }
 
-void mbedtls_ssl_set_dbg( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
                   void (*f_dbg)(void *, int, const char *),
                   void  *p_dbg )
 {
-    ssl->f_dbg      = f_dbg;
-    ssl->p_dbg      = p_dbg;
+    conf->f_dbg      = f_dbg;
+    conf->p_dbg      = p_dbg;
 }
 
-#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
 void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
-            int (*f_recv)(void *, unsigned char *, size_t), void *p_recv,
-            int (*f_send)(void *, const unsigned char *, size_t), void *p_send )
-{
-    if( p_recv != p_send )
-    {
-        ssl->f_recv = NULL;
-        ssl->f_send = NULL;
-        ssl->p_bio  = NULL;
-        return;
-    }
-
-    ssl->f_recv     = f_recv;
-    ssl->f_send     = f_send;
-    ssl->p_bio      = p_send;
-}
-#endif /* MBEDTLS_DEPRECATED_REMOVED */
-
-void mbedtls_ssl_set_bio_timeout( mbedtls_ssl_context *ssl,
         void *p_bio,
         int (*f_send)(void *, const unsigned char *, size_t),
         int (*f_recv)(void *, unsigned char *, size_t),
-        int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t),
-        uint32_t timeout )
+        int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) )
 {
     ssl->p_bio          = p_bio;
     ssl->f_send         = f_send;
     ssl->f_recv         = f_recv;
     ssl->f_recv_timeout = f_recv_timeout;
-    ssl->read_timeout   = timeout;
+}
+
+void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout )
+{
+    conf->read_timeout   = timeout;
 }
 
 #if defined(MBEDTLS_SSL_SRV_C)
-void mbedtls_ssl_set_session_cache( mbedtls_ssl_context *ssl,
-        int (*f_get_cache)(void *, mbedtls_ssl_session *), void *p_get_cache,
-        int (*f_set_cache)(void *, const mbedtls_ssl_session *), void *p_set_cache )
+void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
+        void *p_cache,
+        int (*f_get_cache)(void *, mbedtls_ssl_session *),
+        int (*f_set_cache)(void *, const mbedtls_ssl_session *) )
 {
-    ssl->f_get_cache = f_get_cache;
-    ssl->p_get_cache = p_get_cache;
-    ssl->f_set_cache = f_set_cache;
-    ssl->p_set_cache = p_set_cache;
+    conf->p_cache = p_cache;
+    conf->f_get_cache = f_get_cache;
+    conf->f_set_cache = f_set_cache;
 }
 #endif /* MBEDTLS_SSL_SRV_C */
 
@@ -5373,7 +5280,7 @@
     if( ssl == NULL ||
         session == NULL ||
         ssl->session_negotiate == NULL ||
-        ssl->endpoint != MBEDTLS_SSL_IS_CLIENT )
+        ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
     {
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
@@ -5387,15 +5294,16 @@
 }
 #endif /* MBEDTLS_SSL_CLI_C */
 
-void mbedtls_ssl_set_ciphersuites( mbedtls_ssl_context *ssl, const int *ciphersuites )
+void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
+                                   const int *ciphersuites )
 {
-    ssl->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites;
-    ssl->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites;
-    ssl->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites;
-    ssl->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites;
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites;
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites;
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites;
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites;
 }
 
-void mbedtls_ssl_set_ciphersuites_for_version( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
                                        const int *ciphersuites,
                                        int major, int minor )
 {
@@ -5405,65 +5313,79 @@
     if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 )
         return;
 
-    ssl->ciphersuite_list[minor] = ciphersuites;
+    conf->ciphersuite_list[minor] = ciphersuites;
 }
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
-/* Add a new (empty) key_cert entry an return a pointer to it */
-static mbedtls_ssl_key_cert *ssl_add_key_cert( mbedtls_ssl_context *ssl )
+/* Append a new keycert entry to a (possibly empty) list */
+static int ssl_append_key_cert( mbedtls_ssl_key_cert **head,
+                                mbedtls_x509_crt *cert,
+                                mbedtls_pk_context *key )
 {
-    mbedtls_ssl_key_cert *key_cert, *last;
+    mbedtls_ssl_key_cert *new;
 
-    key_cert = mbedtls_malloc( sizeof(mbedtls_ssl_key_cert) );
-    if( key_cert == NULL )
-        return( NULL );
+    new = mbedtls_malloc( sizeof( mbedtls_ssl_key_cert ) );
+    if( new == NULL )
+        return( MBEDTLS_ERR_SSL_MALLOC_FAILED );
 
-    memset( key_cert, 0, sizeof( mbedtls_ssl_key_cert ) );
+    new->cert = cert;
+    new->key  = key;
+    new->next = NULL;
 
-    /* Append the new key_cert to the (possibly empty) current list */
-    if( ssl->key_cert == NULL )
+    /* Update head is the list was null, else add to the end */
+    if( *head == NULL )
     {
-        ssl->key_cert = key_cert;
-        if( ssl->handshake != NULL )
-            ssl->handshake->key_cert = key_cert;
+        *head = new;
     }
     else
     {
-        last = ssl->key_cert;
-        while( last->next != NULL )
-            last = last->next;
-        last->next = key_cert;
+        mbedtls_ssl_key_cert *cur = *head;
+        while( cur->next != NULL )
+            cur = cur->next;
+        cur->next = new;
     }
 
-    return( key_cert );
-}
-
-void mbedtls_ssl_set_ca_chain( mbedtls_ssl_context *ssl, mbedtls_x509_crt *ca_chain,
-                       mbedtls_x509_crl *ca_crl, const char *peer_cn )
-{
-    ssl->ca_chain   = ca_chain;
-    ssl->ca_crl     = ca_crl;
-    ssl->peer_cn    = peer_cn;
-}
-
-int mbedtls_ssl_set_own_cert( mbedtls_ssl_context *ssl, mbedtls_x509_crt *own_cert,
-                       mbedtls_pk_context *pk_key )
-{
-    mbedtls_ssl_key_cert *key_cert = ssl_add_key_cert( ssl );
-
-    if( key_cert == NULL )
-        return( MBEDTLS_ERR_SSL_MALLOC_FAILED );
-
-    key_cert->cert = own_cert;
-    key_cert->key  = pk_key;
-
     return( 0 );
 }
+
+int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
+                              mbedtls_x509_crt *own_cert,
+                              mbedtls_pk_context *pk_key )
+{
+    return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) );
+}
+
+void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
+                               mbedtls_x509_crt *ca_chain,
+                               mbedtls_x509_crl *ca_crl )
+{
+    conf->ca_chain   = ca_chain;
+    conf->ca_crl     = ca_crl;
+}
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl,
+                                 mbedtls_x509_crt *own_cert,
+                                 mbedtls_pk_context *pk_key )
+{
+    return( ssl_append_key_cert( &ssl->handshake->sni_key_cert,
+                                 own_cert, pk_key ) );
+}
+
+void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
+                                  mbedtls_x509_crt *ca_chain,
+                                  mbedtls_x509_crl *ca_crl )
+{
+    ssl->handshake->sni_ca_chain   = ca_chain;
+    ssl->handshake->sni_ca_crl     = ca_crl;
+}
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-int mbedtls_ssl_set_psk( mbedtls_ssl_context *ssl, const unsigned char *psk, size_t psk_len,
-                 const unsigned char *psk_identity, size_t psk_identity_len )
+int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
+                const unsigned char *psk, size_t psk_len,
+                const unsigned char *psk_identity, size_t psk_identity_len )
 {
     if( psk == NULL || psk_identity == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -5471,72 +5393,89 @@
     if( psk_len > MBEDTLS_PSK_MAX_LEN )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-    if( ssl->psk != NULL || ssl->psk_identity != NULL )
+    if( conf->psk != NULL || conf->psk_identity != NULL )
     {
-        mbedtls_free( ssl->psk );
-        mbedtls_free( ssl->psk_identity );
+        mbedtls_free( conf->psk );
+        mbedtls_free( conf->psk_identity );
     }
 
-    if( ( ssl->psk = mbedtls_malloc( psk_len ) ) == NULL ||
-        ( ssl->psk_identity = mbedtls_malloc( psk_identity_len ) ) == NULL )
+    if( ( conf->psk = mbedtls_malloc( psk_len ) ) == NULL ||
+        ( conf->psk_identity = mbedtls_malloc( psk_identity_len ) ) == NULL )
     {
-        mbedtls_free( ssl->psk );
-        ssl->psk = NULL;
+        mbedtls_free( conf->psk );
+        conf->psk = NULL;
         return( MBEDTLS_ERR_SSL_MALLOC_FAILED );
     }
 
-    ssl->psk_len = psk_len;
-    ssl->psk_identity_len = psk_identity_len;
+    conf->psk_len = psk_len;
+    conf->psk_identity_len = psk_identity_len;
 
-    memcpy( ssl->psk, psk, ssl->psk_len );
-    memcpy( ssl->psk_identity, psk_identity, ssl->psk_identity_len );
+    memcpy( conf->psk, psk, conf->psk_len );
+    memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len );
 
     return( 0 );
 }
 
-void mbedtls_ssl_set_psk_cb( mbedtls_ssl_context *ssl,
+int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
+                            const unsigned char *psk, size_t psk_len )
+{
+    if( psk == NULL || ssl->handshake == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( psk_len > MBEDTLS_PSK_MAX_LEN )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( ssl->handshake->psk != NULL )
+        mbedtls_free( ssl->conf->psk );
+
+    if( ( ssl->handshake->psk = mbedtls_malloc( psk_len ) ) == NULL )
+    {
+        mbedtls_free( ssl->handshake->psk );
+        ssl->handshake->psk = NULL;
+        return( MBEDTLS_ERR_SSL_MALLOC_FAILED );
+    }
+
+    ssl->handshake->psk_len = psk_len;
+    memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len );
+
+    return( 0 );
+}
+
+void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
                      int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
                      size_t),
                      void *p_psk )
 {
-    ssl->f_psk = f_psk;
-    ssl->p_psk = p_psk;
+    conf->f_psk = f_psk;
+    conf->p_psk = p_psk;
 }
 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
 #if defined(MBEDTLS_DHM_C)
-int mbedtls_ssl_set_dh_param( mbedtls_ssl_context *ssl, const char *dhm_P, const char *dhm_G )
+int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G )
 {
     int ret;
 
-    if( ( ret = mbedtls_mpi_read_string( &ssl->dhm_P, 16, dhm_P ) ) != 0 )
+    if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 ||
+        ( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 )
     {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_read_string", ret );
-        return( ret );
-    }
-
-    if( ( ret = mbedtls_mpi_read_string( &ssl->dhm_G, 16, dhm_G ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_read_string", ret );
+        mbedtls_mpi_free( &conf->dhm_P );
+        mbedtls_mpi_free( &conf->dhm_G );
         return( ret );
     }
 
     return( 0 );
 }
 
-int mbedtls_ssl_set_dh_param_ctx( mbedtls_ssl_context *ssl, mbedtls_dhm_context *dhm_ctx )
+int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx )
 {
     int ret;
 
-    if( ( ret = mbedtls_mpi_copy( &ssl->dhm_P, &dhm_ctx->P ) ) != 0 )
+    if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
     {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_copy", ret );
-        return( ret );
-    }
-
-    if( ( ret = mbedtls_mpi_copy( &ssl->dhm_G, &dhm_ctx->G ) ) != 0 )
-    {
-        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_copy", ret );
+        mbedtls_mpi_free( &conf->dhm_P );
+        mbedtls_mpi_free( &conf->dhm_G );
         return( ret );
     }
 
@@ -5548,48 +5487,52 @@
 /*
  * Set the allowed elliptic curves
  */
-void mbedtls_ssl_set_curves( mbedtls_ssl_context *ssl, const mbedtls_ecp_group_id *curve_list )
+void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
+                             const mbedtls_ecp_group_id *curve_list )
 {
-  ssl->curve_list = curve_list;
+    conf->curve_list = curve_list;
 }
 #endif
 
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
 int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname )
 {
+    size_t hostname_len;
+
     if( hostname == NULL )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-    ssl->hostname_len = strlen( hostname );
+    hostname_len = strlen( hostname );
 
-    if( ssl->hostname_len + 1 == 0 )
+    if( hostname_len + 1 == 0 )
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 
-    ssl->hostname = mbedtls_malloc( ssl->hostname_len + 1 );
+    ssl->hostname = mbedtls_malloc( hostname_len + 1 );
 
     if( ssl->hostname == NULL )
         return( MBEDTLS_ERR_SSL_MALLOC_FAILED );
 
-    memcpy( ssl->hostname, (const unsigned char *) hostname,
-            ssl->hostname_len );
+    memcpy( ssl->hostname, hostname, hostname_len );
 
-    ssl->hostname[ssl->hostname_len] = '\0';
+    ssl->hostname[hostname_len] = '\0';
 
     return( 0 );
 }
+#endif
 
-void mbedtls_ssl_set_sni( mbedtls_ssl_context *ssl,
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
                   int (*f_sni)(void *, mbedtls_ssl_context *,
                                 const unsigned char *, size_t),
                   void *p_sni )
 {
-    ssl->f_sni = f_sni;
-    ssl->p_sni = p_sni;
+    conf->f_sni = f_sni;
+    conf->p_sni = p_sni;
 }
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 
 #if defined(MBEDTLS_SSL_ALPN)
-int mbedtls_ssl_set_alpn_protocols( mbedtls_ssl_context *ssl, const char **protos )
+int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos )
 {
     size_t cur_len, tot_len;
     const char **p;
@@ -5608,7 +5551,7 @@
             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    ssl->alpn_list = protos;
+    conf->alpn_list = protos;
 
     return( 0 );
 }
@@ -5619,77 +5562,46 @@
 }
 #endif /* MBEDTLS_SSL_ALPN */
 
-static int ssl_check_version( const mbedtls_ssl_context *ssl, int major, int minor )
+void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
 {
-    if( major < MBEDTLS_SSL_MIN_MAJOR_VERSION || major > MBEDTLS_SSL_MAX_MAJOR_VERSION ||
-        minor < MBEDTLS_SSL_MIN_MINOR_VERSION || minor > MBEDTLS_SSL_MAX_MINOR_VERSION )
-    {
-        return( -1 );
-    }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
-        minor < MBEDTLS_SSL_MINOR_VERSION_2 )
-    {
-        return( -1 );
-    }
-#else
-    ((void) ssl);
-#endif
-
-    return( 0 );
+    conf->max_major_ver = major;
+    conf->max_minor_ver = minor;
 }
 
-int mbedtls_ssl_set_max_version( mbedtls_ssl_context *ssl, int major, int minor )
+void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor )
 {
-    if( ssl_check_version( ssl, major, minor ) != 0 )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    ssl->max_major_ver = major;
-    ssl->max_minor_ver = minor;
-
-    return( 0 );
-}
-
-int mbedtls_ssl_set_min_version( mbedtls_ssl_context *ssl, int major, int minor )
-{
-    if( ssl_check_version( ssl, major, minor ) != 0 )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    ssl->min_major_ver = major;
-    ssl->min_minor_ver = minor;
-
-    return( 0 );
+    conf->min_major_ver = major;
+    conf->min_minor_ver = minor;
 }
 
 #if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
-void mbedtls_ssl_set_fallback( mbedtls_ssl_context *ssl, char fallback )
+void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback )
 {
-    ssl->fallback = fallback;
+    conf->fallback = fallback;
 }
 #endif
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
-void mbedtls_ssl_set_encrypt_then_mac( mbedtls_ssl_context *ssl, char etm )
+void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm )
 {
-    ssl->encrypt_then_mac = etm;
+    conf->encrypt_then_mac = etm;
 }
 #endif
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-void mbedtls_ssl_set_extended_master_secret( mbedtls_ssl_context *ssl, char ems )
+void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems )
 {
-    ssl->extended_ms = ems;
+    conf->extended_ms = ems;
 }
 #endif
 
-void mbedtls_ssl_set_arc4_support( mbedtls_ssl_context *ssl, char arc4 )
+void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 )
 {
-    ssl->arc4_disabled = arc4;
+    conf->arc4_disabled = arc4;
 }
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-int mbedtls_ssl_set_max_frag_len( mbedtls_ssl_context *ssl, unsigned char mfl_code )
+int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code )
 {
     if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ||
         mfl_code_to_length[mfl_code] > MBEDTLS_SSL_MAX_CONTENT_LEN )
@@ -5697,73 +5609,68 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    ssl->mfl_code = mfl_code;
+    conf->mfl_code = mfl_code;
 
     return( 0 );
 }
 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
-int mbedtls_ssl_set_truncated_hmac( mbedtls_ssl_context *ssl, int truncate )
+void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate )
 {
-    ssl->trunc_hmac = truncate;
-
-    return( 0 );
+    conf->trunc_hmac = truncate;
 }
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
 
 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
-void mbedtls_ssl_set_cbc_record_splitting( mbedtls_ssl_context *ssl, char split )
+void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split )
 {
-    ssl->split_done = split;
+    conf->cbc_record_splitting = split;
 }
 #endif
 
-void mbedtls_ssl_legacy_renegotiation( mbedtls_ssl_context *ssl, int allow_legacy )
+void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy )
 {
-    ssl->allow_legacy_renegotiation = allow_legacy;
+    conf->allow_legacy_renegotiation = allow_legacy;
 }
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-void mbedtls_ssl_set_renegotiation( mbedtls_ssl_context *ssl, int renegotiation )
+void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation )
 {
-    ssl->disable_renegotiation = renegotiation;
+    conf->disable_renegotiation = renegotiation;
 }
 
-void mbedtls_ssl_set_renegotiation_enforced( mbedtls_ssl_context *ssl, int max_records )
+void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records )
 {
-    ssl->renego_max_records = max_records;
+    conf->renego_max_records = max_records;
 }
 
-void mbedtls_ssl_set_renegotiation_period( mbedtls_ssl_context *ssl,
+void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
                                    const unsigned char period[8] )
 {
-    memcpy( ssl->renego_period, period, 8 );
+    memcpy( conf->renego_period, period, 8 );
 }
 #endif /* MBEDTLS_SSL_RENEGOTIATION */
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-int mbedtls_ssl_set_session_tickets( mbedtls_ssl_context *ssl, int use_tickets )
+int mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets )
 {
-    ssl->session_tickets = use_tickets;
+    conf->session_tickets = use_tickets;
 
 #if defined(MBEDTLS_SSL_CLI_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    if( conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
         return( 0 );
 #endif
 
     if( use_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
         return( 0 );
 
-    if( ssl->f_rng == NULL )
-        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
-    return( ssl_ticket_keys_init( ssl ) );
+    return( ssl_ticket_keys_init( conf ) );
 }
 
-void mbedtls_ssl_set_session_ticket_lifetime( mbedtls_ssl_context *ssl, int lifetime )
+void mbedtls_ssl_conf_session_ticket_lifetime( mbedtls_ssl_config *conf, int lifetime )
 {
-    ssl->ticket_lifetime = lifetime;
+    conf->ticket_lifetime = lifetime;
 }
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
 
@@ -5797,7 +5704,7 @@
 const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
 {
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         switch( ssl->minor_ver )
         {
@@ -5882,7 +5789,7 @@
     if( ssl == NULL ||
         dst == NULL ||
         ssl->session == NULL ||
-        ssl->endpoint != MBEDTLS_SSL_IS_CLIENT )
+        ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
     {
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
@@ -5899,11 +5806,11 @@
     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
 
 #if defined(MBEDTLS_SSL_CLI_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
         ret = mbedtls_ssl_handshake_client_step( ssl );
 #endif
 #if defined(MBEDTLS_SSL_SRV_C)
-    if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER )
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
         ret = mbedtls_ssl_handshake_server_step( ssl );
 #endif
 
@@ -5980,10 +5887,10 @@
     /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and
      * the ServerHello will have message_seq = 1" */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
         ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
     {
-        if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER )
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
             ssl->handshake->out_msg_seq = 1;
         else
             ssl->handshake->in_msg_seq = 1;
@@ -6014,7 +5921,7 @@
 
 #if defined(MBEDTLS_SSL_SRV_C)
     /* On server, just send the request */
-    if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER )
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
     {
         if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
             return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -6065,14 +5972,14 @@
 {
     if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
         ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
-        ssl->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
+        ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
     {
         return( 0 );
     }
 
     // TODO: adapt for DTLS
-    if( memcmp( ssl->in_ctr,  ssl->renego_period, 8 ) <= 0 &&
-        memcmp( ssl->out_ctr, ssl->renego_period, 8 ) <= 0 )
+    if( memcmp( ssl->in_ctr,  ssl->conf->renego_period, 8 ) <= 0 &&
+        memcmp( ssl->out_ctr, ssl->conf->renego_period, 8 ) <= 0 )
     {
         return( 0 );
     }
@@ -6093,7 +6000,7 @@
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
     {
         if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
             return( ret );
@@ -6134,7 +6041,7 @@
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
         /* Start timer if not already running */
         if( ssl->time_limit == 0 )
-            ssl_set_timer( ssl, ssl->read_timeout );
+            ssl_set_timer( ssl, ssl->conf->read_timeout );
 #endif
 
         if( ! record_read )
@@ -6171,7 +6078,7 @@
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
 
 #if defined(MBEDTLS_SSL_CLI_C)
-            if( ssl->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+            if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
                 ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
                   ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
             {
@@ -6179,29 +6086,29 @@
 
                 /* With DTLS, drop the packet (probably from last handshake) */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-                if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-                    return( MBEDTLS_ERR_NET_WANT_READ );
+                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+                    return( MBEDTLS_ERR_SSL_WANT_READ );
 #endif
                 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
             }
 
-            if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER &&
+            if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
                 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
 
                 /* With DTLS, drop the packet (probably from last handshake) */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-                if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-                    return( MBEDTLS_ERR_NET_WANT_READ );
+                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+                    return( MBEDTLS_ERR_SSL_WANT_READ );
 #endif
                 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
             }
 #endif
 
-            if( ssl->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
+            if( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
                 ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
-                  ssl->allow_legacy_renegotiation ==
+                  ssl->conf->allow_legacy_renegotiation ==
                                                 MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
@@ -6240,8 +6147,8 @@
             {
                 /* DTLS clients need to know renego is server-initiated */
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-                if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
-                    ssl->endpoint == MBEDTLS_SSL_IS_CLIENT )
+                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+                    ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
                 {
                     ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
                 }
@@ -6261,14 +6168,14 @@
             /* If a non-handshake record was read during renego, fallthrough,
              * else tell the user they should call mbedtls_ssl_read() again */
             if( ! record_read )
-                return( MBEDTLS_ERR_NET_WANT_READ );
+                return( MBEDTLS_ERR_SSL_WANT_READ );
         }
         else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
         {
 
-            if( ssl->renego_max_records >= 0 )
+            if( ssl->conf->renego_max_records >= 0 )
             {
-                if( ++ssl->renego_records_seen > ssl->renego_max_records )
+                if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
                 {
                     MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
                                         "but not honored by client" ) );
@@ -6282,7 +6189,7 @@
         if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
         {
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
-            return( MBEDTLS_ERR_NET_WANT_READ );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
         }
 
         if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
@@ -6303,7 +6210,7 @@
          * Do it now, after setting in_offt, to avoid taking this branch
          * again if ssl_write_hello_request() returns WANT_WRITE */
 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
-        if( ssl->endpoint == MBEDTLS_SSL_IS_SERVER &&
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
             ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
         {
             if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
@@ -6350,7 +6257,7 @@
     /*
      * Assume mfl_code is correct since it was checked when set
      */
-    max_len = mfl_code_to_length[ssl->mfl_code];
+    max_len = mfl_code_to_length[ssl->conf->mfl_code];
 
     /*
      * Check if a smaller max length was negotiated
@@ -6364,7 +6271,7 @@
     if( len > max_len )
     {
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-        if( ssl->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
                                 "maximum fragment length: %d > %d",
@@ -6414,7 +6321,8 @@
 {
     int ret;
 
-    if( ssl->split_done == MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
+    if( ssl->conf->cbc_record_splitting ==
+            MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
         len <= 1 ||
         ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
         mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
@@ -6553,6 +6461,14 @@
     mbedtls_free( (void *) handshake->curves );
 #endif
 
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( handshake->psk != NULL )
+    {
+        mbedtls_zeroize( handshake->psk, handshake->psk_len );
+        mbedtls_free( handshake->psk );
+    }
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
     defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     /*
@@ -6631,11 +6547,6 @@
     }
 #endif
 
-#if defined(MBEDTLS_DHM_C)
-    mbedtls_mpi_free( &ssl->dhm_P );
-    mbedtls_mpi_free( &ssl->dhm_G );
-#endif
-
     if( ssl->transform )
     {
         mbedtls_ssl_transform_free( ssl->transform );
@@ -6660,38 +6571,21 @@
     }
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    if( ssl->ticket_keys )
+    if( ssl->conf->ticket_keys )
     {
-        ssl_ticket_keys_free( ssl->ticket_keys );
-        mbedtls_free( ssl->ticket_keys );
+        ssl_ticket_keys_free( ssl->conf->ticket_keys );
+        mbedtls_free( ssl->conf->ticket_keys );
     }
 #endif
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     if( ssl->hostname != NULL )
     {
-        mbedtls_zeroize( ssl->hostname, ssl->hostname_len );
+        mbedtls_zeroize( ssl->hostname, strlen( ssl->hostname ) );
         mbedtls_free( ssl->hostname );
-        ssl->hostname_len = 0;
     }
 #endif
 
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    if( ssl->psk != NULL )
-    {
-        mbedtls_zeroize( ssl->psk, ssl->psk_len );
-        mbedtls_zeroize( ssl->psk_identity, ssl->psk_identity_len );
-        mbedtls_free( ssl->psk );
-        mbedtls_free( ssl->psk_identity );
-        ssl->psk_len = 0;
-        ssl->psk_identity_len = 0;
-    }
-#endif
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-    ssl_key_cert_free( ssl->key_cert );
-#endif
-
 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
     if( mbedtls_ssl_hw_record_finish != NULL )
     {
@@ -6710,6 +6604,142 @@
     mbedtls_zeroize( ssl, sizeof( mbedtls_ssl_context ) );
 }
 
+/*
+ * Initialze mbedtls_ssl_config
+ */
+void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
+{
+    memset( conf, 0, sizeof( mbedtls_ssl_config ) );
+}
+
+/*
+ * Load default in mbetls_ssl_config
+ */
+int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
+                                 int endpoint, int transport )
+{
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
+    int ret;
+#endif
+
+    conf->endpoint  = endpoint;
+    conf->transport = transport;
+
+    conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
+    conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS 1.0 */
+    conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
+    conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        /* DTLS starts with TLS 1.1 */
+        conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+        conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
+#endif
+    }
+#endif
+
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
+                           mbedtls_ssl_list_ciphersuites();
+
+    conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED;
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+    conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    conf->ticket_lifetime = MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME;
+#endif
+
+#if defined(MBEDTLS_SSL_SET_CURVES)
+    conf->curve_list = mbedtls_ecp_grp_id_list( );
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+    conf->f_cookie_write = ssl_cookie_write_dummy;
+    conf->f_cookie_check = ssl_cookie_check_dummy;
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
+    conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
+#endif
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT;
+    memset( conf->renego_period, 0xFF, 7 );
+    conf->renego_period[7] = 0x00;
+#endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
+    if( endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        if( ( ret = mbedtls_ssl_conf_dh_param( conf,
+                        MBEDTLS_DHM_RFC5114_MODP_2048_P,
+                        MBEDTLS_DHM_RFC5114_MODP_2048_G ) ) != 0 )
+        {
+            return( ret );
+        }
+    }
+#endif
+
+    return( 0 );
+}
+
+/*
+ * Free mbedtls_ssl_config
+ */
+void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
+{
+#if defined(MBEDTLS_DHM_C)
+    mbedtls_mpi_free( &conf->dhm_P );
+    mbedtls_mpi_free( &conf->dhm_G );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( conf->psk != NULL )
+    {
+        mbedtls_zeroize( conf->psk, conf->psk_len );
+        mbedtls_zeroize( conf->psk_identity, conf->psk_identity_len );
+        mbedtls_free( conf->psk );
+        mbedtls_free( conf->psk_identity );
+        conf->psk_len = 0;
+        conf->psk_identity_len = 0;
+    }
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    ssl_key_cert_free( conf->key_cert );
+#endif
+
+    mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) );
+}
+
 #if defined(MBEDTLS_PK_C)
 /*
  * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
@@ -6786,7 +6816,7 @@
 {
     const mbedtls_ecp_group_id *gid;
 
-    for( gid = ssl->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
+    for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
         if( *gid == grp_id )
             return( 1 );
 
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index 4f82283..3886bbd 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -92,6 +92,7 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_x509_crt cacert;
 
     ((void) argc);
@@ -105,6 +106,7 @@
      * 0. Initialize the RNG and the session data
      */
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     mbedtls_x509_crt_init( &cacert );
     mbedtls_ctr_drbg_init( &ctr_drbg );
 
@@ -123,7 +125,7 @@
     mbedtls_printf( " ok\n" );
 
     /*
-     * 0. Initialize certificates
+     * 0. Load certificates
      */
     mbedtls_printf( "  . Loading the CA root certificate ..." );
     fflush( stdout );
@@ -160,30 +162,39 @@
     mbedtls_printf( "  . Setting up the DTLS structure..." );
     fflush( stdout );
 
-    if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                   MBEDTLS_SSL_IS_CLIENT,
+                   MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
+        goto exit;
+    }
+
+    /* OPTIONAL is usually a bad choice for security, but makes interop easier
+     * in this simplified example, in which the ca chain is hardcoded.
+     * Production code should set a proper ca chain and use REQUIRED. */
+    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
+    mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
+
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
         goto exit;
     }
 
+    if( ( ret = mbedtls_ssl_set_hostname( &ssl, SERVER_NAME ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
+        goto exit;
+    }
+
+    mbedtls_ssl_set_bio( &ssl, &server_fd,
+                         mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout );
+
     mbedtls_printf( " ok\n" );
 
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_CLIENT );
-    mbedtls_ssl_set_transport( &ssl, MBEDTLS_SSL_TRANSPORT_DATAGRAM );
-
-    /* OPTIONAL is usually a bad choice for security, but makes interop easier
-     * in this simplified example, in which the ca chain is hardcoded.
-     * Production code should set a proper ca chain and use REQUIRED. */
-    mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_OPTIONAL );
-    mbedtls_ssl_set_ca_chain( &ssl, &cacert, NULL, SERVER_NAME );
-
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
-
-    mbedtls_ssl_set_bio_timeout( &ssl, &server_fd,
-                         mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout,
-                         READ_TIMEOUT_MS );
-
     /*
      * 4. Handshake
      */
@@ -191,8 +202,8 @@
     fflush( stdout );
 
     do ret = mbedtls_ssl_handshake( &ssl );
-    while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-           ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+           ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     if( ret != 0 )
     {
@@ -241,8 +252,8 @@
     len = sizeof( MESSAGE ) - 1;
 
     do ret = mbedtls_ssl_write( &ssl, (unsigned char *) MESSAGE, len );
-    while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-           ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+           ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     if( ret < 0 )
     {
@@ -263,14 +274,14 @@
     memset( buf, 0, sizeof( buf ) );
 
     do ret = mbedtls_ssl_read( &ssl, buf, len );
-    while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-           ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+           ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     if( ret <= 0 )
     {
         switch( ret )
         {
-            case MBEDTLS_ERR_NET_TIMEOUT:
+            case MBEDTLS_ERR_SSL_TIMEOUT:
                 mbedtls_printf( " timeout\n\n" );
                 if( retry_left-- > 0 )
                     goto send_request;
@@ -298,7 +309,7 @@
 
     /* No error checking, the connection might be closed already */
     do ret = mbedtls_ssl_close_notify( &ssl );
-    while( ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
     ret = 0;
 
     mbedtls_printf( " done\n" );
@@ -322,6 +333,7 @@
 
     mbedtls_x509_crt_free( &cacert );
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index a4b86f7..40416be 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -97,6 +97,7 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_x509_crt srvcert;
     mbedtls_pk_context pkey;
 #if defined(MBEDTLS_SSL_CACHE_C)
@@ -104,6 +105,7 @@
 #endif
 
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     mbedtls_ssl_cookie_init( &cookie_ctx );
 #if defined(MBEDTLS_SSL_CACHE_C)
     mbedtls_ssl_cache_init( &cache );
@@ -190,28 +192,27 @@
     printf( "  . Setting up the DTLS data..." );
     fflush( stdout );
 
-    if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                    MBEDTLS_SSL_IS_SERVER,
+                    MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ) != 0 )
     {
-        printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
         goto exit;
     }
 
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_SERVER );
-    mbedtls_ssl_set_transport( &ssl, MBEDTLS_SSL_TRANSPORT_DATAGRAM );
-    mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_NONE );
-
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
 #if defined(MBEDTLS_SSL_CACHE_C)
-    mbedtls_ssl_set_session_cache( &ssl, mbedtls_ssl_cache_get, &cache,
-                                 mbedtls_ssl_cache_set, &cache );
+    mbedtls_ssl_conf_session_cache( &conf, &cache,
+                                   mbedtls_ssl_cache_get,
+                                   mbedtls_ssl_cache_set );
 #endif
 
-    mbedtls_ssl_set_ca_chain( &ssl, srvcert.next, NULL, NULL );
-    if( ( ret = mbedtls_ssl_set_own_cert( &ssl, &srvcert, &pkey ) ) != 0 )
+    mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
+   if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
     {
-        printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
+        printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
         goto exit;
     }
 
@@ -222,9 +223,15 @@
         goto exit;
     }
 
-    mbedtls_ssl_set_dtls_cookies( &ssl, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
+    mbedtls_ssl_conf_dtls_cookies( &conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
                                &cookie_ctx );
 
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        goto exit;
+    }
+
     printf( " ok\n" );
 
 reset:
@@ -268,13 +275,12 @@
                                            sizeof( client_ip ) ) ) != 0 )
     {
         printf( " failed\n  ! "
-                "ssl_set_client_tranport_id() returned -0x%x\n\n", -ret );
+                "ssl_set_client_transport_id() returned -0x%x\n\n", -ret );
         goto exit;
     }
 
-    mbedtls_ssl_set_bio_timeout( &ssl, &client_fd,
-                         mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout,
-                         READ_TIMEOUT_MS );
+    mbedtls_ssl_set_bio( &ssl, &client_fd,
+                         mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout );
 
     printf( " ok\n" );
 
@@ -285,8 +291,8 @@
     fflush( stdout );
 
     do ret = mbedtls_ssl_handshake( &ssl );
-    while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-           ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+           ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
     {
@@ -312,14 +318,14 @@
     memset( buf, 0, sizeof( buf ) );
 
     do ret = mbedtls_ssl_read( &ssl, buf, len );
-    while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-           ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+           ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     if( ret <= 0 )
     {
         switch( ret )
         {
-            case MBEDTLS_ERR_NET_TIMEOUT:
+            case MBEDTLS_ERR_SSL_TIMEOUT:
                 printf( " timeout\n\n" );
                 goto reset;
 
@@ -344,8 +350,8 @@
     fflush( stdout );
 
     do ret = mbedtls_ssl_write( &ssl, buf, len );
-    while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-           ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+           ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     if( ret < 0 )
     {
@@ -364,7 +370,7 @@
 
     /* No error checking, the connection might be closed already */
     do ret = mbedtls_ssl_close_notify( &ssl );
-    while( ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
     ret = 0;
 
     printf( " done\n" );
@@ -391,6 +397,7 @@
     mbedtls_x509_crt_free( &srvcert );
     mbedtls_pk_free( &pkey );
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
     mbedtls_ssl_cookie_free( &cookie_ctx );
 #if defined(MBEDTLS_SSL_CACHE_C)
     mbedtls_ssl_cache_free( &cache );
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index cab6e8d..20ce2b7 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -147,7 +147,9 @@
 {
     exit_ok = 0,
     ctr_drbg_seed_failed,
+    ssl_config_defaults_failed,
     ssl_setup_failed,
+    hostname_failed,
     socket_failed,
     connect_failed,
     x509_crt_parse_failed,
@@ -167,12 +169,14 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_ctr_drbg_init( &ctr_drbg );
 
     /*
      * 0. Initialize and setup stuff
      */
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_init( &ca );
 #endif
@@ -185,18 +189,18 @@
         goto exit;
     }
 
-    if( mbedtls_ssl_setup( &ssl ) != 0 )
+    if( mbedtls_ssl_config_defaults( &conf,
+                MBEDTLS_SSL_IS_CLIENT,
+                MBEDTLS_SSL_TRANSPORT_STREAM) != 0 )
     {
-        ret = ssl_setup_failed;
+        ret = ssl_config_defaults_failed;
         goto exit;
     }
 
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_CLIENT );
-
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    mbedtls_ssl_set_psk( &ssl, psk, sizeof( psk ),
+    mbedtls_ssl_conf_psk( &conf, psk, sizeof( psk ),
                 (const unsigned char *) psk_id, sizeof( psk_id ) - 1 );
 #endif
 
@@ -207,10 +211,22 @@
         goto exit;
     }
 
-    mbedtls_ssl_set_ca_chain( &ssl, &ca, NULL, HOSTNAME );
-    mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_REQUIRED );
+    mbedtls_ssl_conf_ca_chain( &conf, &ca, NULL );
+    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
 #endif
 
+    if( mbedtls_ssl_setup( &ssl, &conf ) != 0 )
+    {
+        ret = ssl_setup_failed;
+        goto exit;
+    }
+
+    if( mbedtls_ssl_set_hostname( &ssl, HOSTNAME ) != 0 )
+    {
+        ret = hostname_failed;
+        goto exit;
+    }
+
     /*
      * 1. Start the connection
      */
@@ -235,7 +251,7 @@
         goto exit;
     }
 
-    mbedtls_ssl_set_bio_timeout( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL, 0 );
+    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
     if( mbedtls_ssl_handshake( &ssl ) != 0 )
     {
@@ -260,6 +276,7 @@
         mbedtls_net_close( server_fd );
 
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index 37c24a2..ec1edd8 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -83,6 +83,7 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_x509_crt cacert;
 
 #if defined(MBEDTLS_DEBUG_C)
@@ -93,6 +94,7 @@
      * 0. Initialize the RNG and the session data
      */
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     mbedtls_x509_crt_init( &cacert );
     mbedtls_ctr_drbg_init( &ctr_drbg );
 
@@ -148,23 +150,36 @@
     mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
     fflush( stdout );
 
-    if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                    MBEDTLS_SSL_IS_CLIENT,
+                    MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
         goto exit;
     }
 
     mbedtls_printf( " ok\n" );
 
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_CLIENT );
     /* OPTIONAL is not optimal for security,
      * but makes interop easier in this simplified example */
-    mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_OPTIONAL );
-    mbedtls_ssl_set_ca_chain( &ssl, &cacert, NULL, "mbed TLS Server 1" );
+    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
+    mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
-    mbedtls_ssl_set_bio_timeout( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL, 0 );
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        goto exit;
+    }
+
+    if( ( ret = mbedtls_ssl_set_hostname( &ssl, "mbed TLS Server 1" ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
+        goto exit;
+    }
+
+    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
     /*
      * 4. Handshake
@@ -174,7 +189,7 @@
 
     while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
             goto exit;
@@ -212,7 +227,7 @@
 
     while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
             goto exit;
@@ -234,7 +249,7 @@
         memset( buf, 0, sizeof( buf ) );
         ret = mbedtls_ssl_read( &ssl, buf, len );
 
-        if( ret == MBEDTLS_ERR_NET_WANT_READ || ret == MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
             continue;
 
         if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
@@ -275,6 +290,7 @@
 
     mbedtls_x509_crt_free( &cacert );
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index de6ff65..79cdb28 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -334,11 +334,11 @@
     if( first_try )
     {
         first_try = 0;
-        return( MBEDTLS_ERR_NET_WANT_READ );
+        return( MBEDTLS_ERR_SSL_WANT_READ );
     }
 
     ret = mbedtls_net_recv( ctx, buf, len );
-    if( ret != MBEDTLS_ERR_NET_WANT_READ )
+    if( ret != MBEDTLS_ERR_SSL_WANT_READ )
         first_try = 1; /* Next call will be a new operation */
     return( ret );
 }
@@ -351,11 +351,11 @@
     if( first_try )
     {
         first_try = 0;
-        return( MBEDTLS_ERR_NET_WANT_WRITE );
+        return( MBEDTLS_ERR_SSL_WANT_WRITE );
     }
 
     ret = mbedtls_net_send( ctx, buf, len );
-    if( ret != MBEDTLS_ERR_NET_WANT_WRITE )
+    if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         first_try = 1; /* Next call will be a new operation */
     return( ret );
 }
@@ -401,6 +401,7 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_ssl_session saved_session;
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt cacert;
@@ -415,6 +416,7 @@
      */
     server_fd = 0;
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) );
     mbedtls_ctr_drbg_init( &ctr_drbg );
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -1047,134 +1049,106 @@
     mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
     fflush( stdout );
 
-    if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                    MBEDTLS_SSL_IS_CLIENT,
+                    opt.transport ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret );
         goto exit;
     }
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     if( opt.debug_level > 0 )
-        mbedtls_ssl_set_verify( &ssl, my_verify, NULL );
+        mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
 #endif
 
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_CLIENT );
     if( opt.auth_mode != DFL_AUTH_MODE )
-        mbedtls_ssl_set_authmode( &ssl, opt.auth_mode );
+        mbedtls_ssl_conf_authmode( &conf, opt.auth_mode );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ( ret = mbedtls_ssl_set_transport( &ssl, opt.transport ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! selected transport is not available\n" );
-        goto exit;
-    }
-
     if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
-        mbedtls_ssl_set_handshake_timeout( &ssl, opt.hs_to_min, opt.hs_to_max );
+        mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-    if( ( ret = mbedtls_ssl_set_max_frag_len( &ssl, opt.mfl_code ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_max_frag_len returned %d\n\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret );
         goto exit;
     }
 #endif
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
     if( opt.trunc_hmac != DFL_TRUNC_HMAC )
-        mbedtls_ssl_set_truncated_hmac( &ssl, opt.trunc_hmac );
+        mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
 #endif
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
     if( opt.extended_ms != DFL_EXTENDED_MS )
-        mbedtls_ssl_set_extended_master_secret( &ssl, opt.extended_ms );
+        mbedtls_ssl_conf_extended_master_secret( &conf, opt.extended_ms );
 #endif
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
     if( opt.etm != DFL_ETM )
-        mbedtls_ssl_set_encrypt_then_mac( &ssl, opt.etm );
+        mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
 #endif
 
 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
     if( opt.recsplit != DFL_RECSPLIT )
-        mbedtls_ssl_set_cbc_record_splitting( &ssl, opt.recsplit
+        mbedtls_ssl_conf_cbc_record_splitting( &conf, opt.recsplit
                                     ? MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED
                                     : MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED );
 #endif
 
 #if defined(MBEDTLS_SSL_ALPN)
     if( opt.alpn_string != NULL )
-        if( ( ret = mbedtls_ssl_set_alpn_protocols( &ssl, alpn_list ) ) != 0 )
+        if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_alpn_protocols returned %d\n\n", ret );
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_alpn_protocols returned %d\n\n", ret );
             goto exit;
         }
 #endif
 
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
-    if( opt.nbio == 2 )
-        mbedtls_ssl_set_bio_timeout( &ssl, &server_fd, my_send, my_recv, NULL,
-                             opt.read_timeout );
-    else
-        mbedtls_ssl_set_bio_timeout( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv,
-#if defined(MBEDTLS_HAVE_TIME)
-                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL,
-#else
-                             NULL,
-#endif
-                             opt.read_timeout );
+    mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    if( ( ret = mbedtls_ssl_set_session_tickets( &ssl, opt.tickets ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_session_tickets( &conf, opt.tickets ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_session_tickets returned %d\n\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_session_tickets returned %d\n\n", ret );
         goto exit;
     }
 #endif
 
     if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
-        mbedtls_ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );
+        mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
 
     if( opt.arc4 != DFL_ARC4 )
-        mbedtls_ssl_set_arc4_support( &ssl, opt.arc4 );
+        mbedtls_ssl_conf_arc4_support( &conf, opt.arc4 );
 
     if( opt.allow_legacy != DFL_ALLOW_LEGACY )
-        mbedtls_ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
+        mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy );
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-    mbedtls_ssl_set_renegotiation( &ssl, opt.renegotiation );
+    mbedtls_ssl_conf_renegotiation( &conf, opt.renegotiation );
 #endif
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     if( strcmp( opt.ca_path, "none" ) != 0 &&
         strcmp( opt.ca_file, "none" ) != 0 )
     {
-        mbedtls_ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
+        mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
     }
     if( strcmp( opt.crt_file, "none" ) != 0 &&
         strcmp( opt.key_file, "none" ) != 0 )
     {
-        if( ( ret = mbedtls_ssl_set_own_cert( &ssl, &clicert, &pkey ) ) != 0 )
+        if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
             goto exit;
         }
     }
-#endif
-
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-    if( ( ret = mbedtls_ssl_set_psk( &ssl, psk, psk_len,
-                             (const unsigned char *) opt.psk_identity,
-                             strlen( opt.psk_identity ) ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_psk returned %d\n\n", ret );
-        goto exit;
-    }
-#endif
-
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
@@ -1182,31 +1156,52 @@
     }
 #endif
 
-    if( opt.min_version != DFL_MIN_VERSION )
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( ( ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len,
+                             (const unsigned char *) opt.psk_identity,
+                             strlen( opt.psk_identity ) ) ) != 0 )
     {
-        ret = mbedtls_ssl_set_min_version( &ssl, MBEDTLS_SSL_MAJOR_VERSION_3, opt.min_version );
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  ! selected min_version is not available\n" );
-            goto exit;
-        }
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_psk returned %d\n\n", ret );
+        goto exit;
     }
+#endif
+
+    if( opt.min_version != DFL_MIN_VERSION )
+        mbedtls_ssl_conf_min_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.min_version );
 
     if( opt.max_version != DFL_MAX_VERSION )
-    {
-        ret = mbedtls_ssl_set_max_version( &ssl, MBEDTLS_SSL_MAJOR_VERSION_3, opt.max_version );
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  ! selected max_version is not available\n" );
-            goto exit;
-        }
-    }
+        mbedtls_ssl_conf_max_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.max_version );
 
 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
     if( opt.fallback != DFL_FALLBACK )
-        mbedtls_ssl_set_fallback( &ssl, opt.fallback );
+        mbedtls_ssl_conf_fallback( &conf, opt.fallback );
 #endif
 
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
+        goto exit;
+    }
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
+        goto exit;
+    }
+#endif
+
+    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,
+#if defined(MBEDTLS_HAVE_TIME)
+                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL
+#else
+                             NULL
+#endif
+                );
+
     mbedtls_printf( " ok\n" );
 
     /*
@@ -1217,7 +1212,7 @@
 
     while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n", -ret );
             if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
@@ -1303,8 +1298,8 @@
         fflush( stdout );
         while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
         {
-            if( ret != MBEDTLS_ERR_NET_WANT_READ &&
-                ret != MBEDTLS_ERR_NET_WANT_WRITE )
+            if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
+                ret != MBEDTLS_ERR_SSL_WANT_WRITE )
             {
                 mbedtls_printf( " failed\n  ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
                 goto exit;
@@ -1355,8 +1350,8 @@
             while( ( ret = mbedtls_ssl_write( &ssl, buf + written, len - written ) )
                            <= 0 )
             {
-                if( ret != MBEDTLS_ERR_NET_WANT_READ &&
-                    ret != MBEDTLS_ERR_NET_WANT_WRITE )
+                if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
+                    ret != MBEDTLS_ERR_SSL_WANT_WRITE )
                 {
                     mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned -0x%x\n\n", -ret );
                     goto exit;
@@ -1367,8 +1362,8 @@
     else /* Not stream, so datagram */
     {
         do ret = mbedtls_ssl_write( &ssl, buf, len );
-        while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-               ret == MBEDTLS_ERR_NET_WANT_WRITE );
+        while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+               ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
         if( ret < 0 )
         {
@@ -1400,8 +1395,8 @@
             memset( buf, 0, sizeof( buf ) );
             ret = mbedtls_ssl_read( &ssl, buf, len );
 
-            if( ret == MBEDTLS_ERR_NET_WANT_READ ||
-                ret == MBEDTLS_ERR_NET_WANT_WRITE )
+            if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+                ret == MBEDTLS_ERR_SSL_WANT_WRITE )
                 continue;
 
             if( ret <= 0 )
@@ -1445,14 +1440,14 @@
         memset( buf, 0, sizeof( buf ) );
 
         do ret = mbedtls_ssl_read( &ssl, buf, len );
-        while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-               ret == MBEDTLS_ERR_NET_WANT_WRITE );
+        while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+               ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
         if( ret <= 0 )
         {
             switch( ret )
             {
-                case MBEDTLS_ERR_NET_TIMEOUT:
+                case MBEDTLS_ERR_SSL_TIMEOUT:
                     mbedtls_printf( " timeout\n" );
                     if( retry_left-- > 0 )
                         goto send_request;
@@ -1489,7 +1484,7 @@
 
     /* No error checking, the connection might be closed already */
     do ret = mbedtls_ssl_close_notify( &ssl );
-    while( ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
     ret = 0;
 
     mbedtls_printf( " done\n" );
@@ -1520,7 +1515,7 @@
 
         if( ( ret = mbedtls_ssl_set_session( &ssl, &saved_session ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_session returned %d\n\n", ret );
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_session returned %d\n\n", ret );
             goto exit;
         }
 
@@ -1545,8 +1540,8 @@
 
         while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
         {
-            if( ret != MBEDTLS_ERR_NET_WANT_READ &&
-                ret != MBEDTLS_ERR_NET_WANT_WRITE )
+            if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
+                ret != MBEDTLS_ERR_SSL_WANT_WRITE )
             {
                 mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
                 goto exit;
@@ -1581,6 +1576,7 @@
 #endif
     mbedtls_ssl_session_free( &saved_session );
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index a0880e8..1df814b 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -103,11 +103,12 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_x509_crt srvcert;
     mbedtls_pk_context pkey;
 
-    memset( &ssl, 0, sizeof(mbedtls_ssl_context) );
-
+    mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     mbedtls_entropy_init( &entropy );
     mbedtls_pk_init( &pkey );
     mbedtls_x509_crt_init( &srvcert );
@@ -169,6 +170,32 @@
     mbedtls_printf( " ok\n" );
 
     /*
+     * 1b. Prepare SSL configuration
+     */
+    mbedtls_printf( "  . Configuring SSL..." );
+    fflush( stdout );
+
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                    MBEDTLS_SSL_IS_SERVER,
+                    MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
+        goto exit;
+    }
+
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
+
+    mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
+    if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
+        goto exit;
+    }
+
+    mbedtls_printf( " ok\n" );
+
+    /*
      * 2. Setup the listening TCP socket
      */
     mbedtls_printf( "  . Bind on https://localhost:4433/ ..." );
@@ -248,28 +275,16 @@
             goto exit;
         }
 
-        if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+        if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
             goto exit;
         }
 
+        mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+
         mbedtls_printf( " ok\n" );
 
-        mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_SERVER );
-        mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_NONE );
-
-        mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-        mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
-        mbedtls_ssl_set_bio_timeout( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL, 0 );
-
-        mbedtls_ssl_set_ca_chain( &ssl, srvcert.next, NULL, NULL );
-        if( ( ret = mbedtls_ssl_set_own_cert( &ssl, &srvcert, &pkey ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
-            goto exit;
-        }
-
         /*
          * 5. Handshake
          */
@@ -278,7 +293,7 @@
 
         while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
         {
-            if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+            if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
             {
                 mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned %d\n\n", ret );
                 goto exit;
@@ -299,7 +314,7 @@
             memset( buf, 0, sizeof( buf ) );
             ret = mbedtls_ssl_read( &ssl, buf, len );
 
-            if( ret == MBEDTLS_ERR_NET_WANT_READ || ret == MBEDTLS_ERR_NET_WANT_WRITE )
+            if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
                 continue;
 
             if( ret <= 0 )
@@ -349,7 +364,7 @@
                     goto exit;
                 }
 
-                if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+                if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
                 {
                     mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
                     goto exit;
@@ -373,6 +388,7 @@
     mbedtls_x509_crt_free( &srvcert );
     mbedtls_pk_free( &pkey );
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 8abe740..a555d40 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -177,7 +177,7 @@
 
     while( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
 #if defined(MBEDTLS_ERROR_C)
             mbedtls_strerror( ret, (char *) buf, 1024 );
@@ -224,7 +224,7 @@
     mbedtls_printf("\n%s", buf);
     while( len && ( ret = mbedtls_ssl_write( ssl, buf, len ) ) <= 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
             return -1;
@@ -244,7 +244,7 @@
     mbedtls_printf("\n%s", buf);
     while( len && ( ret = mbedtls_ssl_write( ssl, buf, len ) ) <= 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
             return -1;
@@ -257,7 +257,7 @@
         memset( data, 0, sizeof( data ) );
         ret = mbedtls_ssl_read( ssl, data, len );
 
-        if( ret == MBEDTLS_ERR_NET_WANT_READ || ret == MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
             continue;
 
         if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
@@ -355,6 +355,7 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_x509_crt cacert;
     mbedtls_x509_crt clicert;
     mbedtls_pk_context pkey;
@@ -368,6 +369,7 @@
      */
     server_fd = 0;
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     memset( &buf, 0, sizeof( buf ) );
     mbedtls_x509_crt_init( &cacert );
     mbedtls_x509_crt_init( &clicert );
@@ -582,34 +584,43 @@
     mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
     fflush( stdout );
 
-    if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                    MBEDTLS_SSL_IS_CLIENT,
+                    MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
+        goto exit;
+    }
+
+    /* OPTIONAL is not optimal for security,
+     * but makes interop easier in this simplified example */
+    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
+
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
+
+    if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
+        mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
+
+    mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
+    if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
+        goto exit;
+    }
+
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
         goto exit;
     }
 
-    mbedtls_printf( " ok\n" );
-
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_CLIENT );
-    /* OPTIONAL is not optimal for security,
-     * but makes interop easier in this simplified example */
-    mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_OPTIONAL );
-
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
-    mbedtls_ssl_set_bio_timeout( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL, 0 );
-
-    if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
-        mbedtls_ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );
-
-    mbedtls_ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
-    if( ( ret = mbedtls_ssl_set_own_cert( &ssl, &clicert, &pkey ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
-        goto exit;
-    }
-
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+#if defined(MBEDTLS_x509_CRT_PARSE_C)
     if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
@@ -617,6 +628,10 @@
     }
 #endif
 
+    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+
+    mbedtls_printf( " ok\n" );
+
     if( opt.mode == MODE_SSL_TLS )
     {
         if( do_handshake( &ssl ) != 0 )
@@ -821,6 +836,7 @@
     mbedtls_x509_crt_free( &cacert );
     mbedtls_pk_free( &pkey );
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index 3432e5e..7d710be 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -103,13 +103,7 @@
 typedef struct {
     int client_fd;
     int thread_complete;
-    mbedtls_entropy_context *entropy;
-#if defined(MBEDTLS_SSL_CACHE_C)
-    mbedtls_ssl_cache_context *cache;
-#endif
-    mbedtls_x509_crt *ca_chain;
-    mbedtls_x509_crt *server_cert;
-    mbedtls_pk_context *server_key;
+    const mbedtls_ssl_config *config;
 } thread_info_t;
 
 typedef struct {
@@ -126,93 +120,48 @@
     int ret, len;
     thread_info_t *thread_info = (thread_info_t *) data;
     int client_fd = thread_info->client_fd;
-    int thread_id = (int) pthread_self();
+    long int thread_id = (long int) pthread_self();
     unsigned char buf[1024];
-    char pers[50];
     mbedtls_ssl_context ssl;
-    mbedtls_ctr_drbg_context ctr_drbg;
 
     /* Make sure memory references are valid */
     mbedtls_ssl_init( &ssl );
-    mbedtls_ctr_drbg_init( &ctr_drbg );
 
-    mbedtls_snprintf( pers, sizeof(pers), "SSL Pthread Thread %d", thread_id );
-    mbedtls_printf( "  [ #%d ]  Client FD %d\n", thread_id, client_fd );
-    mbedtls_printf( "  [ #%d ]  Seeding the random number generator...\n", thread_id );
-
-    /* mbedtls_entropy_func() is thread-safe if MBEDTLS_THREADING_C is set
-     */
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, thread_info->entropy,
-                               (const unsigned char *) pers,
-                               strlen( pers ) ) ) != 0 )
-    {
-        mbedtls_printf( "  [ #%d ]  failed: mbedtls_ctr_drbg_seed returned -0x%04x\n",
-                thread_id, -ret );
-        goto thread_exit;
-    }
-
-    mbedtls_printf( "  [ #%d ]  ok\n", thread_id );
+    mbedtls_printf( "  [ #%ld ]  Client FD %d\n", thread_id, client_fd );
 
     /*
-     * 4. Setup stuff
+     * 4. Get the SSL context ready
      */
-    mbedtls_printf( "  [ #%d ]  Setting up the SSL data....\n", thread_id );
-
-    if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+    if( ( ret = mbedtls_ssl_setup( &ssl, thread_info->config ) ) != 0 )
     {
-        mbedtls_printf( "  [ #%d ]  failed: mbedtls_ssl_setup returned -0x%04x\n",
+        mbedtls_printf( "  [ #%ld ]  failed: mbedtls_ssl_setup returned -0x%04x\n",
                 thread_id, -ret );
         goto thread_exit;
     }
 
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_SERVER );
-    mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_NONE );
-
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_set_dbg( &ssl, my_mutexed_debug, stdout );
-
-    /* mbedtls_ssl_cache_get() and mbedtls_ssl_cache_set() are thread-safe if
-     * MBEDTLS_THREADING_C is set.
-     */
-#if defined(MBEDTLS_SSL_CACHE_C)
-    mbedtls_ssl_set_session_cache( &ssl, mbedtls_ssl_cache_get, thread_info->cache,
-                                 mbedtls_ssl_cache_set, thread_info->cache );
-#endif
-
-    mbedtls_ssl_set_ca_chain( &ssl, thread_info->ca_chain, NULL, NULL );
-    if( ( ret = mbedtls_ssl_set_own_cert( &ssl, thread_info->server_cert, thread_info->server_key ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
-        goto thread_exit;
-    }
-
-    mbedtls_printf( "  [ #%d ]  ok\n", thread_id );
-
-        mbedtls_ssl_set_bio_timeout( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL, 0 );
-
-    mbedtls_printf( "  [ #%d ]  ok\n", thread_id );
+    mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
     /*
      * 5. Handshake
      */
-    mbedtls_printf( "  [ #%d ]  Performing the SSL/TLS handshake\n", thread_id );
+    mbedtls_printf( "  [ #%ld ]  Performing the SSL/TLS handshake\n", thread_id );
 
     while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
-            mbedtls_printf( "  [ #%d ]  failed: mbedtls_ssl_handshake returned -0x%04x\n",
+            mbedtls_printf( "  [ #%ld ]  failed: mbedtls_ssl_handshake returned -0x%04x\n",
                     thread_id, -ret );
             goto thread_exit;
         }
     }
 
-    mbedtls_printf( "  [ #%d ]  ok\n", thread_id );
+    mbedtls_printf( "  [ #%ld ]  ok\n", thread_id );
 
     /*
      * 6. Read the HTTP Request
      */
-    mbedtls_printf( "  [ #%d ]  < Read from client\n", thread_id );
+    mbedtls_printf( "  [ #%ld ]  < Read from client\n", thread_id );
 
     do
     {
@@ -220,7 +169,7 @@
         memset( buf, 0, sizeof( buf ) );
         ret = mbedtls_ssl_read( &ssl, buf, len );
 
-        if( ret == MBEDTLS_ERR_NET_WANT_READ || ret == MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
             continue;
 
         if( ret <= 0 )
@@ -228,24 +177,24 @@
             switch( ret )
             {
                 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
-                    mbedtls_printf( "  [ #%d ]  connection was closed gracefully\n",
+                    mbedtls_printf( "  [ #%ld ]  connection was closed gracefully\n",
                             thread_id );
                     goto thread_exit;
 
                 case MBEDTLS_ERR_NET_CONN_RESET:
-                    mbedtls_printf( "  [ #%d ]  connection was reset by peer\n",
+                    mbedtls_printf( "  [ #%ld ]  connection was reset by peer\n",
                             thread_id );
                     goto thread_exit;
 
                 default:
-                    mbedtls_printf( "  [ #%d ]  mbedtls_ssl_read returned -0x%04x\n",
+                    mbedtls_printf( "  [ #%ld ]  mbedtls_ssl_read returned -0x%04x\n",
                             thread_id, -ret );
                     goto thread_exit;
             }
         }
 
         len = ret;
-        mbedtls_printf( "  [ #%d ]  %d bytes read\n=====\n%s\n=====\n",
+        mbedtls_printf( "  [ #%ld ]  %d bytes read\n=====\n%s\n=====\n",
                 thread_id, len, (char *) buf );
 
         if( ret > 0 )
@@ -256,7 +205,7 @@
     /*
      * 7. Write the 200 Response
      */
-    mbedtls_printf( "  [ #%d ]  > Write to client:\n", thread_id );
+    mbedtls_printf( "  [ #%ld ]  > Write to client:\n", thread_id );
 
     len = sprintf( (char *) buf, HTTP_RESPONSE,
                    mbedtls_ssl_get_ciphersuite( &ssl ) );
@@ -265,31 +214,31 @@
     {
         if( ret == MBEDTLS_ERR_NET_CONN_RESET )
         {
-            mbedtls_printf( "  [ #%d ]  failed: peer closed the connection\n",
+            mbedtls_printf( "  [ #%ld ]  failed: peer closed the connection\n",
                     thread_id );
             goto thread_exit;
         }
 
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
-            mbedtls_printf( "  [ #%d ]  failed: mbedtls_ssl_write returned -0x%04x\n",
+            mbedtls_printf( "  [ #%ld ]  failed: mbedtls_ssl_write returned -0x%04x\n",
                     thread_id, ret );
             goto thread_exit;
         }
     }
 
     len = ret;
-    mbedtls_printf( "  [ #%d ]  %d bytes written\n=====\n%s\n=====\n",
+    mbedtls_printf( "  [ #%ld ]  %d bytes written\n=====\n%s\n=====\n",
             thread_id, len, (char *) buf );
 
-    mbedtls_printf( "  [ #%d ]  . Closing the connection...", thread_id );
+    mbedtls_printf( "  [ #%ld ]  . Closing the connection...", thread_id );
 
     while( ( ret = mbedtls_ssl_close_notify( &ssl ) ) < 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ &&
-            ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
+            ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
-            mbedtls_printf( "  [ #%d ]  failed: mbedtls_ssl_close_notify returned -0x%04x\n",
+            mbedtls_printf( "  [ #%ld ]  failed: mbedtls_ssl_close_notify returned -0x%04x\n",
                     thread_id, ret );
             goto thread_exit;
         }
@@ -306,13 +255,12 @@
     {
         char error_buf[100];
         mbedtls_strerror( ret, error_buf, 100 );
-        mbedtls_printf("  [ #%d ]  Last error was: -0x%04x - %s\n\n",
+        mbedtls_printf("  [ #%ld ]  Last error was: -0x%04x - %s\n\n",
                thread_id, -ret, error_buf );
     }
 #endif
 
     mbedtls_net_close( client_fd );
-    mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_ssl_free( &ssl );
 
     thread_info->thread_complete = 1;
@@ -364,9 +312,13 @@
     int ret;
     int listen_fd;
     int client_fd = -1;
+    const char pers[] = "ssl_pthread_server";
 
     mbedtls_entropy_context entropy;
+    mbedtls_ctr_drbg_context ctr_drbg;
+    mbedtls_ssl_config conf;
     mbedtls_x509_crt srvcert;
+    mbedtls_x509_crt cachain;
     mbedtls_pk_context pkey;
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     unsigned char alloc_buf[100000];
@@ -381,18 +333,23 @@
 
 #if defined(MBEDTLS_SSL_CACHE_C)
     mbedtls_ssl_cache_init( &cache );
-    base_info.cache = &cache;
 #endif
 
+    mbedtls_x509_crt_init( &srvcert );
+    mbedtls_x509_crt_init( &cachain );
+
+    mbedtls_ssl_config_init( &conf );
+    mbedtls_ctr_drbg_init( &ctr_drbg );
     memset( threads, 0, sizeof(threads) );
 
     mbedtls_mutex_init( &debug_mutex );
 
+    base_info.config = &conf;
+
     /*
      * We use only a single entropy source that is used in all the threads.
      */
     mbedtls_entropy_init( &entropy );
-    base_info.entropy = &entropy;
 
     /*
      * 1. Load the certificates and private RSA key
@@ -400,8 +357,6 @@
     mbedtls_printf( "\n  . Loading the server cert. and key..." );
     fflush( stdout );
 
-    mbedtls_x509_crt_init( &srvcert );
-
     /*
      * This demonstration program uses embedded test certificates.
      * Instead, you may want to use mbedtls_x509_crt_parse_file() to read the
@@ -415,7 +370,7 @@
         goto exit;
     }
 
-    ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_cas_pem,
+    ret = mbedtls_x509_crt_parse( &cachain, (const unsigned char *) mbedtls_test_cas_pem,
                           mbedtls_test_cas_pem_len );
     if( ret != 0 )
     {
@@ -432,13 +387,61 @@
         goto exit;
     }
 
-    base_info.ca_chain = srvcert.next;
-    base_info.server_cert = &srvcert;
-    base_info.server_key = &pkey;
+    mbedtls_printf( " ok\n" );
+
+    /*
+     * 1b. Seed the random number generator
+     */
+    mbedtls_printf( "  . Seeding the random number generator..." );
+
+    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
+                               (const unsigned char *) pers,
+                               strlen( pers ) ) ) != 0 )
+    {
+        mbedtls_printf( " failed: mbedtls_ctr_drbg_seed returned -0x%04x\n",
+                -ret );
+        goto exit;
+    }
 
     mbedtls_printf( " ok\n" );
 
     /*
+     * 1c. Prepare SSL configuration
+     */
+    mbedtls_printf( "  . Setting up the SSL data...." );
+
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                    MBEDTLS_SSL_IS_SERVER,
+                    MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 )
+    {
+        mbedtls_printf( " failed: mbedtls_ssl_config_defaults returned -0x%04x\n",
+                -ret );
+        goto exit;
+    }
+
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_mutexed_debug, stdout );
+
+    /* mbedtls_ssl_cache_get() and mbedtls_ssl_cache_set() are thread-safe if
+     * MBEDTLS_THREADING_C is set.
+     */
+#if defined(MBEDTLS_SSL_CACHE_C)
+    mbedtls_ssl_conf_session_cache( &conf, &cache,
+                                   mbedtls_ssl_cache_get,
+                                   mbedtls_ssl_cache_set );
+#endif
+
+    mbedtls_ssl_conf_ca_chain( &conf, &cachain, NULL );
+    if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
+        goto exit;
+    }
+
+    mbedtls_printf( " ok\n" );
+
+
+    /*
      * 2. Setup the listening TCP socket
      */
     mbedtls_printf( "  . Bind on https://localhost:4433/ ..." );
@@ -494,7 +497,9 @@
 #if defined(MBEDTLS_SSL_CACHE_C)
     mbedtls_ssl_cache_free( &cache );
 #endif
+    mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
+    mbedtls_ssl_config_free( &conf );
 
     mbedtls_mutex_free( &debug_mutex );
 
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index bd68d3d..a919ad9 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -97,6 +97,7 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_x509_crt srvcert;
     mbedtls_pk_context pkey;
 #if defined(MBEDTLS_SSL_CACHE_C)
@@ -104,6 +105,7 @@
 #endif
 
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
 #if defined(MBEDTLS_SSL_CACHE_C)
     mbedtls_ssl_cache_init( &cache );
 #endif
@@ -189,27 +191,33 @@
     mbedtls_printf( "  . Setting up the SSL data...." );
     fflush( stdout );
 
-    if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                    MBEDTLS_SSL_IS_SERVER,
+                    MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
         goto exit;
     }
 
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_SERVER );
-    mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_NONE );
-
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
 #if defined(MBEDTLS_SSL_CACHE_C)
-    mbedtls_ssl_set_session_cache( &ssl, mbedtls_ssl_cache_get, &cache,
-                                 mbedtls_ssl_cache_set, &cache );
+    mbedtls_ssl_conf_session_cache( &conf, &cache,
+                                   mbedtls_ssl_cache_get,
+                                   mbedtls_ssl_cache_set );
 #endif
 
-    mbedtls_ssl_set_ca_chain( &ssl, srvcert.next, NULL, NULL );
-    if( ( ret = mbedtls_ssl_set_own_cert( &ssl, &srvcert, &pkey ) ) != 0 )
+    mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL );
+    if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
+        goto exit;
+    }
+
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
         goto exit;
     }
 
@@ -244,7 +252,7 @@
         goto exit;
     }
 
-        mbedtls_ssl_set_bio_timeout( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL, 0 );
+    mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
     mbedtls_printf( " ok\n" );
 
@@ -256,7 +264,7 @@
 
     while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned %d\n\n", ret );
             goto reset;
@@ -277,7 +285,7 @@
         memset( buf, 0, sizeof( buf ) );
         ret = mbedtls_ssl_read( &ssl, buf, len );
 
-        if( ret == MBEDTLS_ERR_NET_WANT_READ || ret == MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
             continue;
 
         if( ret <= 0 )
@@ -325,7 +333,7 @@
             goto reset;
         }
 
-        if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
             goto exit;
@@ -339,8 +347,8 @@
 
     while( ( ret = mbedtls_ssl_close_notify( &ssl ) ) < 0 )
     {
-        if( ret != MBEDTLS_ERR_NET_WANT_READ &&
-            ret != MBEDTLS_ERR_NET_WANT_WRITE )
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
+            ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_close_notify returned %d\n\n", ret );
             goto reset;
@@ -369,6 +377,7 @@
     mbedtls_x509_crt_free( &srvcert );
     mbedtls_pk_free( &pkey );
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
 #if defined(MBEDTLS_SSL_CACHE_C)
     mbedtls_ssl_cache_free( &cache );
 #endif
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index be0d70c..863cc53 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -409,11 +409,11 @@
     if( first_try )
     {
         first_try = 0;
-        return( MBEDTLS_ERR_NET_WANT_READ );
+        return( MBEDTLS_ERR_SSL_WANT_READ );
     }
 
     ret = mbedtls_net_recv( ctx, buf, len );
-    if( ret != MBEDTLS_ERR_NET_WANT_READ )
+    if( ret != MBEDTLS_ERR_SSL_WANT_READ )
         first_try = 1; /* Next call will be a new operation */
     return( ret );
 }
@@ -426,11 +426,11 @@
     if( first_try )
     {
         first_try = 0;
-        return( MBEDTLS_ERR_NET_WANT_WRITE );
+        return( MBEDTLS_ERR_SSL_WANT_WRITE );
     }
 
     ret = mbedtls_net_send( ctx, buf, len );
-    if( ret != MBEDTLS_ERR_NET_WANT_WRITE )
+    if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
         first_try = 1; /* Next call will be a new operation */
     return( ret );
 }
@@ -547,7 +547,7 @@
         if( name_len == strlen( cur->name ) &&
             memcmp( name, cur->name, name_len ) == 0 )
         {
-            return( mbedtls_ssl_set_own_cert( ssl, cur->cert, cur->key ) );
+            return( mbedtls_ssl_set_hs_own_cert( ssl, cur->cert, cur->key ) );
         }
 
         cur = cur->next;
@@ -678,8 +678,7 @@
         if( name_len == strlen( cur->name ) &&
             memcmp( name, cur->name, name_len ) == 0 )
         {
-            return( mbedtls_ssl_set_psk( ssl, cur->key, cur->key_len,
-                                 name, name_len ) );
+            return( mbedtls_ssl_set_hs_psk( ssl, cur->key, cur->key_len ) );
         }
 
         cur = cur->next;
@@ -722,6 +721,7 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
     unsigned char renego_period[8] = { 0 };
 #endif
@@ -762,6 +762,7 @@
      */
     listen_fd = 0;
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     mbedtls_ctr_drbg_init( &ctr_drbg );
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_init( &cacert );
@@ -1518,61 +1519,56 @@
     mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
     fflush( stdout );
 
-    if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+    if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                    MBEDTLS_SSL_IS_SERVER,
+                    opt.transport ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret );
         goto exit;
     }
 
-    mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_SERVER );
     if( opt.auth_mode != DFL_AUTH_MODE )
-        mbedtls_ssl_set_authmode( &ssl, opt.auth_mode );
+        mbedtls_ssl_conf_authmode( &conf, opt.auth_mode );
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-    if( ( ret = mbedtls_ssl_set_transport( &ssl, opt.transport ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! selected transport is not available\n" );
-        goto exit;
-    }
-
     if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
-        mbedtls_ssl_set_handshake_timeout( &ssl, opt.hs_to_min, opt.hs_to_max );
+        mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-    if( ( ret = mbedtls_ssl_set_max_frag_len( &ssl, opt.mfl_code ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_max_frag_len returned %d\n\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret );
         goto exit;
     };
 #endif
 
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
     if( opt.trunc_hmac != DFL_TRUNC_HMAC )
-        mbedtls_ssl_set_truncated_hmac( &ssl, opt.trunc_hmac );
+        mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
 #endif
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
     if( opt.extended_ms != DFL_EXTENDED_MS )
-        mbedtls_ssl_set_extended_master_secret( &ssl, opt.extended_ms );
+        mbedtls_ssl_conf_extended_master_secret( &conf, opt.extended_ms );
 #endif
 
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
     if( opt.etm != DFL_ETM )
-        mbedtls_ssl_set_encrypt_then_mac( &ssl, opt.etm );
+        mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
 #endif
 
 #if defined(MBEDTLS_SSL_ALPN)
     if( opt.alpn_string != NULL )
-        if( ( ret = mbedtls_ssl_set_alpn_protocols( &ssl, alpn_list ) ) != 0 )
+        if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_alpn_protocols returned %d\n\n", ret );
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_alpn_protocols returned %d\n\n", ret );
             goto exit;
         }
 #endif
 
-    mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-    mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
+    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
 #if defined(MBEDTLS_SSL_CACHE_C)
     if( opt.cache_max != -1 )
@@ -1581,19 +1577,20 @@
     if( opt.cache_timeout != -1 )
         mbedtls_ssl_cache_set_timeout( &cache, opt.cache_timeout );
 
-    mbedtls_ssl_set_session_cache( &ssl, mbedtls_ssl_cache_get, &cache,
-                                 mbedtls_ssl_cache_set, &cache );
+    mbedtls_ssl_conf_session_cache( &conf, &cache,
+                                   mbedtls_ssl_cache_get,
+                                   mbedtls_ssl_cache_set );
 #endif
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    if( ( ret = mbedtls_ssl_set_session_tickets( &ssl, opt.tickets ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_session_tickets( &conf, opt.tickets ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_session_tickets returned %d\n\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_session_tickets returned %d\n\n", ret );
         goto exit;
     }
 
     if( opt.ticket_timeout != -1 )
-        mbedtls_ssl_set_session_ticket_lifetime( &ssl, opt.ticket_timeout );
+        mbedtls_ssl_conf_session_ticket_lifetime( &conf, opt.ticket_timeout );
 #endif
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -1609,7 +1606,7 @@
                 goto exit;
             }
 
-            mbedtls_ssl_set_dtls_cookies( &ssl, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
+            mbedtls_ssl_conf_dtls_cookies( &conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
                                        &cookie_ctx );
         }
         else
@@ -1617,7 +1614,7 @@
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
         if( opt.cookies == 0 )
         {
-            mbedtls_ssl_set_dtls_cookies( &ssl, NULL, NULL, NULL );
+            mbedtls_ssl_conf_dtls_cookies( &conf, NULL, NULL, NULL );
         }
         else
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
@@ -1627,50 +1624,50 @@
 
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
         if( opt.anti_replay != DFL_ANTI_REPLAY )
-            mbedtls_ssl_set_dtls_anti_replay( &ssl, opt.anti_replay );
+            mbedtls_ssl_conf_dtls_anti_replay( &conf, opt.anti_replay );
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
         if( opt.badmac_limit != DFL_BADMAC_LIMIT )
-            mbedtls_ssl_set_dtls_badmac_limit( &ssl, opt.badmac_limit );
+            mbedtls_ssl_conf_dtls_badmac_limit( &conf, opt.badmac_limit );
 #endif
     }
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
     if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
-        mbedtls_ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );
+        mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
 
     if( opt.arc4 != DFL_ARC4 )
-        mbedtls_ssl_set_arc4_support( &ssl, opt.arc4 );
+        mbedtls_ssl_conf_arc4_support( &conf, opt.arc4 );
 
     if( opt.version_suites != NULL )
     {
-        mbedtls_ssl_set_ciphersuites_for_version( &ssl, version_suites[0],
+        mbedtls_ssl_conf_ciphersuites_for_version( &conf, version_suites[0],
                                           MBEDTLS_SSL_MAJOR_VERSION_3,
                                           MBEDTLS_SSL_MINOR_VERSION_0 );
-        mbedtls_ssl_set_ciphersuites_for_version( &ssl, version_suites[1],
+        mbedtls_ssl_conf_ciphersuites_for_version( &conf, version_suites[1],
                                           MBEDTLS_SSL_MAJOR_VERSION_3,
                                           MBEDTLS_SSL_MINOR_VERSION_1 );
-        mbedtls_ssl_set_ciphersuites_for_version( &ssl, version_suites[2],
+        mbedtls_ssl_conf_ciphersuites_for_version( &conf, version_suites[2],
                                           MBEDTLS_SSL_MAJOR_VERSION_3,
                                           MBEDTLS_SSL_MINOR_VERSION_2 );
-        mbedtls_ssl_set_ciphersuites_for_version( &ssl, version_suites[3],
+        mbedtls_ssl_conf_ciphersuites_for_version( &conf, version_suites[3],
                                           MBEDTLS_SSL_MAJOR_VERSION_3,
                                           MBEDTLS_SSL_MINOR_VERSION_3 );
     }
 
     if( opt.allow_legacy != DFL_ALLOW_LEGACY )
-        mbedtls_ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
+        mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy );
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-    mbedtls_ssl_set_renegotiation( &ssl, opt.renegotiation );
+    mbedtls_ssl_conf_renegotiation( &conf, opt.renegotiation );
 
     if( opt.renego_delay != DFL_RENEGO_DELAY )
-        mbedtls_ssl_set_renegotiation_enforced( &ssl, opt.renego_delay );
+        mbedtls_ssl_conf_renegotiation_enforced( &conf, opt.renego_delay );
 
     if( opt.renego_period != DFL_RENEGO_PERIOD )
     {
         renego_period[7] = opt.renego_period;
-        mbedtls_ssl_set_renegotiation_period( &ssl, renego_period );
+        mbedtls_ssl_conf_renegotiation_period( &conf, renego_period );
     }
 #endif
 
@@ -1678,42 +1675,42 @@
     if( strcmp( opt.ca_path, "none" ) != 0 &&
         strcmp( opt.ca_file, "none" ) != 0 )
     {
-        mbedtls_ssl_set_ca_chain( &ssl, &cacert, NULL, NULL );
+        mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
     }
     if( key_cert_init )
-        if( ( ret = mbedtls_ssl_set_own_cert( &ssl, &srvcert, &pkey ) ) != 0 )
+        if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
             goto exit;
         }
     if( key_cert_init2 )
-        if( ( ret = mbedtls_ssl_set_own_cert( &ssl, &srvcert2, &pkey2 ) ) != 0 )
+        if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert2, &pkey2 ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
             goto exit;
         }
 #endif
 
 #if defined(SNI_OPTION)
     if( opt.sni != NULL )
-        mbedtls_ssl_set_sni( &ssl, sni_callback, sni_info );
+        mbedtls_ssl_conf_sni( &conf, sni_callback, sni_info );
 #endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
     if( strlen( opt.psk ) != 0 && strlen( opt.psk_identity ) != 0 )
     {
-        ret = mbedtls_ssl_set_psk( &ssl, psk, psk_len,
+        ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len,
                            (const unsigned char *) opt.psk_identity,
                            strlen( opt.psk_identity ) );
         if( ret != 0 )
         {
-            mbedtls_printf( "  failed\n  mbedtls_ssl_set_psk returned -0x%04X\n\n", - ret );
+            mbedtls_printf( "  failed\n  mbedtls_ssl_conf_psk returned -0x%04X\n\n", - ret );
             goto exit;
         }
     }
 
     if( opt.psk_list != NULL )
-        mbedtls_ssl_set_psk_cb( &ssl, psk_callback, psk_info );
+        mbedtls_ssl_conf_psk_cb( &conf, psk_callback, psk_info );
 #endif
 
 #if defined(MBEDTLS_DHM_C)
@@ -1722,39 +1719,38 @@
      */
 #if defined(MBEDTLS_FS_IO)
     if( opt.dhm_file != NULL )
-        ret = mbedtls_ssl_set_dh_param_ctx( &ssl, &dhm );
-    else
+        ret = mbedtls_ssl_conf_dh_param_ctx( &conf, &dhm );
 #endif
-        ret = mbedtls_ssl_set_dh_param( &ssl, MBEDTLS_DHM_RFC5114_MODP_2048_P,
-                                      MBEDTLS_DHM_RFC5114_MODP_2048_G );
-
     if( ret != 0 )
     {
-        mbedtls_printf( "  failed\n  mbedtls_ssl_set_dh_param returned -0x%04X\n\n", - ret );
+        mbedtls_printf( "  failed\n  mbedtls_ssl_conf_dh_param returned -0x%04X\n\n", - ret );
         goto exit;
     }
 #endif
 
     if( opt.min_version != DFL_MIN_VERSION )
-    {
-        ret = mbedtls_ssl_set_min_version( &ssl, MBEDTLS_SSL_MAJOR_VERSION_3, opt.min_version );
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  ! selected min_version is not available\n" );
-            goto exit;
-        }
-    }
+        mbedtls_ssl_conf_min_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.min_version );
 
     if( opt.max_version != DFL_MIN_VERSION )
+        mbedtls_ssl_conf_max_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.max_version );
+
+    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
     {
-        ret = mbedtls_ssl_set_max_version( &ssl, MBEDTLS_SSL_MAJOR_VERSION_3, opt.max_version );
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  ! selected max_version is not available\n" );
-            goto exit;
-        }
+        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,
+#if defined(MBEDTLS_HAVE_TIME)
+                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL
+#else
+                             NULL
+#endif
+                );
+
     mbedtls_printf( " ok\n" );
 
 reset:
@@ -1814,16 +1810,7 @@
         goto exit;
     }
 
-    if( opt.nbio == 2 )
-        mbedtls_ssl_set_bio_timeout( &ssl, &client_fd, my_send, my_recv, NULL, 0 );
-    else
-        mbedtls_ssl_set_bio_timeout( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv,
-#if defined(MBEDTLS_HAVE_TIME)
-                             opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL,
-#else
-                             NULL,
-#endif
-                             opt.read_timeout );
+    mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
     if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
@@ -1832,7 +1819,7 @@
                                                sizeof( client_ip ) ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! "
-                    "ssl_set_client_tranport_id() returned -0x%x\n\n", -ret );
+                    "ssl_set_client_transport_id() returned -0x%x\n\n", -ret );
             goto exit;
         }
     }
@@ -1869,8 +1856,8 @@
     fflush( stdout );
 
     do ret = mbedtls_ssl_handshake( &ssl );
-    while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-           ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+           ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
     if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
     {
@@ -1954,8 +1941,8 @@
             memset( buf, 0, sizeof( buf ) );
             ret = mbedtls_ssl_read( &ssl, buf, len );
 
-            if( ret == MBEDTLS_ERR_NET_WANT_READ ||
-                ret == MBEDTLS_ERR_NET_WANT_WRITE )
+            if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+                ret == MBEDTLS_ERR_SSL_WANT_WRITE )
                 continue;
 
             if( ret <= 0 )
@@ -2045,8 +2032,8 @@
         memset( buf, 0, sizeof( buf ) );
 
         do ret = mbedtls_ssl_read( &ssl, buf, len );
-        while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-               ret == MBEDTLS_ERR_NET_WANT_WRITE );
+        while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+               ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
         if( ret <= 0 )
         {
@@ -2081,8 +2068,8 @@
 
         while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
         {
-            if( ret != MBEDTLS_ERR_NET_WANT_READ &&
-                ret != MBEDTLS_ERR_NET_WANT_WRITE )
+            if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
+                ret != MBEDTLS_ERR_SSL_WANT_WRITE )
             {
                 mbedtls_printf( " failed\n  ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
                 goto reset;
@@ -2115,8 +2102,8 @@
                     goto reset;
                 }
 
-                if( ret != MBEDTLS_ERR_NET_WANT_READ &&
-                    ret != MBEDTLS_ERR_NET_WANT_WRITE )
+                if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
+                    ret != MBEDTLS_ERR_SSL_WANT_WRITE )
                 {
                     mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
                     goto reset;
@@ -2127,8 +2114,8 @@
     else /* Not stream, so datagram */
     {
         do ret = mbedtls_ssl_write( &ssl, buf, len );
-        while( ret == MBEDTLS_ERR_NET_WANT_READ ||
-               ret == MBEDTLS_ERR_NET_WANT_WRITE );
+        while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
+               ret == MBEDTLS_ERR_SSL_WANT_WRITE );
 
         if( ret < 0 )
         {
@@ -2158,7 +2145,7 @@
 
     /* No error checking, the connection might be closed already */
     do ret = mbedtls_ssl_close_notify( &ssl );
-    while( ret == MBEDTLS_ERR_NET_WANT_WRITE );
+    while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
     ret = 0;
 
     mbedtls_printf( " done\n" );
@@ -2205,6 +2192,7 @@
 #endif
 
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
     mbedtls_ctr_drbg_free( &ctr_drbg );
     mbedtls_entropy_free( &entropy );
 
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index a13f9bc..41bbb42 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -146,6 +146,7 @@
     mbedtls_entropy_context entropy;
     mbedtls_ctr_drbg_context ctr_drbg;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     mbedtls_x509_crt cacert;
     mbedtls_x509_crt clicert;
     mbedtls_x509_crl cacrl;
@@ -161,6 +162,7 @@
     server_fd = 0;
     mbedtls_ctr_drbg_init( &ctr_drbg );
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     mbedtls_x509_crt_init( &cacert );
     mbedtls_x509_crt_init( &clicert );
 #if defined(MBEDTLS_X509_CRL_PARSE_C)
@@ -372,7 +374,7 @@
                                    strlen( pers ) ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
-            goto exit;
+            goto ssl_exit;
         }
 
         mbedtls_printf( " ok\n" );
@@ -388,56 +390,61 @@
                                  opt.server_port, MBEDTLS_NET_PROTO_TCP ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_net_connect returned %d\n\n", ret );
-            goto exit;
+            goto ssl_exit;
         }
 
         /*
          * 3. Setup stuff
          */
-        if( ( ret = mbedtls_ssl_setup( &ssl ) ) != 0 )
+        if( ( ret = mbedtls_ssl_config_defaults( &conf,
+                        MBEDTLS_SSL_IS_CLIENT,
+                        MBEDTLS_SSL_TRANSPORT_STREAM ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
             goto exit;
         }
 
-        mbedtls_ssl_set_endpoint( &ssl, MBEDTLS_SSL_IS_CLIENT );
         if( verify )
         {
-            mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_REQUIRED );
-            mbedtls_ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
-            mbedtls_ssl_set_verify( &ssl, my_verify, NULL );
+            mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
+            mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
+            mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
         }
         else
-            mbedtls_ssl_set_authmode( &ssl, MBEDTLS_SSL_VERIFY_NONE );
+            mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE );
 
-        mbedtls_ssl_set_rng( &ssl, mbedtls_ctr_drbg_random, &ctr_drbg );
-        mbedtls_ssl_set_dbg( &ssl, my_debug, stdout );
-        mbedtls_ssl_set_bio_timeout( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL, 0 );
+        mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+        mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
-        if( ( ret = mbedtls_ssl_set_own_cert( &ssl, &clicert, &pkey ) ) != 0 )
+        if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) ) != 0 )
         {
-            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_own_cert returned %d\n\n", ret );
-            goto exit;
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
+            goto ssl_exit;
         }
 
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+        if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
+            goto ssl_exit;
+        }
+
         if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
         {
             mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
-            goto exit;
+            goto ssl_exit;
         }
-#endif
+
+        mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
 
         /*
          * 4. Handshake
          */
         while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
         {
-            if( ret != MBEDTLS_ERR_NET_WANT_READ && ret != MBEDTLS_ERR_NET_WANT_WRITE )
+            if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
             {
                 mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned %d\n\n", ret );
-                mbedtls_ssl_free( &ssl );
-                goto exit;
+                goto ssl_exit;
             }
         }
 
@@ -452,14 +459,16 @@
         if( ret == -1 )
         {
             mbedtls_printf( " failed\n  !  mbedtls_x509_crt_info returned %d\n\n", ret );
-            mbedtls_ssl_free( &ssl );
-            goto exit;
+            goto ssl_exit;
         }
 
         mbedtls_printf( "%s\n", buf );
 
         mbedtls_ssl_close_notify( &ssl );
+
+ssl_exit:
         mbedtls_ssl_free( &ssl );
+        mbedtls_ssl_config_free( &conf );
     }
     else
         goto usage;
diff --git a/scripts/data_files/rename-1.3-2.0.txt b/scripts/data_files/rename-1.3-2.0.txt
index 06b56fe..f86341e 100644
--- a/scripts/data_files/rename-1.3-2.0.txt
+++ b/scripts/data_files/rename-1.3-2.0.txt
@@ -546,10 +546,10 @@
 POLARSSL_ERR_NET_RECV_FAILED MBEDTLS_ERR_NET_RECV_FAILED
 POLARSSL_ERR_NET_SEND_FAILED MBEDTLS_ERR_NET_SEND_FAILED
 POLARSSL_ERR_NET_SOCKET_FAILED MBEDTLS_ERR_NET_SOCKET_FAILED
-POLARSSL_ERR_NET_TIMEOUT MBEDTLS_ERR_NET_TIMEOUT
+POLARSSL_ERR_NET_TIMEOUT MBEDTLS_ERR_SSL_TIMEOUT
 POLARSSL_ERR_NET_UNKNOWN_HOST MBEDTLS_ERR_NET_UNKNOWN_HOST
-POLARSSL_ERR_NET_WANT_READ MBEDTLS_ERR_NET_WANT_READ
-POLARSSL_ERR_NET_WANT_WRITE MBEDTLS_ERR_NET_WANT_WRITE
+POLARSSL_ERR_NET_WANT_READ MBEDTLS_ERR_SSL_WANT_READ
+POLARSSL_ERR_NET_WANT_WRITE MBEDTLS_ERR_SSL_WANT_WRITE
 POLARSSL_ERR_OID_BUF_TOO_SMALL MBEDTLS_ERR_OID_BUF_TOO_SMALL
 POLARSSL_ERR_OID_NOT_FOUND MBEDTLS_ERR_OID_NOT_FOUND
 POLARSSL_ERR_PADLOCK_DATA_MISALIGNED MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED
@@ -1969,7 +1969,7 @@
 ssl_hw_record_write mbedtls_ssl_hw_record_write
 ssl_init mbedtls_ssl_init
 ssl_key_cert mbedtls_ssl_key_cert
-ssl_legacy_renegotiation mbedtls_ssl_legacy_renegotiation
+ssl_legacy_renegotiation mbedtls_ssl_conf_legacy_renegotiation
 ssl_list_ciphersuites mbedtls_ssl_list_ciphersuites
 ssl_md_alg_from_hash mbedtls_ssl_md_alg_from_hash
 ssl_optimize_checksum mbedtls_ssl_optimize_checksum
@@ -1997,49 +1997,49 @@
 ssl_session_free mbedtls_ssl_session_free
 ssl_session_init mbedtls_ssl_session_init
 ssl_session_reset mbedtls_ssl_session_reset
-ssl_set_alpn_protocols mbedtls_ssl_set_alpn_protocols
-ssl_set_arc4_support mbedtls_ssl_set_arc4_support
-ssl_set_authmode mbedtls_ssl_set_authmode
+ssl_set_alpn_protocols mbedtls_ssl_conf_alpn_protocols
+ssl_set_arc4_support mbedtls_ssl_conf_arc4_support
+ssl_set_authmode mbedtls_ssl_conf_authmode
 ssl_set_bio mbedtls_ssl_set_bio
 ssl_set_bio_timeout mbedtls_ssl_set_bio_timeout
-ssl_set_ca_chain mbedtls_ssl_set_ca_chain
-ssl_set_cbc_record_splitting mbedtls_ssl_set_cbc_record_splitting
-ssl_set_ciphersuites mbedtls_ssl_set_ciphersuites
-ssl_set_ciphersuites_for_version mbedtls_ssl_set_ciphersuites_for_version
+ssl_set_ca_chain mbedtls_ssl_conf_ca_chain
+ssl_set_cbc_record_splitting mbedtls_ssl_conf_cbc_record_splitting
+ssl_set_ciphersuites mbedtls_ssl_conf_ciphersuites
+ssl_set_ciphersuites_for_version mbedtls_ssl_conf_ciphersuites_for_version
 ssl_set_client_transport_id mbedtls_ssl_set_client_transport_id
-ssl_set_curves mbedtls_ssl_set_curves
-ssl_set_dbg mbedtls_ssl_set_dbg
-ssl_set_dh_param mbedtls_ssl_set_dh_param
-ssl_set_dh_param_ctx mbedtls_ssl_set_dh_param_ctx
-ssl_set_dtls_anti_replay mbedtls_ssl_set_dtls_anti_replay
-ssl_set_dtls_badmac_limit mbedtls_ssl_set_dtls_badmac_limit
-ssl_set_dtls_cookies mbedtls_ssl_set_dtls_cookies
-ssl_set_encrypt_then_mac mbedtls_ssl_set_encrypt_then_mac
-ssl_set_endpoint mbedtls_ssl_set_endpoint
-ssl_set_extended_master_secret mbedtls_ssl_set_extended_master_secret
-ssl_set_fallback mbedtls_ssl_set_fallback
-ssl_set_handshake_timeout mbedtls_ssl_set_handshake_timeout
+ssl_set_curves mbedtls_ssl_conf_curves
+ssl_set_dbg mbedtls_ssl_conf_dbg
+ssl_set_dh_param mbedtls_ssl_conf_dh_param
+ssl_set_dh_param_ctx mbedtls_ssl_conf_dh_param_ctx
+ssl_set_dtls_anti_replay mbedtls_ssl_conf_dtls_anti_replay
+ssl_set_dtls_badmac_limit mbedtls_ssl_conf_dtls_badmac_limit
+ssl_set_dtls_cookies mbedtls_ssl_conf_dtls_cookies
+ssl_set_encrypt_then_mac mbedtls_ssl_conf_encrypt_then_mac
+ssl_set_endpoint mbedtls_ssl_conf_endpoint
+ssl_set_extended_master_secret mbedtls_ssl_conf_extended_master_secret
+ssl_set_fallback mbedtls_ssl_conf_fallback
+ssl_set_handshake_timeout mbedtls_ssl_conf_handshake_timeout
 ssl_set_hostname mbedtls_ssl_set_hostname
-ssl_set_max_frag_len mbedtls_ssl_set_max_frag_len
-ssl_set_max_version mbedtls_ssl_set_max_version
-ssl_set_min_version mbedtls_ssl_set_min_version
-ssl_set_own_cert mbedtls_ssl_set_own_cert
+ssl_set_max_frag_len mbedtls_ssl_conf_max_frag_len
+ssl_set_max_version mbedtls_ssl_conf_max_version
+ssl_set_min_version mbedtls_ssl_conf_min_version
+ssl_set_own_cert mbedtls_ssl_conf_own_cert
 ssl_set_own_cert_alt mbedtls_ssl_set_own_cert_alt
 ssl_set_own_cert_rsa mbedtls_ssl_set_own_cert_rsa
-ssl_set_psk mbedtls_ssl_set_psk
-ssl_set_psk_cb mbedtls_ssl_set_psk_cb
-ssl_set_renegotiation mbedtls_ssl_set_renegotiation
-ssl_set_renegotiation_enforced mbedtls_ssl_set_renegotiation_enforced
-ssl_set_renegotiation_period mbedtls_ssl_set_renegotiation_period
-ssl_set_rng mbedtls_ssl_set_rng
+ssl_set_psk mbedtls_ssl_conf_psk
+ssl_set_psk_cb mbedtls_ssl_conf_psk_cb
+ssl_set_renegotiation mbedtls_ssl_conf_renegotiation
+ssl_set_renegotiation_enforced mbedtls_ssl_conf_renegotiation_enforced
+ssl_set_renegotiation_period mbedtls_ssl_conf_renegotiation_period
+ssl_set_rng mbedtls_ssl_conf_rng
 ssl_set_session mbedtls_ssl_set_session
-ssl_set_session_cache mbedtls_ssl_set_session_cache
-ssl_set_session_ticket_lifetime mbedtls_ssl_set_session_ticket_lifetime
-ssl_set_session_tickets mbedtls_ssl_set_session_tickets
-ssl_set_sni mbedtls_ssl_set_sni
-ssl_set_transport mbedtls_ssl_set_transport
-ssl_set_truncated_hmac mbedtls_ssl_set_truncated_hmac
-ssl_set_verify mbedtls_ssl_set_verify
+ssl_set_session_cache mbedtls_ssl_conf_session_cache
+ssl_set_session_ticket_lifetime mbedtls_ssl_conf_session_ticket_lifetime
+ssl_set_session_tickets mbedtls_ssl_conf_session_tickets
+ssl_set_sni mbedtls_ssl_conf_sni
+ssl_set_transport mbedtls_ssl_conf_transport
+ssl_set_truncated_hmac mbedtls_ssl_conf_truncated_hmac
+ssl_set_verify mbedtls_ssl_conf_verify
 ssl_sig_from_pk mbedtls_ssl_sig_from_pk
 ssl_states mbedtls_ssl_states
 ssl_ticket_keys mbedtls_ssl_ticket_keys
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index a28f4a0..510000a 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -626,8 +626,8 @@
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
              trunc_hmac=1" \
             0 \
-            -S "dumping 'computed mac' (20 bytes)" \
-            -s "dumping 'computed mac' (10 bytes)"
+            -s "dumping 'computed mac' (20 bytes)" \
+            -S "dumping 'computed mac' (10 bytes)"
 
 run_test    "Truncated HMAC: client enabled, server disabled" \
             "$P_SRV debug_level=4 trunc_hmac=0" \
@@ -1044,7 +1044,7 @@
             -s "a session has been resumed" \
             -c "a session has been resumed"
 
-run_test    "Session resume using cache: timemout > delay" \
+run_test    "Session resume using cache: timeout > delay" \
             "$P_SRV debug_level=3 tickets=0" \
             "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=0" \
             0 \
diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function
index 492e32d..5c8993f 100644
--- a/tests/suites/test_suite_debug.function
+++ b/tests/suites/test_suite_debug.function
@@ -34,20 +34,28 @@
                                 char *result_str )
 {
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     struct buffer_data buffer;
 
-    memset( &ssl, 0, sizeof( mbedtls_ssl_context ) );
+    mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     memset( buffer.buf, 0, 2000 );
     buffer.ptr = buffer.buf;
 
+    TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
+
     mbedtls_debug_set_log_mode( MBEDTLS_DEBUG_LOG_FULL );
     mbedtls_debug_set_threshold( threshold );
-    mbedtls_ssl_set_dbg(&ssl, string_debug, &buffer);
+    mbedtls_ssl_conf_dbg( &conf, string_debug, &buffer);
 
     mbedtls_debug_print_msg( &ssl, level, file, line,
                      mbedtls_debug_fmt("Text message, 2 == %d", 2 ) );
 
     TEST_ASSERT( strcmp( buffer.buf, result_str ) == 0 );
+
+exit:
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
 }
 /* END_CASE */
 
@@ -56,18 +64,26 @@
                       char *result_str )
 {
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     struct buffer_data buffer;
 
-    memset( &ssl, 0, sizeof( mbedtls_ssl_context ) );
+    mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     memset( buffer.buf, 0, 2000 );
     buffer.ptr = buffer.buf;
 
+    TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
+
     mbedtls_debug_set_log_mode( mode );
-    mbedtls_ssl_set_dbg(&ssl, string_debug, &buffer);
+    mbedtls_ssl_conf_dbg( &conf, string_debug, &buffer);
 
     mbedtls_debug_print_ret( &ssl, 0, file, line, text, value);
 
     TEST_ASSERT( strcmp( buffer.buf, result_str ) == 0 );
+
+exit:
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
 }
 /* END_CASE */
 
@@ -77,22 +93,30 @@
 {
     unsigned char data[10000];
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     struct buffer_data buffer;
     size_t data_len;
 
+    mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     memset( &data, 0, sizeof( data ) );
-    memset( &ssl, 0, sizeof( mbedtls_ssl_context ) );
     memset( buffer.buf, 0, 2000 );
     buffer.ptr = buffer.buf;
 
     data_len = unhexify( data, data_string );
 
+    TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
+
     mbedtls_debug_set_log_mode( mode );
-    mbedtls_ssl_set_dbg(&ssl, string_debug, &buffer);
+    mbedtls_ssl_conf_dbg( &conf, string_debug, &buffer);
 
     mbedtls_debug_print_buf( &ssl, 0, file, line, text, data, data_len );
 
     TEST_ASSERT( strcmp( buffer.buf, result_str ) == 0 );
+
+exit:
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
 }
 /* END_CASE */
 
@@ -102,15 +126,19 @@
 {
     mbedtls_x509_crt   crt;
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     struct buffer_data buffer;
 
+    mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     mbedtls_x509_crt_init( &crt );
-    memset( &ssl, 0, sizeof( mbedtls_ssl_context ) );
     memset( buffer.buf, 0, 2000 );
     buffer.ptr = buffer.buf;
 
+    TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
+
     mbedtls_debug_set_log_mode( mode );
-    mbedtls_ssl_set_dbg(&ssl, string_debug, &buffer);
+    mbedtls_ssl_conf_dbg( &conf, string_debug, &buffer);
 
     TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
     mbedtls_debug_print_crt( &ssl, 0, file, line, prefix, &crt);
@@ -119,6 +147,8 @@
 
 exit:
     mbedtls_x509_crt_free( &crt );
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
 }
 /* END_CASE */
 
@@ -127,19 +157,22 @@
                       char *prefix, char *result_str )
 {
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     struct buffer_data buffer;
     mbedtls_mpi val;
 
+    mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
     mbedtls_mpi_init( &val );
-
-    memset( &ssl, 0, sizeof( mbedtls_ssl_context ) );
     memset( buffer.buf, 0, 2000 );
     buffer.ptr = buffer.buf;
 
+    TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
+
     TEST_ASSERT( mbedtls_mpi_read_string( &val, radix, value ) == 0 );
 
     mbedtls_debug_set_log_mode( mode );
-    mbedtls_ssl_set_dbg(&ssl, string_debug, &buffer);
+    mbedtls_ssl_conf_dbg( &conf, string_debug, &buffer);
 
     mbedtls_debug_print_mpi( &ssl, 0, file, line, prefix, &val);
 
@@ -147,5 +180,7 @@
 
 exit:
     mbedtls_mpi_free( &val );
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
 }
 /* END_CASE */
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 6d9a4c0..c8acfea 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -11,12 +11,16 @@
 void ssl_dtls_replay( char *prevs, char *new, int ret )
 {
     mbedtls_ssl_context ssl;
+    mbedtls_ssl_config conf;
     char *end_prevs = prevs + strlen( prevs ) + 1;
 
     mbedtls_ssl_init( &ssl );
+    mbedtls_ssl_config_init( &conf );
 
-    TEST_ASSERT( mbedtls_ssl_setup( &ssl ) == 0 );
-    TEST_ASSERT( mbedtls_ssl_set_transport( &ssl, MBEDTLS_SSL_TRANSPORT_DATAGRAM ) == 0 );
+    TEST_ASSERT( mbedtls_ssl_config_defaults( &conf,
+                 MBEDTLS_SSL_IS_CLIENT,
+                 MBEDTLS_SSL_TRANSPORT_DATAGRAM ) == 0 );
+    TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
 
     /* Read previous record numbers */
     for( ; end_prevs - prevs >= 13; prevs += 13 )
@@ -31,5 +35,6 @@
     TEST_ASSERT( mbedtls_ssl_dtls_replay_check( &ssl ) == ret );
 
     mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
 }
 /* END_CASE */