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 7b916042c..935248f4c 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -123,6 +123,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 0bc08cca4..03033619d 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -618,6 +618,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_ECDSA_DETERMINISTIC * diff --git a/library/version_features.c b/library/version_features.c index d6deb0149..de0af3f10 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -312,6 +312,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_ECDSA_DETERMINISTIC) "MBEDTLS_ECDSA_DETERMINISTIC", #endif /* MBEDTLS_ECDSA_DETERMINISTIC */ diff --git a/scripts/config.pl b/scripts/config.pl index 2f04d91a1..b2c895321 100755 --- a/scripts/config.pl +++ b/scripts/config.pl @@ -72,6 +72,7 @@ EOU my @excluded = qw( 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 c99c2a68f..4103ace65 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -814,6 +814,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_full_cmake_clang () { msg "build: cmake, full config, clang" # ~ 50s scripts/config.pl full