Fix edge case with half-supported ECDSA (manual test cases)

ECDSA has two variants: deterministic (PSA_ALG_DETERMINISTIC_ECDSA) and
randomized (PSA_ALG_ECDSA). The two variants are different for signature but
identical for verification. Mbed TLS accepts either variant as the algorithm
parameter for verification even when only the other variant is supported,
so we need to handle this as a special case when generating not-supported
test cases.

In this commit:

* Add manually written not-supported test cases for the signature
  operation when exactly one variant is supported.
* Add manually written positive test cases for the verification
  operation when exactly one variant is supported.
* Register that !ECDSA but DETERMINISTIC_ECDSA is not tested yet
  (https://github.com/Mbed-TLS/mbedtls/issues/9592).

A commit in the framework will take care of automatically generated test cases.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 18c8bde..09e1245 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -206,6 +206,11 @@
             'PBES2 Encrypt, pad=6 (PKCS7 padding disabled)',
             'PBES2 Encrypt, pad=8 (PKCS7 padding disabled)',
         ],
+        'test_suite_psa_crypto': [
+            # We don't test this unusual, but sensible configuration.
+            # https://github.com/Mbed-TLS/mbedtls/issues/9592
+            re.compile(r'.*ECDSA.*only deterministic supported'),
+        ],
         'test_suite_psa_crypto_generate_key.generated': [
             # Ignore mechanisms that are not implemented, except
             # for public keys for which we always test that
@@ -258,6 +263,9 @@
             # "PSA test case generation: dependency inference class: operation fail"
             # from https://github.com/Mbed-TLS/mbedtls/pull/9025 .
             re.compile(r'.* with (?:DH|ECC)_(?:KEY_PAIR|PUBLIC_KEY)\(.*'),
+            # We don't test this unusual, but sensible configuration.
+            # https://github.com/Mbed-TLS/mbedtls/issues/9592
+            re.compile(r'.*: !ECDSA but DETERMINISTIC_ECDSA with ECC_.*'),
             # PBKDF2_HMAC is not in the default configuration, so we don't
             # enable it in depends.py where we remove hashes.
             # https://github.com/Mbed-TLS/mbedtls/issues/9576
@@ -272,6 +280,11 @@
             # https://github.com/Mbed-TLS/mbedtls/issues/9578
             re.compile(r'PSA sign RSA_PSS_ANY_SALT.*!(?:MD|RIPEMD|SHA).*'),
         ],
+        'test_suite_psa_crypto_op_fail.misc': [
+            # We don't test this unusual, but sensible configuration.
+            # https://github.com/Mbed-TLS/mbedtls/issues/9592
+            'PSA sign DETERMINISTIC_ECDSA(SHA_256): !ECDSA but DETERMINISTIC_ECDSA with ECC_KEY_PAIR(SECP_R1)', #pylint: disable=line-too-long
+        ],
         'test_suite_psa_crypto_storage_format.current': [
             PSA_MECHANISM_NOT_IMPLEMENTED_SEARCH_RE,
         ],
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 9ac6646..f7bbbc7 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -4735,6 +4735,29 @@
 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_384
 verify_hash_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04d9c662b50ba29ca47990450e043aeaf4f0c69b15676d112f622a71c93059af999691c5680d2b44d111579db12f4a413a2ed5c45fcfb67b5b63e00b91ebe59d09a6b1ac2c0c4282aa12317ed5914f999bc488bb132e8342cc36f2ca5e3379c747":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"bed412df472eef873fb0839f91a6867d1c6824d4c5781d4b851faa43c7df904d99dbdd28c0d2fd3a4a006e89d34993a120aff166deb4974e96449a7ffe93c66726ad9443b14b87330c86bdde3faff5fd1cbfdc9afe46f8090376f9664cb116b4":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
 
+# The next 4 test cases check what happens if only one of the two ECDSA
+# variants is supported. The ECDSA variants (deterministic and randomized)
+# are different signature algorithms that can be enabled independently,
+# but they have the same verification. Mbed TLS accepts either variant
+# as the algorithm requested for verification even if that variant is not
+# supported. Test that this works. It would also be acceptable if the
+# library returned NOT_SUPPORTED in this case.
+PSA verify hash: ECDSA SECP256R1, only deterministic supported
+depends_on:!PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_256
+verify_hash:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
+PSA verify hash with keypair: ECDSA SECP256R1, only deterministic supported
+depends_on:!PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_ECC_SECP_R1_256
+verify_hash:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
+PSA verify hash: deterministic ECDSA SECP256R1, only randomized supported
+depends_on:PSA_WANT_ALG_ECDSA:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
+verify_hash:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
+PSA verify hash with keypair: deterministic ECDSA SECP256R1, only randomized supported
+depends_on:PSA_WANT_ALG_ECDSA:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
+verify_hash:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f"
+
 PSA verify hash: ECDSA SECP256R1, wrong signature size (correct but ASN1-encoded)
 depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:PSA_WANT_ECC_SECP_R1_256
 verify_hash_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"304502206a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151022100ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE
