Merge pull request #599 from ARMmbed/baremetal-ec-preparation

[Baremetal] Avoid heap-allocation for client-supported elliptic curves
diff --git a/configs/baremetal.h b/configs/baremetal.h
index 7ff7b07..ee514b4 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -93,6 +93,12 @@
 #define MBEDTLS_SSL_CONF_AUTHMODE MBEDTLS_SSL_VERIFY_REQUIRED
 #define MBEDTLS_SSL_CONF_BADMAC_LIMIT 0
 #define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED
+#define MBEDTLS_SSL_CONF_GET_TIMER mbedtls_timing_get_delay
+#define MBEDTLS_SSL_CONF_SET_TIMER mbedtls_timing_set_delay
+#define MBEDTLS_SSL_CONF_RECV mbedtls_net_recv
+#define MBEDTLS_SSL_CONF_SEND mbedtls_net_send
+#define MBEDTLS_SSL_CONF_RECV_TIMEOUT mbedtls_net_recv_timeout
+#define MBEDTLS_SSL_CONF_RNG mbedtls_hmac_drbg_random
 #define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET \
     MBEDTLS_SSL_EXTENDED_MS_ENABLED
 #define MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET \
diff --git a/configs/baremetal_test.h b/configs/baremetal_test.h
index 82c0ed1..1b87474 100644
--- a/configs/baremetal_test.h
+++ b/configs/baremetal_test.h
@@ -51,6 +51,8 @@
 
 /* ssl_client2 and ssl_server2 use CTR-DRBG so far. */
 #define MBEDTLS_CTR_DRBG_C
+#undef MBEDTLS_SSL_CONF_RNG
+#define MBEDTLS_SSL_CONF_RNG mbedtls_ctr_drbg_random
 
 /* The ticket implementation hardcodes AES-GCM */
 #define MBEDTLS_GCM_C
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 764fba4..735a1e4 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -668,7 +668,26 @@
       !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) ) || \
     ( !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) &&           \
       defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) )
-#define "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET and MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET must be defined together."
+#error "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET and MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET must be defined together."
+#endif
+
+#if ( defined(MBEDTLS_SSL_CONF_SEND) &&                 \
+      !( defined(MBEDTLS_SSL_CONF_RECV) &&              \
+         defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) ) ) ||  \
+    ( defined(MBEDTLS_SSL_CONF_RECV) &&                 \
+      !( defined(MBEDTLS_SSL_CONF_SEND) &&              \
+         defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) ) ) ||  \
+    ( defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT) &&         \
+      !( defined(MBEDTLS_SSL_CONF_SEND) &&              \
+         defined(MBEDTLS_SSL_CONF_RECV) ) )
+#error "MBEDTLS_SSL_CONF_SEND/RECV/RECV_TIMEOUT must be defined simultaneously"
+#endif
+
+#if ( defined(MBEDTLS_SSL_CONF_GET_TIMER) &&            \
+      !defined(MBEDTLS_SSL_CONF_SET_TIMER) ) || \
+    ( !defined(MBEDTLS_SSL_CONF_GET_TIMER) &&           \
+      defined(MBEDTLS_SSL_CONF_SET_TIMER) )
+#error "MBEDTLS_SSL_CONF_GET_TIMER and MBEDTLS_SSL_CONF_SET_TIMER must be defined together."
 #endif
 
 #if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 95dd4cd..91d2550 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -3601,6 +3601,41 @@
 //#define MBEDTLS_SSL_CONF_CID_LEN 0
 //#define MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID MBEDTLS_SSL_UNEXPECTED_CID_IGNORE
 
+/* The timer callbacks to use by the SSL module.
+ * If defined,
+ * - MBEDTLS_SSL_CONF_SET_TIMER must evaluate to the name of an externally
+ *   defined function with signature
+ *      void f_set_timer( void* , uint32_t, uint32_t ),
+ * * MBEDTLS_SSL_CONF_SEND must evaluate to the name of an externally
+ *   defined function with signature
+ *      int f_get_timer( void* ).
+ */
+//#define MBEDTLS_SSL_CONF_GET_TIMER mbedtls_timing_get_delay
+//#define MBEDTLS_SSL_CONF_SET_TIMER mbedtls_timing_set_delay
+
+/* The send and receive callbacks to use by the SSL module.
+ * If defined,
+ * - MBEDTLS_SSL_CONF_RECV must evaluate to the name of an externally
+ *   defined function with signature
+ *      int f_recv( void*, unsigned char *, size_t ),
+ * * MBEDTLS_SSL_CONF_SEND must evaluate to the name of an externally
+ *   defined function with signature
+ *      int f_send( void*, const unsigned char *, size_t ),
+ * * MBEDTLS_SSL_CONF_RECV_TIMEOUT must evaluate to the name of an
+ *   externally defined function with signature
+ *      int f_recv_timeout( void*, const unsigned char *, size_t, uint32_t ).
+ */
+//#define MBEDTLS_SSL_CONF_RECV mbedtls_net_recv
+//#define MBEDTLS_SSL_CONF_SEND mbedtls_net_send
+//#define MBEDTLS_SSL_CONF_RECV_TIMEOUT mbedtls_net_recv_timeout
+
+/* The PRNG to use by the SSL module. If defined, this must
+ * evaluate to the name on externally defined function with signature
+ * int f_rng(void *, unsigned char *, size_t),
+ * e.g. mbedtls_ctr_drbg_random or mbedtls_hmac_drbg_random.
+ */
+//#define MBEDTLS_SSL_CONF_RNG mbedtls_ctr_drbg_random
+
 /* ExtendedMasterSecret extension
  * The following two options must be set/unset simultaneously. */
 //#define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MS_ENABLED
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index ead0fa7..ad60e82 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -902,8 +902,10 @@
     void (*f_dbg)(void *, int, const char *, int, const char *);
     void *p_dbg;                    /*!< context for the debug function     */
 
