From 23983f30dea2b897cea92f95719bc3cabfcf5f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 19 May 2020 12:38:31 +0200 Subject: [PATCH] Add config.h option MBEDTLS_ECP_NO_INTERNAL_RNG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No effect so far, except on dependency checking, as the feature it's meant to disable isn't implemented yet (so the descriptions in config.h and the ChangeLog entry are anticipation for now). Signed-off-by: Manuel Pégourié-Gonnard --- ChangeLog.d/ecp-internal-rng.txt | 5 +++++ include/mbedtls/check_config.h | 8 ++++++++ include/mbedtls/config.h | 22 ++++++++++++++++++++++ library/version_features.c | 3 +++ programs/ssl/query_config.c | 8 ++++++++ scripts/config.pl | 1 + tests/scripts/all.sh | 18 ++++++++++++++++++ 7 files changed, 65 insertions(+) create mode 100644 ChangeLog.d/ecp-internal-rng.txt diff --git a/ChangeLog.d/ecp-internal-rng.txt b/ChangeLog.d/ecp-internal-rng.txt new file mode 100644 index 000000000..bf11a7391 --- /dev/null +++ b/ChangeLog.d/ecp-internal-rng.txt @@ -0,0 +1,5 @@ +Changes + * The ECP module, enabled by `MBEDTLS_ECP_C`, now depends on + `MBEDTLS_CTR_DRBG_C` or `MBEDTLS_HMAC_DRBG_C` for some side-channel + coutermeasures. If side channels are not a concern, this dependency can + be avoided by enabling the new option `MBEDTLS_ECP_NO_INTERNAL_RNG`. diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 93de091c4..0aef0d068 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -140,6 +140,14 @@ #error "MBEDTLS_ECP_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_ECP_C) && !( \ + defined(MBEDTLS_ECP_ALT) || \ + defined(MBEDTLS_CTR_DRBG_C) || \ + defined(MBEDTLS_HMAC_DRBG_C) || \ + defined(MBEDTLS_ECP_NO_INTERNAL_RNG)) +#error "MBEDTLS_ECP_C requires a DRBG module unless MBEDTLS_ECP_NO_INTERNAL_RNG is defined or an alternative implementation is used" +#endif + #if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C) #error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites" #endif diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 834cced87..9442eb44b 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -780,6 +780,28 @@ */ #define MBEDTLS_ECP_NIST_OPTIM +/** + * \def MBEDTLS_ECP_NO_INTERNAL_RNG + * + * When this option is disabled, mbedtls_ecp_mul() will make use of an + * internal RNG when called with a NULL \c f_rng argument, in order to protect + * against some side-channel attacks. + * + * This protection introduces a dependency of the ECP module on one of the + * DRBG modules. For very constrained implementations that don't require this + * protection (for example, because you're only doing signature verification, + * so not manipulating any secret, or because local/physical side-channel + * attacks are outside your threat model), it might be desirable to get rid of + * that dependency. + * + * \warning Enabling this option makes some uses of ECP vulnerable to some + * side-channel attacks. Only enable it if you know that's not a problem for + * your use case. + * + * Uncomment this macro to disable some counter-measures in ECP. + */ +//#define MBEDTLS_ECP_NO_INTERNAL_RNG + /** * \def MBEDTLS_ECP_RESTARTABLE * diff --git a/library/version_features.c b/library/version_features.c index 3b67b2be8..6c9833ea9 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -351,6 +351,9 @@ static const char *features[] = { #if defined(MBEDTLS_ECP_NIST_OPTIM) "MBEDTLS_ECP_NIST_OPTIM", #endif /* MBEDTLS_ECP_NIST_OPTIM */ +#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) + "MBEDTLS_ECP_NO_INTERNAL_RNG", +#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */ #if defined(MBEDTLS_ECP_RESTARTABLE) "MBEDTLS_ECP_RESTARTABLE", #endif /* MBEDTLS_ECP_RESTARTABLE */ diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index 37e4141e9..976724e37 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -978,6 +978,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_ECP_NIST_OPTIM */ +#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG) + if( strcmp( "MBEDTLS_ECP_NO_INTERNAL_RNG", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_ECP_NO_INTERNAL_RNG ); + return( 0 ); + } +#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */ + #if defined(MBEDTLS_ECP_RESTARTABLE) if( strcmp( "MBEDTLS_ECP_RESTARTABLE", config ) == 0 ) { diff --git a/scripts/config.pl b/scripts/config.pl index ba563d6eb..72aabf672 100755 --- a/scripts/config.pl +++ b/scripts/config.pl @@ -73,6 +73,7 @@ my @excluded = qw( MBEDTLS_CTR_DRBG_USE_128_BIT_KEY MBEDTLS_DEPRECATED_REMOVED MBEDTLS_DEPRECATED_WARNING +MBEDTLS_ECP_NO_INTERNAL_RNG MBEDTLS_HAVE_SSE2 MBEDTLS_MEMORY_BACKTRACE MBEDTLS_MEMORY_BUFFER_ALLOC_C diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 634dfa80f..b16fd9a26 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -817,6 +817,24 @@ component_test_no_hmac_drbg () { # so there's little value in running those lengthy tests here. } +component_test_ecp_no_internal_rng () { + msg "build: Default plus ECP_NO_INTERNAL_RNG minus DRBG modules" + scripts/config.pl set MBEDTLS_ECP_NO_INTERNAL_RNG + scripts/config.pl unset MBEDTLS_CTR_DRBG_C + scripts/config.pl unset MBEDTLS_HMAC_DRBG_C + scripts/config.pl unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG + scripts/config.pl unset MBEDTLS_PSA_CRYPTO_C # requires a DRBG + scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C # requires PSA Crypto + + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . + make + + msg "test: ECP_NO_INTERNAL_RNG, no DRBG module" + make test + + # no SSL tests as they all depend on having a DRBG +} + component_test_small_ssl_out_content_len () { msg "build: small SSL_OUT_CONTENT_LEN (ASan build)" scripts/config.pl set MBEDTLS_SSL_IN_CONTENT_LEN 16384