diff --git a/configs/baremetal.h b/configs/baremetal.h index a6da5c361..d6ce9a302 100644 --- a/configs/baremetal.h +++ b/configs/baremetal.h @@ -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 diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 764fba4b4..29d9906ff 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 597f2a33d..a767cb298 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 7364dc497..671d10766 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -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) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 52835b49c..8d5170c27 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -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); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 8c24ee995..847ac711a 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -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 ) diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c index cb2851b8c..6f508ae16 100644 --- a/programs/ssl/dtls_client.c +++ b/programs/ssl/dtls_client.c @@ -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 ); diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c index 18e11d0a6..4231c0c8f 100644 --- a/programs/ssl/mini_client.c +++ b/programs/ssl/mini_client.c @@ -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 ) { diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index 6d2b67bbe..a4881df66 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -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 ) { diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index a4af97a5b..695cc6a97 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -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 ) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 2704d4efe..916a64224 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -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 )