+#if !defined(MBEDTLS_SSL_CONF_RNG)
     /** Callback for getting (pseudo-)random numbers                        */
     int  (*f_rng)(void *, unsigned char *, size_t);
+#endif /* !MBEDTLS_SSL_CONF_RNG */
     void *p_rng;                    /*!< context for the RNG function       */
 
 #if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE)
@@ -1144,9 +1146,15 @@
     unsigned badmac_seen;       /*!< records with a bad MAC received    */
 #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
 
+#if !defined(MBEDTLS_SSL_CONF_SEND)
     mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
+#endif /* !MBEDTLS_SSL_CONF_SEND */
+#if !defined(MBEDTLS_SSL_CONF_RECV)
     mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
+#endif /* !MBEDTLS_SSL_CONF_RECV */
+#if !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
     mbedtls_ssl_recv_timeout_t *f_recv_timeout;
+#endif /* !MBEDTLS_SSL_CONF_RECV_TIMEOUT */
                                 /*!< Callback for network receive with timeout */
 
     void *p_bio;                /*!< context for I/O operations   */
@@ -1175,8 +1183,12 @@
      */
     void *p_timer;              /*!< context for the timer callbacks */
 
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER)
     mbedtls_ssl_set_timer_t *f_set_timer;       /*!< set timer callback */
+#endif /* !MBEDTLS_SSL_CONF_SET_TIMER */
+#if !defined(MBEDTLS_SSL_CONF_GET_TIMER)
     mbedtls_ssl_get_timer_t *f_get_timer;       /*!< get timer callback */
+#endif /* !MBEDTLS_SSL_CONF_GET_TIMER */
 
     /*
      * Record layer (incoming data)
@@ -1462,9 +1474,13 @@
                      void *p_vrfy );
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
+#if !defined(MBEDTLS_SSL_CONF_RNG)
 /**
  * \brief          Set the random number generator callback
  *
+ * \note           On constrained systems, the RNG can also be configured at
+ *                 compile-time via the option MBEDTLS_SSL_CONF_RNG.
+ *
  * \param conf     SSL configuration
  * \param f_rng    RNG function
  * \param p_rng    RNG parameter
@@ -1472,6 +1488,16 @@
 void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
                   int (*f_rng)(void *, unsigned char *, size_t),
                   void *p_rng );
+#else /* !MBEDTLS_SSL_CONF_RNG */
+/**
+ * \brief          Set the random number generator callback context.
+ *
+ * \param conf     SSL configuration
+ * \param p_rng    RNG parameter
+ */
+void mbedtls_ssl_conf_rng_ctx( mbedtls_ssl_config *conf,
+                               void *p_rng );
+#endif /* MBEDTLS_SSL_CONF_RNG */
 
 /**
  * \brief          Set the debug callback
@@ -1491,6 +1517,9 @@
                   void (*f_dbg)(void *, int, const char *, int, const char *),
                   void  *p_dbg );
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
 /**
  * \brief          Set the underlying BIO callbacks for write, read and
  *                 read-with-timeout.
@@ -1516,6 +1545,11 @@
  *                 \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for
  *                 the conventions those callbacks must follow.
  *
+ * \note           On constrained systems, the pointers \p f_send, \p f_recv,
+ *                 and \p f_recv_timeout can also be configured at compile-time
+ *                 via the macros MBEDTLS_SSL_CONF_RECV, MBEDTLS_SSL_CONF_SEND
+ *                 and MBEDTLS_SSL_CONF_RECV_TIMEOUT.
+ *
  * \note           On some platforms, net_sockets.c provides
  *                 \c mbedtls_net_send(), \c mbedtls_net_recv() and
  *                 \c mbedtls_net_recv_timeout() that are suitable to be used
@@ -1526,6 +1560,22 @@
                           mbedtls_ssl_send_t *f_send,
                           mbedtls_ssl_recv_t *f_recv,
                           mbedtls_ssl_recv_timeout_t *f_recv_timeout );
+#else /* !( MBEDTLS_SSL_CONF_RECV &&
+            MBEDTLS_SSL_CONF_SEND &&
+            MBEDTLS_SSL_CONF_RECV_TIMEOUT ) */
+/**
+ * \brief          Set the context to be passed to the underlying BIO callbacks
+ *                 for write, read and read-with-timeout.
+ *
+ * \param ssl      The SSL context to configure.
+ * \param p_bio    The parameter (context) to be used for the BIO callbacks.
+ *
+ */
+void mbedtls_ssl_set_bio_ctx( mbedtls_ssl_context *ssl,
+                              void *p_bio );
+#endif /* MBEDTLS_SSL_CONF_RECV &&
+          MBEDTLS_SSL_CONF_SEND &&
+          MBEDTLS_SSL_CONF_RECV_TIMEOUT */
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
 
