Merge pull request #8582 from yanrayw/issue/8167/PK_parse_write_OID_dependency

PK parse and PK write: add dependency check with OID
diff --git a/ChangeLog.d/gen-key-segfault.txt b/ChangeLog.d/gen-key-segfault.txt
new file mode 100644
index 0000000..fefc702
--- /dev/null
+++ b/ChangeLog.d/gen-key-segfault.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Avoid segmentation fault caused by releasing not initialized
+     entropy resource in gen_key example. Fixes #8809.
diff --git a/docs/driver-only-builds.md b/docs/driver-only-builds.md
index f59420e..4095d8e 100644
--- a/docs/driver-only-builds.md
+++ b/docs/driver-only-builds.md
@@ -105,7 +105,28 @@
 - for code that uses only the PSA Crypto API: `PSA_WANT_ALG_xxx` from
   `psa/crypto.h`;
 - for code that uses non-PSA crypto APIs: `MBEDTLS_MD_CAN_xxx` from
-  `mbedtls/md.h`.
+  `mbedtls/config_adjust_legacy_crypto.h`.
+
+### HMAC
+
+In addition to accelerated hash operations, it is also possible to accelerate
+HMAC by enabling and accelerating:
+- HMAC algorithm and key type, i.e. `[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_HMAC` and
+  `[PSA_WANT|MBEDTLS_PSA_ACCEL]KEY_TYPE_HMAC`.
+- Required hash algorithm(s) as explained in [Hashes](#hashes) section.
+
+In such a build it is possible to disable legacy HMAC support by disabling
+`MBEDTLS_MD_C` and still getting crypto operations, X.509 and TLS to work as
+usual. Exceptions are:
+- As mentioned in [Hashes](#hashes) direct calls to legacy lo-level hash APIs
+  (`mbedtls_sha256()` etc.) will not be possible for the legacy modules that
+  are disabled.
+- Legacy HMAC support (`mbedtls_md_hmac_xxx()`) won't be possible.
+- `MBEDTLS_PKCS[5|7]_C`, `MBEDTLS_HMAC_DRBG_C` and `MBEDTLS_HKDF_C` since they
+  depend on the legacy implementation of HMAC.
+  - disabling HMAC_DRBG_C cause deterministic ECDSA (i.e.
+  `MBEDTLS_DETERMINISTIC_ECDSA` on the legacy side and 
+  `PSA_WANT_ALG_DETERMINISTIC_ECDSA` on the PSA one) to be not available.
 
 Elliptic-curve cryptography (ECC)
 ---------------------------------
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index 6914c93..194a5cb 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -249,6 +249,7 @@
     mbedtls_mpi_init(&DQ); mbedtls_mpi_init(&QP);
 #endif /* MBEDTLS_RSA_C */
 
+    mbedtls_entropy_init(&entropy);
     mbedtls_pk_init(&key);
     mbedtls_ctr_drbg_init(&ctr_drbg);
     memset(buf, 0, sizeof(buf));
@@ -336,7 +337,6 @@
     mbedtls_printf("\n  . Seeding the random number generator...");
     fflush(stdout);
 
-    mbedtls_entropy_init(&entropy);
 #if !defined(_WIN32) && defined(MBEDTLS_FS_IO)
     if (opt.use_dev_random) {
         if ((ret = mbedtls_entropy_add_source(&entropy, dev_random_entropy_poll,
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index 6ae43a9..dcfd176 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -14,7 +14,8 @@
 #if !defined(MBEDTLS_X509_CSR_WRITE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
     !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \
     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
-    !defined(MBEDTLS_PEM_WRITE_C) || !defined(MBEDTLS_FS_IO)
+    !defined(MBEDTLS_PEM_WRITE_C) || !defined(MBEDTLS_FS_IO) || \
+    !defined(MBEDTLS_MD_C)
 int main(void)
 {
     mbedtls_printf("MBEDTLS_X509_CSR_WRITE_C and/or MBEDTLS_FS_IO and/or "
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index bf25c4c..0b2575e 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -15,7 +15,7 @@
     !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) || \
     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
     !defined(MBEDTLS_ERROR_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \
-    !defined(MBEDTLS_PEM_WRITE_C)
+    !defined(MBEDTLS_PEM_WRITE_C) || !defined(MBEDTLS_MD_C)
 int main(void)
 {
     mbedtls_printf("MBEDTLS_X509_CRT_WRITE_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index af32c06..f18bfad 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -3691,6 +3691,75 @@
     tests/ssl-opt.sh
 }
 
+# Auxiliary function to build config for hashes with and without drivers
+config_psa_crypto_hmac_use_psa () {
+    driver_only="$1"
+    # start with config full for maximum coverage (also enables USE_PSA)
+    helper_libtestdriver1_adjust_config "full"
+
+    if [ "$driver_only" -eq 1 ]; then
+        # Disable MD_C in order to disable the builtin support for HMAC. MD_LIGHT
+        # is still enabled though (for ENTROPY_C among others).
+        scripts/config.py unset MBEDTLS_MD_C
+        # Disable also the builtin hashes since they are supported by the driver
+        # and MD module is able to perform PSA dispathing.
+        scripts/config.py unset-all MBEDTLS_SHA
+        scripts/config.py unset MBEDTLS_MD5_C
+        scripts/config.py unset MBEDTLS_RIPEMD160_C
+    fi
+
+    # Direct dependencies of MD_C. We disable them also in the reference
+    # component to work with the same set of features.
+    scripts/config.py unset MBEDTLS_PKCS7_C
+    scripts/config.py unset MBEDTLS_PKCS5_C
+    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
+    scripts/config.py unset MBEDTLS_HKDF_C
+    # Dependencies of HMAC_DRBG
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
+    scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
+}
+
+component_test_psa_crypto_config_accel_hmac() {
+    msg "test: full with accelerated hmac"
+
+    loc_accel_list="ALG_HMAC KEY_TYPE_HMAC \
+                    ALG_MD5 ALG_RIPEMD160 ALG_SHA_1 \
+                    ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \
+                    ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512"
+
+    # Configure
+    # ---------
+
+    config_psa_crypto_hmac_use_psa 1
+
+    # Build
+    # -----
+
+    helper_libtestdriver1_make_drivers "$loc_accel_list"
+
+    helper_libtestdriver1_make_main "$loc_accel_list"
+
+    # Ensure that built-in support for HMAC is disabled.
+    not grep mbedtls_md_hmac library/md.o
+
+    # Run the tests
+    # -------------
+
+    msg "test: full with accelerated hmac"
+    make test
+}
+
+component_test_psa_crypto_config_reference_hmac() {
+    msg "test: full without accelerated hmac"
+
+    config_psa_crypto_hmac_use_psa 0
+
+    make
+
+    msg "test: full without accelerated hmac"
+    make test
+}
+
 component_test_psa_crypto_config_accel_des () {
     msg "test: MBEDTLS_PSA_CRYPTO_CONFIG with accelerated DES"
 
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 8c7f21f..11e4836 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -240,6 +240,44 @@
             }
         }
     },
+    'analyze_driver_vs_reference_hmac': {
+        'test_function': do_analyze_driver_vs_reference,
+        'args': {
+            'component_ref': 'test_psa_crypto_config_reference_hmac',
+            'component_driver': 'test_psa_crypto_config_accel_hmac',
+            'ignored_suites': [
+                # These suites require legacy hash support, which is disabled
+                # in the accelerated component.
+                'shax', 'mdx',
+                # This suite tests builtins directly, but these are missing
+                # in the accelerated case.
+                'psa_crypto_low_hash.generated',
+            ],
+            'ignored_tests': {
+                'test_suite_md': [
+                    # Builtin HMAC is not supported in the accelerate component.
+                    re.compile('.*HMAC.*'),
+                    # Following tests make use of functions which are not available
+                    # when MD_C is disabled, as it happens in the accelerated
+                    # test component.
+                    re.compile('generic .* Hash file .*'),
+                    'MD list',
+                ],
+                'test_suite_md.psa': [
+                    # "legacy only" tests require hash algorithms to be NOT
+                    # accelerated, but this of course false for the accelerated
+                    # test component.
+                    re.compile('PSA dispatch .* legacy only'),
+                ],
+                'test_suite_platform': [
+                    # Incompatible with sanitizers (e.g. ASan). If the driver
+                    # component uses a sanitizer but the reference component
+                    # doesn't, we have a PASS vs SKIP mismatch.
+                    'Check mbedtls_calloc overallocation',
+                ],
+            }
+        }
+    },
     'analyze_driver_vs_reference_cipher_aead_cmac': {
         'test_function': do_analyze_driver_vs_reference,
         'args': {
diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function
index ed9f3ac..5ac65fc 100644
--- a/tests/suites/test_suite_entropy.function
+++ b/tests/suites/test_suite_entropy.function
@@ -447,7 +447,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_MD_C:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */
+/* BEGIN_CASE depends_on:MBEDTLS_MD_LIGHT:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */
 void entropy_nv_seed(data_t *read_seed)
 {
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)