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 |
This commit is contained in:
Hanno Becker 2019-06-13 16:11:15 +01:00
parent ece325c8dd
commit a58a896172
11 changed files with 218 additions and 21 deletions

View file

@ -93,6 +93,9 @@
#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_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

View file

@ -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

View file

@ -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),

View file

@ -1146,9 +1146,15 @@ struct mbedtls_ssl_context
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 mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
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 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
* \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 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
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)

View file

@ -1291,8 +1291,68 @@ static inline unsigned int mbedtls_ssl_conf_get_anti_replay(
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 @@ static inline mbedtls_frng_t mbedtls_ssl_conf_get_frng(
#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);

View file

@ -3064,7 +3064,8 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
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()" ) );
@ -3166,11 +3167,16 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
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 );
@ -3235,15 +3241,15 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
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 );
}
}
@ -3286,7 +3292,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
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()" ) );
@ -3306,7 +3312,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
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 );
@ -4581,7 +4587,7 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
/* 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 );
}
@ -8212,17 +8218,27 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
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 )

View file

@ -205,8 +205,13 @@ int main( int argc, char *argv[] )
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
mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
mbedtls_timing_get_delay );

View file

@ -269,7 +269,13 @@ int main( void )
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 )
{

View file

@ -2706,6 +2706,30 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */
#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 )
{

View file

@ -466,6 +466,10 @@ static void my_debug( void *ctx, int level,
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 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
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];
@ -1876,12 +1883,18 @@ int main( int argc, char *argv[] )
}
#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 )

View file

@ -597,6 +597,10 @@ static void my_debug( void *ctx, int level,
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 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
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)
/*
@ -2859,11 +2866,18 @@ int main( int argc, char *argv[] )
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 )