@@ -1732,30 +1782,50 @@
 void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
 #endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */
 
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \
+    !defined(MBEDTLS_SSL_CONF_GET_TIMER)
 /**
- * \brief          Set the timer callbacks (Mandatory for DTLS.)
+ * \brief         Set the timer callbacks (Mandatory for DTLS.)
  *
- * \param ssl      SSL context
- * \param p_timer  parameter (context) shared by timer callbacks
+ * \param ssl     SSL context
+ * \param p_timer parameter (context) shared by timer callbacks
  * \param f_set_timer   set timer callback
  * \param f_get_timer   get timer callback. Must return:
  *
- * \note           See the documentation of \c mbedtls_ssl_set_timer_t and
- *                 \c mbedtls_ssl_get_timer_t for the conventions this pair of
- *                 callbacks must follow.
+ * \note          See the documentation of \c mbedtls_ssl_set_timer_t and
+ *                \c mbedtls_ssl_get_timer_t for the conventions this pair of
+ *                callbacks must follow.
  *
- * \note           On some platforms, timing.c provides
- *                 \c mbedtls_timing_set_delay() and
- *                 \c mbedtls_timing_get_delay() that are suitable for using
- *                 here, except if using an event-driven style.
+ * \note          On some platforms, timing.c provides
+ *                \c mbedtls_timing_set_delay() and
+ *                \c mbedtls_timing_get_delay() that are suitable for using
+ *                here, except if using an event-driven style.
  *
- * \note           See also the "DTLS tutorial" article in our knowledge base.
- *                 https://tls.mbed.org/kb/how-to/dtls-tutorial
+ * \note          On constrained systems, the timer callbacks \p f_set_timer
+ *                and \p f_get_timer may also be configured at compile-time
+ *                via MBEDTLS_SSL_CONF_GET_TIMER and MBEDTLS_SSL_CONF_SET_TIMER.
+ *
+ * \note          See also the "DTLS tutorial" article in our knowledge base.
+ *                https://tls.mbed.org/kb/how-to/dtls-tutorial
  */
 void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
                                void *p_timer,
                                mbedtls_ssl_set_timer_t *f_set_timer,
                                mbedtls_ssl_get_timer_t *f_get_timer );
