Allow compile-time configuration of I/O function pointers
Introduce the compile-time options
- MBEDTLS_SSL_CONF_RECV
- MBEDTLS_SSL_CONF_SEND
- MBEDTLS_SSL_CONF_RECV_TIMEOUT
which can be used to configure the callbacks for the underlying
transport at compile-time.
Code-size impact:
| | GCC 8.2.1 | ARMC5 5.06 | ARMC6 6.12 |
| --- | --- | --- | --- |
| `libmbedtls.a` before | 23471 | 24077 | 27045 |
| `libmbedtls.a` before | 23379 | 23981 | 26941 |
| gain in Bytes | 92 | 96 | 104 |
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 764fba4..29d9906 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -671,6 +671,18 @@
#define "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) ) )
+#define "MBEDTLS_SSL_CONF_SEND/RECV/RECV_TIMEOUT must be defined simultaneously"
+#endif
+
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
#endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 597f2a3..a767cb2 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -3601,6 +3601,22 @@
//#define MBEDTLS_SSL_CONF_CID_LEN 0
//#define MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID MBEDTLS_SSL_UNEXPECTED_CID_IGNORE
+/* 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),
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 7364dc4..671d107 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1146,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 */
@@ -1510,6 +1516,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.
@@ -1535,6 +1544,13 @@
* \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. In this case, the
+ * corresponding parameters to this function don't take
+ * any effect.
+ *
* \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
@@ -1545,6 +1561,18 @@
mbedtls_ssl_send_t *f_send,
mbedtls_ssl_recv_t *f_recv,
mbedtls_ssl_recv_timeout_t *f_recv_timeout );
+#else
+/**
+ * \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
#if defined(MBEDTLS_SSL_PROTO_DTLS)
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 52835b4..8d5170c 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1291,8 +1291,68 @@
typedef int (*mbedtls_frng_t)( void*, unsigned char*, size_t );
+#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(
+static inline mbedtls_frng_t* mbedtls_ssl_conf_get_frng(
mbedtls_ssl_config const *conf )
{
return( conf->f_rng );
@@ -1302,7 +1362,7 @@
#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(
+static inline mbedtls_frng_t* mbedtls_ssl_conf_get_frng(
mbedtls_ssl_config const *conf )
{
((void) conf);