diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h index ca06dc3c5..52cb6a0e5 100644 --- a/include/mbedtls/entropy.h +++ b/include/mbedtls/entropy.h @@ -83,8 +83,8 @@ #define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ #define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES -#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */ -#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */ +#define MBEDTLS_ENTROPY_SOURCE_STRONG 0x7F /**< Entropy source is strong */ +#define MBEDTLS_ENTROPY_SOURCE_WEAK 0x0 /**< Entropy source is weak */ #ifdef __cplusplus extern "C" { diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 8008b516b..e14f58f71 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -125,8 +125,13 @@ #define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 /**< DTLS client must retry for hello verification */ #define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 /**< A buffer is too small to receive or write a message */ #define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6980 /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */ -#define MBEDTLS_ERR_SSL_WANT_READ -0x6900 /**< No data of requested type currently available on underlying transport. */ -#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */ +/* + * MBEDTLS_ERR_SSL_WANT_READ and MBEDTLS_ERR_SSL_WANT_WRITE are dismissable errors, + * therefore the hamming distance to other non-dismissable errors should be + * large to prevent bit-flipping a non-dismissable error to dismissable. + */ +#define MBEDTLS_ERR_SSL_WANT_READ -0xFF6900 /**< No data of requested type currently available on underlying transport. */ +#define MBEDTLS_ERR_SSL_WANT_WRITE -0xFF6880 /**< Connection requires a write call. */ #define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */ #define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 /**< The client initiated a reconnect from the same port. */ #define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 /**< Record header looks valid but is not expected. */ @@ -191,10 +196,10 @@ #define MBEDTLS_SSL_COMPRESS_NULL 0 #define MBEDTLS_SSL_COMPRESS_DEFLATE 1 -#define MBEDTLS_SSL_VERIFY_NONE 0 -#define MBEDTLS_SSL_VERIFY_OPTIONAL 1 -#define MBEDTLS_SSL_VERIFY_REQUIRED 2 -#define MBEDTLS_SSL_VERIFY_UNSET 3 /* Used only for sni_authmode */ +#define MBEDTLS_SSL_VERIFY_NONE 0x0 +#define MBEDTLS_SSL_VERIFY_OPTIONAL 0xf +#define MBEDTLS_SSL_VERIFY_REQUIRED 0x33 +#define MBEDTLS_SSL_VERIFY_UNSET 0x3c /* Used only for sni_authmode */ #define MBEDTLS_SSL_LEGACY_RENEGOTIATION 0 #define MBEDTLS_SSL_SECURE_RENEGOTIATION 1 @@ -564,25 +569,26 @@ extern "C" { */ typedef enum { - MBEDTLS_SSL_HELLO_REQUEST, - MBEDTLS_SSL_CLIENT_HELLO, - MBEDTLS_SSL_SERVER_HELLO, - MBEDTLS_SSL_SERVER_CERTIFICATE, - MBEDTLS_SSL_SERVER_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_REQUEST, - MBEDTLS_SSL_SERVER_HELLO_DONE, - MBEDTLS_SSL_CLIENT_CERTIFICATE, - MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_VERIFY, - MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_CLIENT_FINISHED, - MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_SERVER_FINISHED, - MBEDTLS_SSL_FLUSH_BUFFERS, - MBEDTLS_SSL_HANDSHAKE_WRAPUP, - MBEDTLS_SSL_HANDSHAKE_OVER, - MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET, - MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, + MBEDTLS_SSL_HELLO_REQUEST = 0x0, + MBEDTLS_SSL_CLIENT_HELLO = 0x0000FFFF, + MBEDTLS_SSL_SERVER_HELLO = 0x00FF00FF, + MBEDTLS_SSL_SERVER_CERTIFICATE = 0x00FFFF00, + MBEDTLS_SSL_SERVER_KEY_EXCHANGE = 0x0F0F0F0F, + MBEDTLS_SSL_CERTIFICATE_REQUEST = 0x0F0FF0F0, + MBEDTLS_SSL_SERVER_HELLO_DONE = 0x0FF00FF0, + MBEDTLS_SSL_CLIENT_CERTIFICATE = 0x0FF0F00F, + MBEDTLS_SSL_CLIENT_KEY_EXCHANGE = 0x33333333, + MBEDTLS_SSL_CERTIFICATE_VERIFY = 0x3333CCCC, + MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC = 0x33CC33CC, + MBEDTLS_SSL_CLIENT_FINISHED = 0x33CCCC33, + MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC = 0x3C3C3C3C, + MBEDTLS_SSL_SERVER_FINISHED = 0x3C3CC3C3, + MBEDTLS_SSL_FLUSH_BUFFERS = 0x3CC33CC3, + MBEDTLS_SSL_HANDSHAKE_WRAPUP = 0x3CC3C33C, + MBEDTLS_SSL_HANDSHAKE_OVER = 0x55555555, + MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET = 0x5555AAAA, + MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT = 0x55AA55AA, + MBEDTLS_SSL_INVALID = 0x55AAAA55 } mbedtls_ssl_states; @@ -1196,7 +1202,7 @@ struct mbedtls_ssl_config #endif /* !MBEDTLS_SSL_CONF_ENDPOINT */ unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */ #if !defined(MBEDTLS_SSL_CONF_AUTHMODE) - unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */ + unsigned int authmode : 6; /*!< MBEDTLS_SSL_VERIFY_XXX */ #endif /* !MBEDTLS_SSL_CONF_AUTHMODE */ #if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 4872f6fb5..19328d88f 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -226,6 +226,9 @@ : ( MBEDTLS_SSL_IN_CONTENT_LEN ) \ ) +#define MBEDTLS_SSL_FI_FLAG_UNSET 0x0 +#define MBEDTLS_SSL_FI_FLAG_SET 0x7F + /* * Check that we obey the standard's message size bounds */ @@ -385,6 +388,10 @@ struct mbedtls_ssl_handshake_params #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) uint8_t got_peer_pubkey; /*!< Did we store the peer's public key from its certificate? */ #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + volatile uint8_t peer_authenticated; /*!< Is the peer authenticated? */ + volatile uint8_t hello_random_set; /*!< Has the hello random been set? */ + volatile uint8_t key_derivation_done; /*!< Has the key derivation been done? */ + volatile uint8_t premaster_generated; /*!< Has the PMS been generated? */ #if defined(MBEDTLS_SSL_PROTO_DTLS) unsigned char verify_cookie_len; /*!< Cli: cookie length Srv: flag for sending a cookie */ @@ -506,7 +513,7 @@ struct mbedtls_ssl_handshake_params #endif /* !MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE */ #if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - int resume; /*!< session resume indicator*/ + volatile int resume; /*!< session resume indicator*/ #endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ #if defined(MBEDTLS_SSL_SRV_C) && \ @@ -905,7 +912,7 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ); int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ); int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ); int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ); diff --git a/library/entropy.c b/library/entropy.c index 75421cfb2..b4d1f2921 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -43,9 +43,7 @@ #include #endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) #include "mbedtls/platform.h" -#endif #if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_PLATFORM_C) @@ -258,7 +256,9 @@ int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, */ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) { - int ret, i, have_one_strong = 0; + int i; + volatile int ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE; + volatile int have_one_strong_fi = MBEDTLS_ENTROPY_SOURCE_WEAK; unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; size_t olen; @@ -270,8 +270,16 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) */ for( i = 0; i < ctx->source_count; i++ ) { - if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG ) - have_one_strong = 1; + volatile int strong_fi = ctx->source[i].strong; + if( strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG ) + { + mbedtls_platform_enforce_volatile_reads(); + + if( strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG ) + have_one_strong_fi = MBEDTLS_ENTROPY_SOURCE_STRONG; + else + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } olen = 0; if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, @@ -292,13 +300,24 @@ static int entropy_gather_internal( mbedtls_entropy_context *ctx ) } } - if( have_one_strong == 0 ) - ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE; - cleanup: mbedtls_platform_zeroize( buf, sizeof( buf ) ); - return( ret ); + if( have_one_strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG ) + { + mbedtls_platform_enforce_volatile_reads(); + if( have_one_strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG ) + { + return( ret ); + } + else + { + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } + + } + + return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE ); } /* diff --git a/library/pk.c b/library/pk.c index dfdd4d143..27276a829 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1515,6 +1515,7 @@ int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, const unsigned char *sig, size_t sig_len, mbedtls_pk_restart_ctx *rs_ctx ) { + volatile int verify_ret = MBEDTLS_ERR_PK_HW_ACCEL_FAILED; PK_VALIDATE_RET( ctx != NULL ); PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || hash != NULL ); @@ -1547,8 +1548,23 @@ int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, (void) rs_ctx; #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - return( pk_info_verify_func( MBEDTLS_PK_CTX_INFO( ctx ), - ctx->pk_ctx, md_alg, hash, hash_len, sig, sig_len ) ); + verify_ret = pk_info_verify_func( MBEDTLS_PK_CTX_INFO( ctx ), + ctx->pk_ctx, md_alg, hash, hash_len, sig, sig_len ); + + if( verify_ret == 0 ) + { + mbedtls_platform_enforce_volatile_reads(); + if( verify_ret == 0 ) + { + return( verify_ret ); + } + else + { + verify_ret = MBEDTLS_ERR_PK_HW_ACCEL_FAILED; + } + } + + return( verify_ret ); } /* diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 7c03b41f9..479554d78 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -687,7 +687,7 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_HAVE_TIME) mbedtls_time_t t; #endif - + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; /* * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1) */ @@ -713,13 +713,19 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl ) p += 4; #endif /* MBEDTLS_HAVE_TIME */ - if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), p, 28 ) ) != 0 ) + ret = mbedtls_ssl_conf_get_frng( ssl->conf ) + ( mbedtls_ssl_conf_get_prng( ssl->conf ), p, 28 ); + if( ret == 0 ) { - return( ret ); + mbedtls_platform_enforce_volatile_reads(); + if( ret == 0 ) + { + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; + return( 0 ); + } } - return( 0 ); + return( ret ); } /** @@ -862,7 +868,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) * appropriate length. Otherwise make the length 0 (for now, see next code * block for behaviour with tickets). */ - if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == 0 || + if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == MBEDTLS_SSL_FI_FLAG_UNSET || mbedtls_ssl_get_renego_status( ssl ) != MBEDTLS_SSL_INITIAL_HANDSHAKE || ssl->session_negotiate->id_len < 16 || ssl->session_negotiate->id_len > 32 ) @@ -1116,7 +1122,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO; - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_HELLO; #if defined(MBEDTLS_SSL_PROTO_DTLS) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) @@ -1719,8 +1725,15 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", (unsigned long)mbedtls_platform_get_uint32_be( &buf[2] ) ) ); + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; + mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 ); + if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32, buf + 2, 32 ) == 0 ) + { + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; + } + n = buf[34]; MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 ); @@ -1819,11 +1832,11 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->session_negotiate->id_len != n || mbedtls_platform_memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 ) { - ssl->handshake->resume = 0; + ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_UNSET; } #endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ - if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == 1 ) + if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == MBEDTLS_SSL_FI_FLAG_SET ) { /* Resume a session */ ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; @@ -1839,7 +1852,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) else { /* Start a new session */ - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_CERTIFICATE; #if defined(MBEDTLS_HAVE_TIME) ssl->session_negotiate->start = mbedtls_time( NULL ); #endif @@ -2329,7 +2342,7 @@ static int ssl_rsa_generate_partial_pms( mbedtls_ssl_context *ssl, unsigned char* out, unsigned add_length_tag ) { - int ret; + volatile int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; /* * Generate (part of) the pre-master secret as @@ -2351,14 +2364,21 @@ static int ssl_rsa_generate_partial_pms( mbedtls_ssl_context *ssl, mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ), ssl->conf->transport, out ); - if( ( ret = mbedtls_ssl_conf_get_frng( ssl->conf ) - ( mbedtls_ssl_conf_get_prng( ssl->conf ), out + 2, 46 ) ) != 0 ) + ret = mbedtls_ssl_conf_get_frng( ssl->conf ) + ( mbedtls_ssl_conf_get_prng( ssl->conf ), out + 2, 46 ); + + if( ret == 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret ); - return( ret ); + mbedtls_platform_enforce_volatile_reads(); + if( ret == 0 ) + { + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + return( 0 ); + } } - return( 0 ); + MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret ); + return( ret ); } /* @@ -2370,7 +2390,7 @@ static int ssl_rsa_encrypt_partial_pms( mbedtls_ssl_context *ssl, unsigned char *out, size_t buflen, size_t *olen ) { - int ret; + volatile int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; size_t len_bytes = mbedtls_ssl_get_minor_ver( ssl ) == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; mbedtls_pk_context *peer_pk = NULL; @@ -2414,16 +2434,27 @@ static int ssl_rsa_encrypt_partial_pms( mbedtls_ssl_context *ssl, goto cleanup; } - if( ( ret = mbedtls_pk_encrypt( peer_pk, + ret = mbedtls_pk_encrypt( peer_pk, ppms, 48, out + len_bytes, olen, buflen - len_bytes, mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) + mbedtls_ssl_conf_get_prng( ssl->conf ) ); + + if( ret == 0 ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ret == 0 ) + { + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + } + } + else { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); goto cleanup; } + #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) if( len_bytes == 2 ) @@ -2731,7 +2762,11 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, unsigned char *buf, size_t buflen ) { - int ret; + /* + * Initialising to an error value would need a significant + * structural change to provide default flow assumes failure + */ + volatile int ret = 0; unsigned char *p; unsigned char *end; @@ -3031,39 +3066,51 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl, rs_ctx = &ssl->handshake->ecrs_ctx.pk; #endif - if( ( ret = mbedtls_pk_verify_restartable( peer_pk, - md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 ) + ret = mbedtls_pk_verify_restartable( peer_pk, + md_alg, hash, hashlen, p, sig_len, rs_ctx ); + + if( ret == 0 ) { -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) -#endif + mbedtls_platform_enforce_volatile_reads(); + + if( ret == 0 ) { - mbedtls_ssl_pend_fatal_alert( ssl, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); +#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + /* We don't need the peer's public key anymore. Free it, + * so that more RAM is available for upcoming expensive + * operations like ECDHE. */ + mbedtls_pk_free( peer_pk ); +#else + mbedtls_x509_crt_pk_release( + ssl->session_negotiate->peer_cert ); +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + return( ret ); } + else + { + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + } +#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) + if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) +#endif + { + mbedtls_ssl_pend_fatal_alert( ssl, + MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); + } MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); #if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; + if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) + ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; #endif #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - return( ret ); - } -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it, - * so that more RAM is available for upcoming expensive - * operations like ECDHE. */ - mbedtls_pk_free( peer_pk ); -#else - mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ } #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - return( 0 ); + return( ret ); } static int ssl_in_server_key_exchange_postprocess( mbedtls_ssl_context *ssl ) @@ -3143,7 +3190,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; return( 0 ); } @@ -3165,7 +3212,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; return( 0 ); } @@ -3183,7 +3230,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request", @@ -3340,7 +3387,7 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); } - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CERTIFICATE; #if defined(MBEDTLS_SSL_PROTO_DTLS) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) @@ -3827,7 +3874,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; return( 0 ); } @@ -3866,14 +3913,14 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; return( 0 ); } if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; return( 0 ); } @@ -3997,7 +4044,7 @@ sign: ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) { @@ -4251,9 +4298,10 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - mbedtls_ssl_handshake_wrapup( ssl ); + ret = mbedtls_ssl_handshake_wrapup( ssl ); break; + case MBEDTLS_SSL_INVALID: default: MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 1ef8f9466..92d1da016 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -627,7 +627,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) ); - ssl->handshake->resume = 1; + ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_SET; /* Don't send a new ticket after all, this one is OK */ ssl->handshake->new_session_ticket = 0; @@ -1223,8 +1223,14 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) mbedtls_platform_memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len ); p += sess_len; + + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; memset( ssl->handshake->randbytes, 0, 64 ); mbedtls_platform_memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); + if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ) == 0 ) + { + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; + } /* * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV @@ -1360,7 +1366,7 @@ have_ciphersuite_v2: } ssl->in_left = 0; - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_HELLO; MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) ); @@ -1717,10 +1723,14 @@ read_record_header: /* * Save client random (inc. Unix time) */ + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 ); mbedtls_platform_memcpy( ssl->handshake->randbytes, buf + 2, 32 ); - + if( mbedtls_platform_memcmp( ssl->handshake->randbytes, buf + 2, 32 ) == 0 ) + { + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; + } /* * Check the session ID length and save session ID */ @@ -2298,7 +2308,7 @@ have_ciphersuite: mbedtls_ssl_get_ciphersuite_name( mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) ) ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_HELLO; #if defined(MBEDTLS_SSL_PROTO_DTLS) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) @@ -2814,8 +2824,12 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) } p += 28; - + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET; mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); + if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32, buf + 6, 32 ) == 0 ) + { + ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET; + } MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); @@ -2825,19 +2839,19 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) * It may be already set to 1 by ssl_parse_session_ticket_ext(). * If not, try looking up session ID in our cache. */ - if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == 0 && + if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == MBEDTLS_SSL_FI_FLAG_UNSET && mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE && ssl->session_negotiate->id_len != 0 && ssl->conf->f_get_cache != NULL && ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); - ssl->handshake->resume = 1; + ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_SET; } #endif /* !MBEDTLS_SSL_NO_SESSION_CACHE */ #if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == 1 ) + if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == MBEDTLS_SSL_FI_FLAG_SET ) { /* * Resuming a session @@ -2858,7 +2872,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) * New session, create a new session id, * unless we're about to issue a session ticket */ - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_CERTIFICATE; #if defined(MBEDTLS_HAVE_TIME) ssl->session_negotiate->start = mbedtls_time( NULL ); @@ -3008,7 +3022,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; return( 0 ); } @@ -3030,7 +3044,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_SERVER_HELLO_DONE; #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ) @@ -3693,7 +3707,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) /* Key exchanges not involving ephemeral keys don't use * ServerKeyExchange, so end here. */ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_CERTIFICATE_REQUEST; return( 0 ); } #endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ @@ -3751,7 +3765,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; - ssl->state++; + ssl->state = MBEDTLS_SSL_CERTIFICATE_REQUEST; if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) { @@ -3773,7 +3787,7 @@ static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl ) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CERTIFICATE; #if defined(MBEDTLS_SSL_PROTO_DTLS) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) @@ -3964,6 +3978,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, unsigned char mask; size_t i, peer_pmslen; unsigned int diff; + volatile unsigned int pmscounter = 0; /* In case of a failure in decryption, the decryption may write less than * 2 bytes of output, but we always read the first two bytes. It doesn't @@ -4042,7 +4057,19 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, /* Set pms to either the true or the fake PMS, without * data-dependent branches. */ for( i = 0; i < ssl->handshake->pmslen; i++ ) + { pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); + pmscounter++; + } + + if( pmscounter == ssl->handshake->pmslen ) + { + mbedtls_platform_enforce_volatile_reads(); + if( pmscounter == ssl->handshake->pmslen ) + { + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + } + } return( 0 ); } @@ -4422,7 +4449,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; return( 0 ); } @@ -4432,7 +4459,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) #else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + volatile int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; size_t i, sig_len; unsigned char hash[48]; unsigned char *hash_start = hash; @@ -4450,7 +4477,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; return( 0 ); } @@ -4478,7 +4505,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( peer_pk == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; return( 0 ); } @@ -4490,7 +4517,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) goto exit; } - ssl->state++; + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; /* Process the message contents */ if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || @@ -4618,17 +4645,25 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) md_alg, ssl, hash, &dummy_hlen ); } - if( ( ret = mbedtls_pk_verify( peer_pk, - md_alg, hash_start, hashlen, - ssl->in_msg + i, sig_len ) ) != 0 ) + ret = mbedtls_pk_verify( peer_pk, + md_alg, hash_start, hashlen, + ssl->in_msg + i, sig_len ); + + if( ret == 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); - goto exit; + mbedtls_platform_enforce_volatile_reads(); + + if( ret == 0 ) + { + mbedtls_ssl_update_handshake_status( ssl ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); + goto exit; + } + } - mbedtls_ssl_update_handshake_status( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); exit: @@ -4815,9 +4850,10 @@ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - mbedtls_ssl_handshake_wrapup( ssl ); + ret = mbedtls_ssl_handshake_wrapup( ssl ); break; + case MBEDTLS_SSL_INVALID: default: MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index c12af9684..19bdc9079 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -48,6 +48,8 @@ #include "mbedtls/ssl_internal.h" #include "mbedtls/platform_util.h" #include "mbedtls/version.h" +#include "mbedtls/platform.h" + #include @@ -1825,7 +1827,7 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, mbedtls_ssl_handshake_get_ciphersuite( handshake ); #if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - if( handshake->resume != 0 ) + if( handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); return( 0 ); @@ -1881,10 +1883,10 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) { - int ret; + volatile int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); - + ssl->handshake->key_derivation_done = MBEDTLS_SSL_FI_FLAG_UNSET; /* Compute master secret if needed */ ret = ssl_compute_master( ssl->handshake, ssl->session_negotiate->master, @@ -1925,7 +1927,19 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) mbedtls_ssl_get_minor_ver( ssl ), mbedtls_ssl_conf_get_endpoint( ssl->conf ), ssl ); - if( ret != 0 ) + if( ret == 0 ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ret == 0 ) + { + ssl->handshake->key_derivation_done = MBEDTLS_SSL_FI_FLAG_SET; + } + else + { + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } + } + else { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_populate_transform", ret ); return( ret ); @@ -1958,11 +1972,10 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) { - int ret; + volatile int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - #if defined(MBEDTLS_USE_TINYCRYPT) if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || @@ -1980,6 +1993,7 @@ int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); if( ret != UECC_SUCCESS ) return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; ssl->handshake->pmslen = NUM_ECC_BYTES; } @@ -1989,12 +2003,26 @@ int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) { - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, + ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, ssl->handshake->premaster, MBEDTLS_PREMASTER_SIZE, &ssl->handshake->pmslen, mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) + mbedtls_ssl_conf_get_prng( ssl->conf ) ); + if( ret == 0 ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ret == 0 ) + { + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + } + else + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); + return( ret ); + } + } + else { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); return( ret ); @@ -2018,12 +2046,26 @@ int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) { - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, + ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &ssl->handshake->pmslen, ssl->handshake->premaster, MBEDTLS_MPI_MAX_SIZE, mbedtls_ssl_conf_get_frng( ssl->conf ), - mbedtls_ssl_conf_get_prng( ssl->conf ) ) ) != 0 ) + mbedtls_ssl_conf_get_prng( ssl->conf ) ); + if( ret == 0 ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ret == 0 ) + { + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + } + else + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } + } + else { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); return( ret ); @@ -2039,8 +2081,22 @@ int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) { - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ) ) != 0 ) + ret = mbedtls_ssl_psk_derive_premaster( ssl, + mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ); + if( ret == 0 ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ret == 0 ) + { + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + } + else + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } + } + else { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); return( ret ); @@ -2056,7 +2112,20 @@ int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) ssl->handshake->premaster, 32, &ssl->handshake->pmslen, mbedtls_ssl_conf_get_frng( ssl->conf ), mbedtls_ssl_conf_get_prng( ssl->conf ) ); - if( ret != 0 ) + if( ret == 0 ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ret == 0 ) + { + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + } + else + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } + } + else { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); return( ret ); @@ -2214,6 +2283,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch ssl->handshake->pmslen = p - ssl->handshake->premaster; + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + return( 0 ); } #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ @@ -4490,6 +4561,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) { unsigned i; size_t protected_record_size; + volatile int encrypted_fi = 0; /* Skip writing the record content type to after the encryption, * as it may change when using the CID extension. */ @@ -4544,6 +4616,13 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ ssl->out_msglen = len = rec.data_len; (void)mbedtls_platform_put_uint16_be( ssl->out_len, rec.data_len ); + encrypted_fi = 1; + } + + /* Double check to ensure the encryption has been done */ + if( ssl->transform_out != NULL && encrypted_fi == 0 ) + { + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl ); @@ -6740,7 +6819,18 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; + if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } return( 0 ); } @@ -6758,7 +6848,18 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - ssl->state++; + if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } return( 0 ); } @@ -6782,7 +6883,18 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; + if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } return( 0 ); } @@ -6793,7 +6905,18 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) if( ssl->client_auth == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; + if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } return( 0 ); } @@ -6867,7 +6990,18 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) write_msg: #endif - ssl->state++; + if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) { @@ -7129,7 +7263,7 @@ static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl ) * indicating whether a Certificate message is expected or not. */ #define SSL_CERTIFICATE_EXPECTED 0 -#define SSL_CERTIFICATE_SKIP 1 +#define SSL_CERTIFICATE_SKIP 0xff static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl, int authmode ) { @@ -7163,19 +7297,24 @@ static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl, } static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, - int authmode, + volatile int authmode, mbedtls_x509_crt *chain, void *rs_ctx ) { - int verify_ret; + volatile int verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + volatile int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + volatile int flow_counter = 0; mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); mbedtls_x509_crt *ca_chain; mbedtls_x509_crl *ca_crl; if( authmode == MBEDTLS_SSL_VERIFY_NONE ) + { return( 0 ); + } + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) if( ssl->handshake->sni_ca_chain != NULL ) { @@ -7205,9 +7344,22 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_X509_REMOVE_VERIFY_CALLBACK */ rs_ctx ); + if( verify_ret == 0 ) + { + mbedtls_platform_enforce_volatile_reads(); + if( verify_ret == 0 ) + { + flow_counter++; + } + else + { + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } + } if( verify_ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", verify_ret ); + flow_counter++; } #if defined(MBEDTLS_SSL__ECP_RESTARTABLE) @@ -7221,7 +7373,6 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_ECP_C) || defined(MBEDTLS_USE_TINYCRYPT) { - int ret; #if defined(MBEDTLS_USE_TINYCRYPT) ret = mbedtls_ssl_check_curve_uecc( ssl, MBEDTLS_UECC_DP_SECP256R1 ); #else /* MBEDTLS_USE_TINYCRYPT */ @@ -7249,16 +7400,27 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); if( verify_ret == 0 ) verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + flow_counter++; + } + if( ret == 0 ) + { + flow_counter++; } } #endif /* MBEDTLS_ECP_C || MEDTLS_USE_TINYCRYPT */ - if( mbedtls_ssl_check_cert_usage( chain, + ret = mbedtls_ssl_check_cert_usage( chain, ciphersuite_info, ( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ), - &ssl->session_negotiate->verify_result ) != 0 ) + &ssl->session_negotiate->verify_result ); + if( ret == 0 ) { + flow_counter++; + } + else + { + flow_counter++; MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); if( verify_ret == 0 ) verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; @@ -7274,13 +7436,31 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, ( verify_ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || verify_ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) { - verify_ret = 0; + mbedtls_platform_enforce_volatile_reads(); + if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && + ( verify_ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || + verify_ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) + { + verify_ret = 0; + flow_counter++; + } + else + { + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } + } else { + flow_counter++; } if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); verify_ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; + flow_counter++; + } + else + { + flow_counter++; } if( verify_ret != 0 ) @@ -7315,6 +7495,32 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, mbedtls_ssl_pend_fatal_alert( ssl, alert ); } + if( verify_ret == 0 && +#if defined(MBEDTLS_ECP_C) || defined(MBEDTLS_USE_TINYCRYPT) + flow_counter == 5 ) +#else + flow_counter == 4 ) +#endif + { + mbedtls_platform_enforce_volatile_reads(); + if( verify_ret == 0 && +#if defined(MBEDTLS_ECP_C) || defined(MBEDTLS_USE_TINYCRYPT) + flow_counter == 5 ) +#else + flow_counter == 4 ) +#endif + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PEER AUTHENTICATED" ) ); + ssl->handshake->peer_authenticated = MBEDTLS_SSL_FI_FLAG_SET; + } + else + { + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); + } + } else { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PEER NOT AUTHENTICATED, %d", flow_counter)); + } + #if defined(MBEDTLS_DEBUG_C) if( ssl->session_negotiate->verify_result != 0 ) { @@ -7523,7 +7729,20 @@ crt_verify: exit: if( ret == 0 ) - ssl->state++; + { + if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_CLIENT_KEY_EXCHANGE; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_CERTIFICATE ) + { + ssl->state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } + } #if defined(MBEDTLS_SSL__ECP_RESTARTABLE) if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ) @@ -7553,7 +7772,18 @@ int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) ssl->out_msglen = 1; ssl->out_msg[0] = 1; - ssl->state++; + if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ) + { + ssl->state = MBEDTLS_SSL_CLIENT_FINISHED; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) + { + ssl->state = MBEDTLS_SSL_SERVER_FINISHED; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) { @@ -7636,7 +7866,18 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) } #endif - ssl->state++; + if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ) + { + ssl->state = MBEDTLS_SSL_CLIENT_FINISHED; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) + { + ssl->state = MBEDTLS_SSL_SERVER_FINISHED; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); @@ -7685,8 +7926,21 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) ); } -void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) +int mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) { + volatile int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + volatile const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET + ? ssl->handshake->sni_authmode + : mbedtls_ssl_conf_get_authmode( ssl->conf ); +#else + volatile const int authmode = mbedtls_ssl_conf_get_authmode( ssl->conf ); +#endif +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + volatile int crt_expected = SSL_CERTIFICATE_EXPECTED; + crt_expected = ssl_parse_certificate_coordinate( ssl, authmode ); +#endif MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) ); #if defined(MBEDTLS_SSL_RENEGOTIATION) @@ -7720,13 +7974,102 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) */ if( ssl->conf->f_set_cache != NULL && ssl->session->id_len != 0 && - ssl->handshake->resume == 0 ) + ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_UNSET ) { if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) ); } #endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ + if( authmode == MBEDTLS_SSL_VERIFY_NONE || + authmode == MBEDTLS_SSL_VERIFY_OPTIONAL || +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + crt_expected == SSL_CERTIFICATE_SKIP ) +#else + 1 ) +#endif + { + mbedtls_platform_enforce_volatile_reads(); + if( authmode == MBEDTLS_SSL_VERIFY_NONE || + authmode == MBEDTLS_SSL_VERIFY_OPTIONAL || +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + crt_expected == SSL_CERTIFICATE_SKIP ) +#else + 1 ) +#endif + { + ssl->handshake->peer_authenticated = MBEDTLS_SSL_FI_FLAG_SET; + } + else + { + ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + goto cleanup; + } + } + +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) + if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) + { + /* When doing session resume, no premaster or peer authentication */ + ssl->handshake->peer_authenticated = MBEDTLS_SSL_FI_FLAG_SET; + ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET; + } + else + { + ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + goto cleanup; + } + } +#endif + + if( ssl->handshake->peer_authenticated == MBEDTLS_SSL_FI_FLAG_SET ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ssl->handshake->peer_authenticated == MBEDTLS_SSL_FI_FLAG_SET ) + { + ret = 0; + } + else + { + ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + goto cleanup; + } + } + else + { + ret = MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED; + goto cleanup; + } + + if( ssl->handshake->hello_random_set == MBEDTLS_SSL_FI_FLAG_SET && + ssl->handshake->key_derivation_done == MBEDTLS_SSL_FI_FLAG_SET && + ssl->handshake->premaster_generated == MBEDTLS_SSL_FI_FLAG_SET ) + { + mbedtls_platform_enforce_volatile_reads(); + if( ssl->handshake->hello_random_set == MBEDTLS_SSL_FI_FLAG_SET && + ssl->handshake->key_derivation_done == MBEDTLS_SSL_FI_FLAG_SET && + ssl->handshake->premaster_generated == MBEDTLS_SSL_FI_FLAG_SET ) + { + ret = 0; + } + else + { + ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + goto cleanup; + } + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "hello random %d", ssl->handshake->hello_random_set ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "key_derivation_done %d", ssl->handshake->key_derivation_done ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "premaster_generated %d", ssl->handshake->premaster_generated ) ); + ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + +cleanup: #if defined(MBEDTLS_SSL_PROTO_DTLS) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && ssl->handshake->flight != NULL ) @@ -7742,9 +8085,10 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) #endif ssl_handshake_wrapup_free_hs_transform( ssl ); - ssl->state++; + ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER; MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) ); + return ret; } int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) @@ -7785,7 +8129,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) * In case of session resuming, invert the client and server * ChangeCipherSpec messages order. */ - if( ssl->handshake->resume != 0 ) + if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) { #if defined(MBEDTLS_SSL_CLI_C) if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == @@ -7804,7 +8148,20 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) } else #endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ - ssl->state++; + { + if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ) + { + ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) + { + ssl->state = MBEDTLS_SSL_FLUSH_BUFFERS; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } + } /* * Switch to our negotiated transform and session parameters for outbound @@ -7951,7 +8308,7 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) #endif #if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) - if( ssl->handshake->resume != 0 ) + if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET ) { #if defined(MBEDTLS_SSL_CLI_C) if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) @@ -7964,7 +8321,20 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) } else #endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ - ssl->state++; + { + if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ) + { + ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + } + else if( ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) + { + ssl->state = MBEDTLS_SSL_FLUSH_BUFFERS; + } + else + { + ssl->state = MBEDTLS_SSL_INVALID; + } + } #if defined(MBEDTLS_SSL_PROTO_DTLS) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) ) @@ -8667,7 +9037,7 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session session ) ) != 0 ) return( ret ); - ssl->handshake->resume = 1; + ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_SET; return( 0 ); }