+#else /* !( MBEDTLS_SSL_CONF_SET_TIMER &&
+            MBEDTLS_SSL_CONF_GET_TIMER ) */
+/**
+ * \brief          Set the context to be passed to the timer callbacks
+ *                 (Mandatory for DTLS.)
+ *
+ * \param ssl      The SSL context to configure.
+ * \param p_timer  The context to be passed to the timer callbacks.
+ *
+ */
+void mbedtls_ssl_set_timer_cb_ctx( mbedtls_ssl_context *ssl,
+                                   void *p_timer );
+#endif /* MBEDTLS_SSL_CONF_SET_TIMER &&
+          MBEDTLS_SSL_CONF_GET_TIMER */
 
 /**
  * \brief           Callback type: generate and write session ticket
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index e9f3409..151589f 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1289,6 +1289,123 @@
 #endif /* MBEDTLS_SSL_CONF_ANTI_REPLAY */
 #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
 
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER)
+static inline mbedtls_ssl_set_timer_t* mbedtls_ssl_get_set_timer(
+    mbedtls_ssl_context const *ssl )
+{
+    return( ssl->f_set_timer );
+}
+#else /* !MBEDTLS_SSL_CONF_SET_TIMER */
+
+#define mbedtls_ssl_conf_set_timer_func MBEDTLS_SSL_CONF_SET_TIMER
+extern void mbedtls_ssl_conf_set_timer_func( void*, uint32_t, uint32_t );
+
+static inline mbedtls_ssl_set_timer_t* mbedtls_ssl_get_set_timer(
+    mbedtls_ssl_context const *ssl )
+{
+    ((void) ssl);
+    return ((mbedtls_ssl_set_timer_t*) mbedtls_ssl_conf_set_timer_func);
+}
+#endif /* MBEDTLS_SSL_CONF_SET_TIMER */
+
+#if !defined(MBEDTLS_SSL_CONF_GET_TIMER)
+static inline mbedtls_ssl_get_timer_t* mbedtls_ssl_get_get_timer(
+    mbedtls_ssl_context const *ssl )
+{
+    return( ssl->f_get_timer );
+}
+#else /* !MBEDTLS_SSL_CONF_GET_TIMER */
+
+#define mbedtls_ssl_conf_get_timer_func MBEDTLS_SSL_CONF_GET_TIMER
+extern int mbedtls_ssl_conf_get_timer_func( void* );
+
+static inline mbedtls_ssl_get_timer_t* mbedtls_ssl_get_get_timer(
+    mbedtls_ssl_context const *ssl )
+{
+    ((void) ssl);
+    return ((mbedtls_ssl_get_timer_t*) mbedtls_ssl_conf_get_timer_func);
+}
+#endif /* MBEDTLS_SSL_CONF_GET_TIMER */
+
+#if !defined(MBEDTLS_SSL_CONF_RECV)
+static inline mbedtls_ssl_recv_t* mbedtls_ssl_get_recv(
+    mbedtls_ssl_context const *ssl )
+{
+    return( ssl->f_recv );
+}
+#else /* !MBEDTLS_SSL_CONF_RECV */
+
+#define mbedtls_ssl_conf_recv_func MBEDTLS_SSL_CONF_RECV
+extern int mbedtls_ssl_conf_recv_func( void*, unsigned char*, size_t );
+
+static inline mbedtls_ssl_recv_t* mbedtls_ssl_get_recv(
+    mbedtls_ssl_context const *ssl )
+{
+    ((void) ssl);
+    return ((mbedtls_ssl_recv_t*) mbedtls_ssl_conf_recv_func);
+}
+#endif /* MBEDTLS_SSL_CONF_RECV */
+
+#if !defined(MBEDTLS_SSL_CONF_SEND)
+static inline mbedtls_ssl_send_t* mbedtls_ssl_get_send(
+    mbedtls_ssl_context const *ssl )
+{
+    return( ssl->f_send );
+}
+#else /* !MBEDTLS_SSL_CONF_SEND */
+
+#define mbedtls_ssl_conf_send_func MBEDTLS_SSL_CONF_SEND
+extern int mbedtls_ssl_conf_send_func( void*, unsigned char const*, size_t );
+
+static inline mbedtls_ssl_send_t* mbedtls_ssl_get_send(
+    mbedtls_ssl_context const *ssl )
+{
+    ((void) ssl);
+    return ((mbedtls_ssl_send_t*) mbedtls_ssl_conf_send_func);
+}
+#endif /* MBEDTLS_SSL_CONF_SEND */
+
+#if !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
+static inline mbedtls_ssl_recv_timeout_t* mbedtls_ssl_get_recv_timeout(
+    mbedtls_ssl_context const *ssl )
+{
+    return( ssl->f_recv_timeout );
+}
+#else /* !MBEDTLS_SSL_CONF_RECV_TIMEOUT */
+
+#define mbedtls_ssl_conf_recv_timeout_func MBEDTLS_SSL_CONF_RECV_TIMEOUT
+extern int mbedtls_ssl_conf_recv_timeout_func(
+    void*, unsigned char*, size_t, uint32_t );
+
+static inline mbedtls_ssl_recv_timeout_t* mbedtls_ssl_get_recv_timeout(
+    mbedtls_ssl_context const *ssl )
+{
+    ((void) ssl);
+    return ((mbedtls_ssl_recv_timeout_t*) mbedtls_ssl_conf_recv_timeout_func);
+}
+#endif /* MBEDTLS_SSL_CONF_RECV_TIMEOUT */
+
+typedef int mbedtls_frng_t( void*, unsigned char*, size_t );
+
+#if !defined(MBEDTLS_SSL_CONF_RNG)
+static inline mbedtls_frng_t* mbedtls_ssl_conf_get_frng(
+    mbedtls_ssl_config const *conf )
+{
+    return( conf->f_rng );
+}
+#else /* !MBEDTLS_SSL_CONF_RNG */
+
+#define mbedtls_ssl_conf_rng_func MBEDTLS_SSL_CONF_RNG
+extern int mbedtls_ssl_conf_rng_func( void*, unsigned char*, size_t );
+
+static inline mbedtls_frng_t* mbedtls_ssl_conf_get_frng(
+    mbedtls_ssl_config const *conf )
+{
+    ((void) conf);
+    return ((mbedtls_frng_t*) mbedtls_ssl_conf_rng_func);
+}
+#endif /* MBEDTLS_SSL_CONF_RNG */
+
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
 static inline unsigned int mbedtls_ssl_conf_get_ems(
     mbedtls_ssl_config const *conf )
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 2749389..a050adb 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -394,7 +394,8 @@
 
         ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
                                         p + 2, end - p - 2, &kkpp_len,
-                                        ssl->conf->f_rng, ssl->conf->p_rng );
+                                        mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                        ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
@@ -751,14 +752,20 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
 #else
-    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf )
+          ( ssl->conf->p_rng, p, 4 ) ) != 0 )
+    {
         return( ret );
+    }
 
     p += 4;
 #endif /* MBEDTLS_HAVE_TIME */
 
-    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf )
+          ( ssl->conf->p_rng, p, 28 ) ) != 0 )
+    {
         return( ret );
+    }
 
     return( 0 );
 }
@@ -822,7 +829,7 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
 
