diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 756360b18..20e443630 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -88,6 +88,14 @@ #endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +/* Shorthand for restartable */ +#if defined(MBEDTLS_ECP_RESTARTABLE) && \ + defined(MBEDTLS_SSL_CLI_C) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#define MBEDTLS_SSL__ECP_RESTARTABLE +#endif + #define MBEDTLS_SSL_INITIAL_HANDSHAKE 0 #define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */ #define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */ @@ -218,6 +226,14 @@ struct mbedtls_ssl_handshake_params mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) + enum { + ssl_ecrs_init = 0, /*!< just getting started */ + ssl_ecrs_ecdh_public_done, /*!< wrote ECDHE public share */ + ssl_ecrs_ecdh_completed, /*!< completed ECDHE key exchange */ + } ecrs_state; /*!< state for restartable ECC */ + size_t ecrs_n; /*!< place for seving a length */ +#endif #if defined(MBEDTLS_SSL_PROTO_DTLS) unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ diff --git a/library/ssl_cli.c b/library/ssl_cli.c index a2b9f8cfe..8d7bc45ce 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -2861,6 +2861,11 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) */ i = 4; +#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) + if( ssl->handshake->ecrs_state == ssl_ecrs_ecdh_public_done ) + goto ecdh_calc_secret; +#endif + ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, &ssl->out_msg[i], 1000, @@ -2873,6 +2878,13 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); +#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) + ssl->handshake->ecrs_n = n; + ssl->handshake->ecrs_state++; + +ecdh_calc_secret: + n = ssl->handshake->ecrs_n; +#endif if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &ssl->handshake->pmslen, ssl->handshake->premaster, @@ -2884,6 +2896,10 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) } MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); + +#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) + ssl->handshake->ecrs_state++; +#endif } else #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 280fc6348..05e882249 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -3441,6 +3441,48 @@ run_test "Large packet TLS 1.2 AEAD shorter tag" \ 0 \ -s "Read from client: 16384 bytes read" +# Tests for restartable ECC + +requires_config_enabled MBEDTLS_ECP_RESTARTABLE +run_test "EC restart: TLS, default" \ + "$P_SRV" \ + "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \ + debug_level=1" \ + 0 \ + -C "mbedtls_ecdh_make_public.*4b80" + +requires_config_enabled MBEDTLS_ECP_RESTARTABLE +run_test "EC restart: TLS, max_ops=0" \ + "$P_SRV" \ + "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \ + debug_level=1 ec_max_ops=0" \ + 0 \ + -C "mbedtls_ecdh_make_public.*4b80" + +requires_config_enabled MBEDTLS_ECP_RESTARTABLE +run_test "EC restart: TLS, max_ops=65535" \ + "$P_SRV" \ + "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \ + debug_level=1 ec_max_ops=65535" \ + 0 \ + -C "mbedtls_ecdh_make_public.*4b80" + +requires_config_enabled MBEDTLS_ECP_RESTARTABLE +run_test "EC restart: TLS, max_ops=1000" \ + "$P_SRV" \ + "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \ + debug_level=1 ec_max_ops=1000" \ + 0 \ + -c "mbedtls_ecdh_make_public.*4b80" + +requires_config_enabled MBEDTLS_ECP_RESTARTABLE +run_test "EC restart: DTLS, max_ops=1000" \ + "$P_SRV dtls=1" \ + "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \ + dtls=1 debug_level=1 ec_max_ops=1000" \ + 0 \ + -c "mbedtls_ecdh_make_public.*4b80" + # Tests for DTLS HelloVerifyRequest run_test "DTLS cookie: enabled" \