diff --git a/tests/suites/test_suite_psa_crypto_not_supported.function b/tests/suites/test_suite_psa_crypto_not_supported.function
index f37a197..4f15a3f 100644
--- a/tests/suites/test_suite_psa_crypto_not_supported.function
+++ b/tests/suites/test_suite_psa_crypto_not_supported.function
@@ -26,14 +26,14 @@
 #if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
     if (actual_status == PSA_ERROR_INVALID_ARGUMENT) {
         /* Edge case: when importing an ECC public key with an unspecified
-         * bit-size (as we do here), psa_import_key() infers the bit-size from
-         * the input. If the key type specifies an unknown curve, the validation
-         * might reject the data as invalid before it checks that the curve is
-         * supported. If so, that's ok. In practice, at the time of writing,
-         * this happens with Ed25519, for which a valid but unsupported
-         * 32-byte input causes psa_import_key() to fail because it
-         * assumes a Weierstrass curve which must have an odd-length
-         * encoding.
+         * bit-size (as we do here), the implementation of psa_import_key()
+         * infers the bit-size from the input. If the key type specifies an
+         * unknown curve, the validation might reject the data as invalid
+         * before it checks that the curve is supported. If so, that's ok.
+         * In practice, at the time of writing, this happens with Ed25519,
+         * for which a valid but unsupported 32-byte input causes
+         * psa_import_key() to fail because it assumes a Weierstrass curve
+         * which must have an odd-length encoding.
          *
          * In other cases, we do not expect an INVALID_ARGUMENT error here. */
         TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(key_type));
diff --git a/tests/suites/test_suite_psa_crypto_op_fail.function b/tests/suites/test_suite_psa_crypto_op_fail.function
index 9289869..86e4f1a 100644
--- a/tests/suites/test_suite_psa_crypto_op_fail.function
+++ b/tests/suites/test_suite_psa_crypto_op_fail.function
@@ -252,8 +252,8 @@
     PSA_ASSERT(psa_sign_hash_abort(&sign_operation));
 
     if (!private_only) {
-        /* Determine a plausible signature size to avoid an INVALID_SIGNATURE
-         * error based on this. */
+        /* Construct a signature candidate of a plausible size to avoid an
+         * INVALID_SIGNATURE error based on an early size verification. */
         PSA_ASSERT(psa_get_key_attributes(key_id, &attributes));
         size_t key_bits = psa_get_key_bits(&attributes);
         size_t output_length = sizeof(output);
diff --git a/tests/suites/test_suite_psa_crypto_op_fail.misc.data b/tests/suites/test_suite_psa_crypto_op_fail.misc.data
index 7158f2d..0c69fa8 100644
--- a/tests/suites/test_suite_psa_crypto_op_fail.misc.data
+++ b/tests/suites/test_suite_psa_crypto_op_fail.misc.data
@@ -13,3 +13,24 @@
 PSA sign RSA_PSS(SHA_256): RSA_PSS not enabled, key pair
 depends_on:!PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT
 sign_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):0:PSA_ERROR_NOT_SUPPORTED
+
+# There is a special case with ECDSA: deterministic and randomized ECDSA are
+# different signature algorithms that can be enabled independently, but
+# the verification algorithms are the same. Mbed TLS supports verification
+# of either variant when either variant is enabled. (It would also be correct
+# to reject the not-supported algorithm, but it would require a few more lines
+# of code.) In the automatically generated test cases, we avoid this difficulty
+# by making the not-supported test cases require neither variant to be
+# enabled. Here, test the signature operation when one variant is supported
+# but not the other. Testing the positive cases for the verification
+# operation is the job of test_suite_psa_crypto.
+#
+# We only test with one curve and one hash, because we know from a gray-box
+# approach that the curve and hash don't matter here.
+PSA sign DETERMINISTIC_ECDSA(SHA_256): !DETERMINISTIC_ECDSA but ECDSA with ECC_KEY_PAIR(SECP_R1)
+depends_on:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_192:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT
+sign_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"d83b57a59c51358d9c8bbb898aff507f44dd14cf16917190":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):1:PSA_ERROR_NOT_SUPPORTED
+
+PSA sign DETERMINISTIC_ECDSA(SHA_256): !ECDSA but DETERMINISTIC_ECDSA with ECC_KEY_PAIR(SECP_R1)
+depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:!PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_192:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT
+sign_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"d83b57a59c51358d9c8bbb898aff507f44dd14cf16917190":PSA_ALG_ECDSA(PSA_ALG_SHA_256):1:PSA_ERROR_NOT_SUPPORTED