-    if( ssl->conf->f_rng == NULL )
+    if( mbedtls_ssl_conf_get_frng( ssl->conf ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
         return( MBEDTLS_ERR_SSL_NO_RNG );
@@ -908,7 +915,8 @@
         ssl->session_negotiate->ticket != NULL &&
         ssl->session_negotiate->ticket_len != 0 )
     {
-        ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
+        ret = mbedtls_ssl_conf_get_frng( ssl->conf )
+            ( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
 
         if( ret != 0 )
             return( ret );
@@ -2333,7 +2341,8 @@
     mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
                        ssl->conf->transport, p );
 
-    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf )
+          ( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
         return( ret );
@@ -2382,7 +2391,8 @@
                             p, ssl->handshake->pmslen,
                             ssl->out_msg + offset + len_bytes, olen,
                             MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
-                            ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                            mbedtls_ssl_conf_get_frng( ssl->conf ),
+                            ssl->conf->p_rng ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
         goto cleanup;
@@ -3155,7 +3165,8 @@
         ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
                                 (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
                                &ssl->out_msg[i], n,
-                                ssl->conf->f_rng, ssl->conf->p_rng );
+                                mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
@@ -3169,7 +3180,8 @@
                                       ssl->handshake->premaster,
                                       MBEDTLS_PREMASTER_SIZE,
                                      &ssl->handshake->pmslen,
-                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                                      mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                      ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
             return( ret );
@@ -3206,7 +3218,8 @@
         ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
                                 &n,
                                 &ssl->out_msg[i], 1000,
-                                ssl->conf->f_rng, ssl->conf->p_rng );
+                                mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
@@ -3235,7 +3248,8 @@
                                       &ssl->handshake->pmslen,
                                        ssl->handshake->premaster,
                                        MBEDTLS_MPI_MAX_SIZE,
-                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                                       mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                       ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
@@ -3317,7 +3331,8 @@
             ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
                     (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
                     &ssl->out_msg[i], n,
-                    ssl->conf->f_rng, ssl->conf->p_rng );
+                    mbedtls_ssl_conf_get_frng( ssl->conf ),
+                    ssl->conf->p_rng );
             if( ret != 0 )
             {
                 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
@@ -3334,7 +3349,8 @@
              */
             ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
                     &ssl->out_msg[i], MBEDTLS_SSL_OUT_CONTENT_LEN - i,
-                    ssl->conf->f_rng, ssl->conf->p_rng );
+                    mbedtls_ssl_conf_get_frng( ssl->conf ),
+                    ssl->conf->p_rng );
             if( ret != 0 )
             {
                 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
@@ -3376,7 +3392,8 @@
 
         ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
                 ssl->out_msg + i, MBEDTLS_SSL_OUT_CONTENT_LEN - i, &n,
-                ssl->conf->f_rng, ssl->conf->p_rng );
+                mbedtls_ssl_conf_get_frng( ssl->conf ),
+                ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
@@ -3385,7 +3402,8 @@
 
         ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
                 ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
-                ssl->conf->f_rng, ssl->conf->p_rng );
+                mbedtls_ssl_conf_get_frng( ssl->conf ),
+                ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
@@ -3583,7 +3601,8 @@
     if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ),
                          md_alg, hash_start, hashlen,
                          ssl->out_msg + 6 + offset, &n,
-                         ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 )
+                         mbedtls_ssl_conf_get_frng( ssl->conf ),
+                         ssl->conf->p_rng, rs_ctx ) ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
 #if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index ccc32d7..4fab4ed 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2508,7 +2508,8 @@
 
     ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
                                         p + 2, end - p - 2, &kkpp_len,
-                                        ssl->conf->f_rng, ssl->conf->p_rng );
+                                        mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                        ssl->conf->p_rng );
     if( ret != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
@@ -2652,7 +2653,7 @@
     }
 #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
 
-    if( ssl->conf->f_rng == NULL )
+    if( mbedtls_ssl_conf_get_frng( ssl->conf ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
         return( MBEDTLS_ERR_SSL_NO_RNG );
@@ -2684,14 +2685,20 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
 #else
-    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf )
+          ( ssl->conf->p_rng, p, 4 ) ) != 0 )
+    {
         return( ret );
+    }
 
     p += 4;
 #endif /* MBEDTLS_HAVE_TIME */
 
-    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
+    if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf )
+          ( ssl->conf->p_rng, p, 28 ) ) != 0 )
+    {
         return( ret );
+    }
 
     p += 28;
 
@@ -2754,9 +2761,11 @@
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
         {
             ssl->session_negotiate->id_len = n = 32;
-            if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id,
-                                    n ) ) != 0 )
+            if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf )
+                  ( ssl->conf->p_rng, ssl->session_negotiate->id, n ) ) != 0 )
+            {
                 return( ret );
+            }
         }
     }
 
@@ -3160,7 +3169,8 @@
             &ssl->handshake->ecjpake_ctx,
             ssl->out_msg + ssl->out_msglen,
             MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len,
-            ssl->conf->f_rng, ssl->conf->p_rng );
+            mbedtls_ssl_conf_get_frng( ssl->conf ),
+            ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
@@ -3223,7 +3233,8 @@
                   &ssl->handshake->dhm_ctx,
                   (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
                   ssl->out_msg + ssl->out_msglen, &len,
-                  ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                  mbedtls_ssl_conf_get_frng( ssl->conf ),
+                  ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret );
             return( ret );
@@ -3278,7 +3289,8 @@
                   &ssl->handshake->ecdh_ctx, &len,
                   ssl->out_msg + ssl->out_msglen,
                   MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
-                  ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                  mbedtls_ssl_conf_get_frng( ssl->conf ),
+                  ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
             return( ret );
@@ -3462,7 +3474,7 @@
                                      md_alg, hash, hashlen,
                                      ssl->out_msg + ssl->out_msglen + 2,
                                      signature_len,
-                                     ssl->conf->f_rng,
+                                     mbedtls_ssl_conf_get_frng( ssl->conf ),
                                      ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
@@ -3759,7 +3771,8 @@
 
     ret = mbedtls_pk_decrypt( private_key, p, len,
                               peer_pms, peer_pmslen, peer_pmssize,
-                              ssl->conf->f_rng, ssl->conf->p_rng );
+                              mbedtls_ssl_conf_get_frng( ssl->conf ),
+                              ssl->conf->p_rng );
     return( ret );
 }
 
@@ -3828,7 +3841,8 @@
      * successful. In particular, always generate the fake premaster secret,
      * regardless of whether it will ultimately influence the output or not.
      */
