@ -96,8 +96,6 @@ extern const struct altcp_functions altcp_mbedtls_functions;
/** Our global mbedTLS configuration (server-specific, not connection-specific) */
struct altcp_tls_config {
mbedtls_ssl_config conf ;
mbedtls_entropy_context entropy ;
mbedtls_ctr_drbg_context ctr_drbg ;
mbedtls_x509_crt * cert ;
mbedtls_pk_context * pkey ;
uint8_t cert_count ;
@ -114,6 +112,14 @@ struct altcp_tls_config {
# endif
} ;
/** Entropy and random generator are shared by all mbedTLS configuration */
struct altcp_tls_entropy_rng {
mbedtls_entropy_context entropy ;
mbedtls_ctr_drbg_context ctr_drbg ;
int ref ;
} ;
static struct altcp_tls_entropy_rng * altcp_tls_entropy_rng ;
static err_t altcp_mbedtls_lower_recv ( void * arg , struct altcp_pcb * inner_conn , struct pbuf * p , err_t err ) ;
static err_t altcp_mbedtls_setup ( void * conf , struct altcp_pcb * conn , struct altcp_pcb * inner_conn ) ;
static err_t altcp_mbedtls_lower_recv_process ( struct altcp_pcb * conn , altcp_mbedtls_state_t * state ) ;
@ -706,15 +712,32 @@ altcp_tls_create_config(int is_server, uint8_t cert_count, uint8_t pkey_count, i
}
mbedtls_ssl_config_init ( & conf - > conf ) ;
mbedtls_entropy_init ( & conf - > entropy ) ;
mbedtls_ctr_drbg_init ( & conf - > ctr_drbg ) ;
/* Seed the RNG */
ret = mbedtls_ctr_drbg_seed ( & conf - > ctr_drbg , mbedtls_entropy_func , & conf - > entropy , ALTCP_MBEDTLS_ENTROPY_PTR , ALTCP_MBEDTLS_ENTROPY_LEN ) ;
if ( ret ! = 0 ) {
LWIP_DEBUGF ( ALTCP_MBEDTLS_DEBUG , ( " mbedtls_ctr_drbg_seed failed: %d \n " , ret ) ) ;
altcp_mbedtls_free_config ( conf ) ;
return NULL ;
if ( ! altcp_tls_entropy_rng ) {
altcp_tls_entropy_rng = ( struct altcp_tls_entropy_rng * ) altcp_mbedtls_alloc_config ( sizeof ( struct altcp_tls_entropy_rng ) ) ;
if ( altcp_tls_entropy_rng ) {
altcp_tls_entropy_rng - > ref = 1 ;
mbedtls_entropy_init ( & altcp_tls_entropy_rng - > entropy ) ;
mbedtls_ctr_drbg_init ( & altcp_tls_entropy_rng - > ctr_drbg ) ;
/* Seed the RNG, only once */
ret = mbedtls_ctr_drbg_seed ( & altcp_tls_entropy_rng - > ctr_drbg ,
mbedtls_entropy_func , & altcp_tls_entropy_rng - > entropy ,
ALTCP_MBEDTLS_ENTROPY_PTR , ALTCP_MBEDTLS_ENTROPY_LEN ) ;
if ( ret ! = 0 ) {
LWIP_DEBUGF ( ALTCP_MBEDTLS_DEBUG , ( " mbedtls_ctr_drbg_seed failed: %d \n " , ret ) ) ;
mbedtls_ctr_drbg_free ( & altcp_tls_entropy_rng - > ctr_drbg ) ;
mbedtls_entropy_free ( & altcp_tls_entropy_rng - > entropy ) ;
altcp_mbedtls_free_config ( altcp_tls_entropy_rng ) ;
altcp_tls_entropy_rng = NULL ;
altcp_mbedtls_free_config ( conf ) ;
return NULL ;
}
} else {
altcp_mbedtls_free_config ( conf ) ;
return NULL ;
}
} else {
altcp_tls_entropy_rng - > ref + + ;
}
/* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */
@ -722,12 +745,18 @@ altcp_tls_create_config(int is_server, uint8_t cert_count, uint8_t pkey_count, i
MBEDTLS_SSL_TRANSPORT_STREAM , MBEDTLS_SSL_PRESET_DEFAULT ) ;
if ( ret ! = 0 ) {
LWIP_DEBUGF ( ALTCP_MBEDTLS_DEBUG , ( " mbedtls_ssl_config_defaults failed: %d \n " , ret ) ) ;
if ( altcp_tls_entropy_rng - > ref = = 1 ) {
mbedtls_ctr_drbg_free ( & altcp_tls_entropy_rng - > ctr_drbg ) ;
mbedtls_entropy_free ( & altcp_tls_entropy_rng - > entropy ) ;
altcp_mbedtls_free_config ( altcp_tls_entropy_rng ) ;
altcp_tls_entropy_rng = NULL ;
}
altcp_mbedtls_free_config ( conf ) ;
return NULL ;
}
mbedtls_ssl_conf_authmode ( & conf - > conf , MBEDTLS_SSL_VERIFY_OPTIONAL ) ;
mbedtls_ssl_conf_rng ( & conf - > conf , mbedtls_ctr_drbg_random , & conf - > ctr_drbg ) ;
mbedtls_ssl_conf_rng ( & conf - > conf , mbedtls_ctr_drbg_random , & altcp_tls_entropy_rng - > ctr_drbg ) ;
# if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF
mbedtls_ssl_conf_dbg ( & conf - > conf , altcp_mbedtls_debug , stdout ) ;
# endif
@ -740,7 +769,7 @@ altcp_tls_create_config(int is_server, uint8_t cert_count, uint8_t pkey_count, i
# if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS
mbedtls_ssl_ticket_init ( & conf - > ticket_ctx ) ;
ret = mbedtls_ssl_ticket_setup ( & conf - > ticket_ctx , mbedtls_ctr_drbg_random , & conf - > ctr_drbg ,
ret = mbedtls_ssl_ticket_setup ( & conf - > ticket_ctx , mbedtls_ctr_drbg_random , & altcp_tls_entropy_rng - > ctr_drbg ,
ALTCP_MBEDTLS_SESSION_TICKET_CIPHER , ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS ) ;
if ( ret ) {
LWIP_DEBUGF ( ALTCP_MBEDTLS_DEBUG , ( " mbedtls_ssl_ticket_setup failed: %d \n " , ret ) ) ;
@ -752,7 +781,6 @@ altcp_tls_create_config(int is_server, uint8_t cert_count, uint8_t pkey_count, i
& conf - > ticket_ctx ) ;
# endif
return conf ;
}
@ -929,6 +957,19 @@ altcp_tls_free_config(struct altcp_tls_config *conf)
mbedtls_x509_crt_free ( conf - > ca ) ;
}
altcp_mbedtls_free_config ( conf ) ;
if ( altcp_tls_entropy_rng & & altcp_tls_entropy_rng - > ref )
altcp_tls_entropy_rng - > ref - - ;
}
void
altcp_tls_free_entropy ( void )
{
if ( altcp_tls_entropy_rng & & altcp_tls_entropy_rng - > ref = = 0 ) {
mbedtls_ctr_drbg_free ( & altcp_tls_entropy_rng - > ctr_drbg ) ;
mbedtls_entropy_free ( & altcp_tls_entropy_rng - > entropy ) ;
altcp_mbedtls_free_config ( altcp_tls_entropy_rng ) ;
altcp_tls_entropy_rng = NULL ;
}
}
/* "virtual" functions */