Add config.h option MBEDTLS_ECP_NO_INTERNAL_RNG

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 <manuel.pegourie-gonnard@arm.com>
diff --git a/ChangeLog.d/ecp-internal-rng.txt b/ChangeLog.d/ecp-internal-rng.txt
new file mode 100644
index 0000000..bf11a73
--- /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 7b91604..935248f 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 0bc08cc..0303361 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -619,6 +619,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
  *
  * Enable deterministic ECDSA (RFC 6979).
diff --git a/library/version_features.c b/library/version_features.c
index d6deb01..de0af3f 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -312,6 +312,9 @@
 #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 2f04d91..b2c8953 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -72,6 +72,7 @@
 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 c99c2a6..4103ace 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -814,6 +814,24 @@
     # 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