-    ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
+    ret = mbedtls_ssl_conf_get_frng( ssl->conf )
+        ( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
     if( ret != 0 )
     {
         /* It's ok to abort on an RNG failure, since this does not reveal
@@ -3986,7 +4000,8 @@
                                       ssl->handshake->premaster,
                                       MBEDTLS_PREMASTER_SIZE,
                                      &ssl->handshake->pmslen,
-                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                                      mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                      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 );
@@ -4019,7 +4034,8 @@
                                       &ssl->handshake->pmslen,
                                        ssl->handshake->premaster,
                                        MBEDTLS_MPI_MAX_SIZE,
-                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                                       mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                       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 );
@@ -4175,7 +4191,8 @@
 
         ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
                 ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
-                ssl->conf->f_rng, ssl->conf->p_rng );
+                mbedtls_ssl_conf_get_frng( ssl->conf ),
+                ssl->conf->p_rng );
         if( ret != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 950d03d..84c78c4 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -81,11 +81,13 @@
  */
 static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
 {
-    if( ssl->f_set_timer == NULL )
+    if( mbedtls_ssl_get_set_timer( ssl ) == NULL )
         return;
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
-    ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
+    mbedtls_ssl_get_set_timer( ssl )( ssl->p_timer,
+                                           millisecs / 4,
+                                           millisecs );
 }
 
 /*
@@ -93,10 +95,10 @@
  */
 static int ssl_check_timer( mbedtls_ssl_context *ssl )
 {
-    if( ssl->f_get_timer == NULL )
+    if( mbedtls_ssl_get_get_timer( ssl ) == NULL )
         return( 0 );
 
-    if( ssl->f_get_timer( ssl->p_timer ) == 2 )
+    if( mbedtls_ssl_get_get_timer( ssl )( ssl->p_timer ) == 2 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
         return( -1 );
@@ -1623,7 +1625,8 @@
         /* Write length only when we know the actual value */
         if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
                                       p + 2, end - ( p + 2 ), &len,
-                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                                      mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                      ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
             return( ret );
@@ -1644,7 +1647,8 @@
 
         if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
                                        p + 2, end - ( p + 2 ),
-                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                                       mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                       ssl->conf->p_rng ) ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
             return( ret );
@@ -3062,7 +3066,8 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
 
-    if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
+    if( mbedtls_ssl_get_recv( ssl ) == NULL &&
+        mbedtls_ssl_get_recv_timeout( ssl ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
                             "or mbedtls_ssl_set_bio()" ) );
@@ -3081,7 +3086,8 @@
         uint32_t timeout;
 
         /* Just to be sure */
-        if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
+        if( mbedtls_ssl_get_set_timer( ssl ) == NULL ||
+            mbedtls_ssl_get_get_timer( ssl ) == NULL )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
                         "mbedtls_ssl_set_timer_cb() for DTLS" ) );
@@ -3164,11 +3170,16 @@
 
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
 
-            if( ssl->f_recv_timeout != NULL )
-                ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
-                                                                    timeout );
+            if( mbedtls_ssl_get_recv_timeout( ssl ) != NULL )
+            {
+                ret = mbedtls_ssl_get_recv_timeout( ssl )
+                    ( ssl->p_bio, ssl->in_hdr, len, timeout );
+            }
             else
-                ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
+            {
+                ret = mbedtls_ssl_get_recv( ssl )
+                    ( ssl->p_bio, ssl->in_hdr, len );
+            }
 
             MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
 
@@ -3233,15 +3244,15 @@
                 ret = MBEDTLS_ERR_SSL_TIMEOUT;
             else
             {
-                if( ssl->f_recv_timeout != NULL )
+                if( mbedtls_ssl_get_recv_timeout( ssl ) != NULL )
                 {
-                    ret = ssl->f_recv_timeout( ssl->p_bio,
-                             ssl->in_hdr + ssl->in_left, len,
-                             mbedtls_ssl_conf_get_read_timeout( ssl->conf ) );
+                    ret = mbedtls_ssl_get_recv_timeout( ssl )( ssl->p_bio,
+                       ssl->in_hdr + ssl->in_left, len,
+                       mbedtls_ssl_conf_get_read_timeout( ssl->conf ) );
                 }
                 else
                 {
-                    ret = ssl->f_recv( ssl->p_bio,
+                    ret = mbedtls_ssl_get_recv( ssl )( ssl->p_bio,
                                        ssl->in_hdr + ssl->in_left, len );
                 }
             }
@@ -3284,7 +3295,7 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
 
-    if( ssl->f_send == NULL )
+    if( mbedtls_ssl_get_send( ssl ) == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
                             "or mbedtls_ssl_set_bio()" ) );
@@ -3304,7 +3315,7 @@
                        mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
 
         buf = ssl->out_hdr - ssl->out_left;
-        ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
+        ret = mbedtls_ssl_get_send( ssl )( ssl->p_bio, buf, ssl->out_left );
 
         MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
 
@@ -3941,7 +3952,8 @@
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 
             if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec,
-                                         ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+                                         mbedtls_ssl_conf_get_frng( ssl->conf ),
+                                         ssl->conf->p_rng ) ) != 0 )
             {
                 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
                 return( ret );
@@ -4578,7 +4590,7 @@
         /* Don't check write errors as we can't do anything here.
          * If the error is permanent we'll catch it later,
          * if it's not, then hopefully it'll work next time. */
-        (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+        (void) mbedtls_ssl_get_send( ssl )( ssl->p_bio, ssl->out_buf, len );
 
         return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
     }
@@ -8185,6 +8197,7 @@
 }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
+#if !defined(MBEDTLS_SSL_CONF_RNG)
 void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
                   int (*f_rng)(void *, unsigned char *, size_t),
                   void *p_rng )
@@ -8192,6 +8205,13 @@
     conf->f_rng      = f_rng;
     conf->p_rng      = p_rng;
 }
+#else
+void mbedtls_ssl_conf_rng_ctx( mbedtls_ssl_config *conf,
+                               void *p_rng )
+{
+    conf->p_rng      = p_rng;
+}
+#endif
 
 void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
                   void (*f_dbg)(void *, int, const char *, int, const char *),
@@ -8201,17 +8221,27 @@
     conf->p_dbg      = p_dbg;
 }
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
 void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
         void *p_bio,
         mbedtls_ssl_send_t *f_send,
         mbedtls_ssl_recv_t *f_recv,
         mbedtls_ssl_recv_timeout_t *f_recv_timeout )
 {
-    ssl->p_bio          = p_bio;
-    ssl->f_send         = f_send;
-    ssl->f_recv         = f_recv;
+    ssl->p_bio = p_bio;
+    ssl->f_send = f_send;
+    ssl->f_recv = f_recv;
     ssl->f_recv_timeout = f_recv_timeout;
 }
+#else
+void mbedtls_ssl_set_bio_ctx( mbedtls_ssl_context *ssl,
+                              void *p_bio )
+{
+    ssl->p_bio = p_bio;
+}
+#endif
 
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
 void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu )
@@ -8227,6 +8257,8 @@
 }
 #endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */
 
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \
+    !defined(MBEDTLS_SSL_CONF_GET_TIMER)
 void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
                                void *p_timer,
                                mbedtls_ssl_set_timer_t *f_set_timer,
@@ -8235,10 +8267,18 @@
     ssl->p_timer        = p_timer;
     ssl->f_set_timer    = f_set_timer;
     ssl->f_get_timer    = f_get_timer;
-
     /* Make sure we start with no timer running */
     ssl_set_timer( ssl, 0 );
 }
+#else
+void mbedtls_ssl_set_timer_cb_ctx( mbedtls_ssl_context *ssl,
+                               void *p_timer )
+{
+    ssl->p_timer        = p_timer;
+    /* Make sure we start with no timer running */
+    ssl_set_timer( ssl, 0 );
+}
+#endif
 
 #if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE)
 void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
@@ -9990,8 +10030,8 @@
     while( ssl->in_offt == NULL )
     {
         /* Start timer if not already running */
-        if( ssl->f_get_timer != NULL &&
-            ssl->f_get_timer( ssl->p_timer ) == -1 )
+        if( mbedtls_ssl_get_get_timer( ssl ) != NULL &&
+            mbedtls_ssl_get_get_timer( ssl )( ssl->p_timer ) == -1 )
         {
             ssl_set_timer( ssl,
                            mbedtls_ssl_conf_get_read_timeout( ssl->conf ) );
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index cb2851b..700e197 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -205,11 +205,23 @@
         goto exit;
     }
 
-    mbedtls_ssl_set_bio( &ssl, &server_fd,
-                         mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout );
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
+    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+#else
+     mbedtls_ssl_set_bio_ctx( &ssl, &server_fd );
+#endif
 
+#if defined(MBEDTLS_TIMING_C)
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \
+    !defined(MBEDTLS_SSL_CONF_GET_TIMER)
     mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
                                             mbedtls_timing_get_delay );
+#else
+    mbedtls_ssl_set_timer_cb_ctx( &ssl, &timer );
+#endif
+#endif
 
     mbedtls_printf( " ok\n" );
 
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index 7d19d69..e238a95 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -254,8 +254,14 @@
         goto exit;
     }
 
-    mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
-                                            mbedtls_timing_get_delay );
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \
+    !defined(MBEDTLS_SSL_CONF_GET_TIMER)
+    mbedtls_ssl_set_timer_cb( &ssl, &timer,
+                              mbedtls_timing_set_delay,
+                              mbedtls_timing_get_delay );
+#else
+    mbedtls_ssl_set_timer_cb_ctx( &ssl, &timer );
+#endif
 
     printf( " ok\n" );
 
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 4b8140e..4231c0c 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -209,7 +209,11 @@
         goto exit;
     }
 
+#if !defined(MBEDTLS_SSL_CONF_RNG)
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+#else
+    mbedtls_ssl_conf_rng_ctx( &conf, &ctr_drbg );
+#endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
     mbedtls_ssl_conf_psk( &conf, psk, sizeof( psk ),
@@ -265,7 +269,13 @@
         goto exit;
     }
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
     mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+#else
+     mbedtls_ssl_set_bio_ctx( &ssl, &server_fd );
+#endif
 
     if( mbedtls_ssl_handshake( &ssl ) != 0 )
     {
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index 419be6b..cda71fd 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -2706,6 +2706,54 @@
     }
 #endif /* MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */
 
+#if defined(MBEDTLS_SSL_CONF_GET_TIMER)
+    if( strcmp( "MBEDTLS_SSL_CONF_GET_TIMER", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_GET_TIMER );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_GET_TIMER */
+
+#if defined(MBEDTLS_SSL_CONF_SET_TIMER)
+    if( strcmp( "MBEDTLS_SSL_CONF_SET_TIMER", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SET_TIMER );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_SET_TIMER */
+
+#if defined(MBEDTLS_SSL_CONF_RECV)
+    if( strcmp( "MBEDTLS_SSL_CONF_RECV", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_RECV );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_RECV */
+
+#if defined(MBEDTLS_SSL_CONF_SEND)
+    if( strcmp( "MBEDTLS_SSL_CONF_SEND", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_SEND );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_SEND */
+
+#if defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
+    if( strcmp( "MBEDTLS_SSL_CONF_RECV_TIMEOUT", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_RECV_TIMEOUT );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_RECV_TIMEOUT */
+
+#if defined(MBEDTLS_SSL_CONF_RNG)
+    if( strcmp( "MBEDTLS_SSL_CONF_RNG", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_RNG );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_RNG */
+
 #if defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
     if( strcmp( "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET", config ) == 0 )
     {
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 8d7ee0a..c63b445 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -466,6 +466,10 @@
     fflush(  (FILE *) ctx  );
 }
 
+
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
 /*
  * Test recv/send functions that make sure each try returns
  * WANT_READ/WANT_WRITE at least once before sucesseding
@@ -503,6 +507,9 @@
         first_try = 1; /* Next call will be a new operation */
     return( ret );
 }
+#endif /* MBEDTLS_SSL_CONF_RECV &&
+          MBEDTLS_SSL_CONF_SEND &&
+          MBEDTLS_SSL_CONF_RECV_TIMEOUT */
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 static unsigned char peer_crt_info[1024];
@@ -1764,7 +1771,12 @@
         }
 #endif
 
+#if !defined(MBEDTLS_SSL_CONF_RNG)
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+#else
+    mbedtls_ssl_conf_rng_ctx( &conf, &ctr_drbg );
+#endif
+
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
 #if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT)
@@ -1871,12 +1883,18 @@
     }
 #endif
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
     if( opt.nbio == 2 )
         mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL );
     else
         mbedtls_ssl_set_bio( &ssl, &server_fd,
                              mbedtls_net_send, mbedtls_net_recv,
                              opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
+#else
+     mbedtls_ssl_set_bio_ctx( &ssl, &server_fd );
+#endif
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
@@ -1897,8 +1915,13 @@
 #endif
 
 #if defined(MBEDTLS_TIMING_C)
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \
+    !defined(MBEDTLS_SSL_CONF_GET_TIMER)
     mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
                                             mbedtls_timing_get_delay );
+#else
+    mbedtls_ssl_set_timer_cb_ctx( &ssl, &timer );
+#endif
 #endif
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -2489,9 +2512,16 @@
 
 #if defined(MBEDTLS_TIMING_C)
             if( opt.nbio != 0 && opt.read_timeout != 0 )
+            {
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \
+    !defined(MBEDTLS_SSL_CONF_GET_TIMER)
                 mbedtls_ssl_set_timer_cb( &ssl, &timer,
                                           mbedtls_timing_set_delay,
                                           mbedtls_timing_get_delay );
+#else
+                mbedtls_ssl_set_timer_cb_ctx( &ssl, &timer );
+#endif
+            }
 #endif /* MBEDTLS_TIMING_C */
         }
 
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 5135ad4..876a7a0 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -597,6 +597,10 @@
     fflush(  (FILE *) ctx  );
 }
 
+
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
 /*
  * Test recv/send functions that make sure each try returns
  * WANT_READ/WANT_WRITE at least once before sucesseding
@@ -634,6 +638,9 @@
         first_try = 1; /* Next call will be a new operation */
     return( ret );
 }
+#endif /* MBEDTLS_SSL_CONF_RECV &&
+          MBEDTLS_SSL_CONF_SEND &&
+          MBEDTLS_SSL_CONF_RECV_TIMEOUT */
 
 #if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
 /*
@@ -2570,7 +2577,12 @@
         }
 #endif
 
+#if !defined(MBEDTLS_SSL_CONF_RNG)
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+#else
+    mbedtls_ssl_conf_rng_ctx( &conf, &ctr_drbg );
+#endif
+
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
 
 #if defined(MBEDTLS_SSL_CACHE_C)
@@ -2854,11 +2866,18 @@
         goto exit;
     }
 
+#if !defined(MBEDTLS_SSL_CONF_RECV) && \
+    !defined(MBEDTLS_SSL_CONF_SEND) && \
+    !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
     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,
+        mbedtls_ssl_set_bio( &ssl, &client_fd,
+                             mbedtls_net_send, mbedtls_net_recv,
                              opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
+#else
+     mbedtls_ssl_set_bio_ctx( &ssl, &client_fd );
+#endif
 
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
     if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
@@ -2879,8 +2898,13 @@
 #endif
 
 #if defined(MBEDTLS_TIMING_C)
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \
+    !defined(MBEDTLS_SSL_CONF_GET_TIMER)
     mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
                                             mbedtls_timing_get_delay );
+#else
+    mbedtls_ssl_set_timer_cb_ctx( &ssl, &timer );
+#endif
 #endif
 
     mbedtls_printf( " ok\n" );
@@ -3496,9 +3520,16 @@
 
 #if defined(MBEDTLS_TIMING_C)
             if( opt.nbio != 0 && opt.read_timeout != 0 )
+            {
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER) && \
+    !defined(MBEDTLS_SSL_CONF_GET_TIMER)
                 mbedtls_ssl_set_timer_cb( &ssl, &timer,
                                           mbedtls_timing_set_delay,
                                           mbedtls_timing_get_delay );
+#else
+                mbedtls_ssl_set_timer_cb_ctx( &ssl, &timer );
+#endif
+            }
 #endif /* MBEDTLS_TIMING_C */
         }