diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py index 3a31fdb989..ad1cf37307 100755 --- a/tests/scripts/analyze_outcomes.py +++ b/tests/scripts/analyze_outcomes.py @@ -195,6 +195,11 @@ class CoverageTask(outcome_analysis.CoverageTask): '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 @@ -247,12 +252,19 @@ class CoverageTask(outcome_analysis.CoverageTask): # "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_.*'), # We never test with the HMAC algorithm enabled but the HMAC # key type disabled. Those dependencies don't really make sense. # https://github.com/Mbed-TLS/mbedtls/issues/9573 re.compile(r'.* !HMAC with HMAC'), ], + '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/tf-psa-crypto/core/psa_crypto.c b/tf-psa-crypto/core/psa_crypto.c index 359d622728..60707c6232 100644 --- a/tf-psa-crypto/core/psa_crypto.c +++ b/tf-psa-crypto/core/psa_crypto.c @@ -2437,6 +2437,58 @@ exit: /* Message digests */ /****************************************************************/ +static int is_hash_supported(psa_algorithm_t alg) +{ + switch (alg) { +#if defined(PSA_WANT_ALG_MD5) + case PSA_ALG_MD5: + return 1; +#endif +#if defined(PSA_WANT_ALG_RIPEMD160) + case PSA_ALG_RIPEMD160: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA_1) + case PSA_ALG_SHA_1: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA_224) + case PSA_ALG_SHA_224: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA_256) + case PSA_ALG_SHA_256: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA_384) + case PSA_ALG_SHA_384: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA_512) + case PSA_ALG_SHA_512: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA3_224) + case PSA_ALG_SHA3_224: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA3_256) + case PSA_ALG_SHA3_256: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA3_384) + case PSA_ALG_SHA3_384: + return 1; +#endif +#if defined(PSA_WANT_ALG_SHA3_512) + case PSA_ALG_SHA3_512: + return 1; +#endif + default: + return 0; + } +} + psa_status_t psa_hash_abort(psa_hash_operation_t *operation) { /* Aborting a non-active operation is allowed */ @@ -3080,16 +3132,44 @@ static psa_status_t psa_sign_verify_check_alg(int input_is_message, if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) { return PSA_ERROR_INVALID_ARGUMENT; } + } - if (PSA_ALG_IS_SIGN_HASH(alg)) { - if (!PSA_ALG_IS_HASH(PSA_ALG_SIGN_GET_HASH(alg))) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - } else { - if (!PSA_ALG_IS_SIGN_HASH(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } + psa_algorithm_t hash_alg = 0; + if (PSA_ALG_IS_SIGN_HASH(alg)) { + hash_alg = PSA_ALG_SIGN_GET_HASH(alg); + } + + /* Now hash_alg==0 if alg by itself doesn't need a hash. + * This is good enough for sign-hash, but a guaranteed failure for + * sign-message which needs to hash first for all algorithms + * supported at the moment. */ + + if (hash_alg == 0 && input_is_message) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (hash_alg == PSA_ALG_ANY_HASH) { + return PSA_ERROR_INVALID_ARGUMENT; + } + /* Give up immediately if the hash is not supported. This has + * several advantages: + * - For mechanisms that don't use the hash at all (e.g. + * ECDSA verification, randomized ECDSA signature), without + * this check, the operation would succeed even though it has + * been given an invalid argument. This would not be insecure + * since the hash was not necessary, but it would be weird. + * - For mechanisms that do use the hash, we avoid an error + * deep inside the execution. In principle this doesn't matter, + * but there is a little more risk of a bug in error handling + * deep inside than in this preliminary check. + * - When calling a driver, the driver might be capable of using + * a hash that the core doesn't support. This could potentially + * result in a buffer overflow if the hash is larger than the + * maximum hash size assumed by the core. + * - Returning a consistent error makes it possible to test + * not-supported hashes in a consistent way. + */ + if (hash_alg != 0 && !is_hash_supported(hash_alg)) { + return PSA_ERROR_NOT_SUPPORTED; } return PSA_SUCCESS; @@ -3970,6 +4050,34 @@ uint32_t mbedtls_psa_verify_hash_get_num_ops( * defined( MBEDTLS_ECP_RESTARTABLE ) */ } +/* Detect supported interruptible sign/verify mechanisms precisely. + * This is not strictly needed: we could accept everything, and let the + * code fail later during complete() if the mechanism is unsupported + * (e.g. attempting deterministic ECDSA when only the randomized variant + * is available). But it's easier for applications and especially for our + * test code to detect all not-supported errors during start(). + * + * Note that this function ignores the hash component. The core code + * is supposed to check the hash part by calling is_hash_supported(). + */ +static inline int can_do_interruptible_sign_verify(psa_algorithm_t alg) +{ +#if defined(MBEDTLS_ECP_RESTARTABLE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) + if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) { + return 1; + } +#endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) + if (PSA_ALG_IS_RANDOMIZED_ECDSA(alg)) { + return 1; + } +#endif +#endif /* defined(MBEDTLS_ECP_RESTARTABLE) */ + (void) alg; + return 0; +} + psa_status_t mbedtls_psa_sign_hash_start( mbedtls_psa_sign_hash_interruptible_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key_buffer, @@ -3983,7 +4091,7 @@ psa_status_t mbedtls_psa_sign_hash_start( return PSA_ERROR_NOT_SUPPORTED; } - if (!PSA_ALG_IS_ECDSA(alg)) { + if (!can_do_interruptible_sign_verify(alg)) { return PSA_ERROR_NOT_SUPPORTED; } @@ -4199,7 +4307,7 @@ psa_status_t mbedtls_psa_verify_hash_start( return PSA_ERROR_NOT_SUPPORTED; } - if (!PSA_ALG_IS_ECDSA(alg)) { + if (!can_do_interruptible_sign_verify(alg)) { return PSA_ERROR_NOT_SUPPORTED; } diff --git a/tf-psa-crypto/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/tf-psa-crypto/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja index d3b7d6fb31..ed5c9a02d0 100644 --- a/tf-psa-crypto/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja +++ b/tf-psa-crypto/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja @@ -307,8 +307,7 @@ static inline psa_status_t psa_driver_wrapper_sign_hash( #endif /* PSA_CRYPTO_DRIVER_TEST */ #if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED) if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && - PSA_ALG_IS_ECDSA(alg) && - !PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) && + PSA_ALG_IS_RANDOMIZED_ECDSA(alg) && PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && psa_get_key_bits(attributes) == 256 ) { @@ -412,7 +411,6 @@ static inline psa_status_t psa_driver_wrapper_verify_hash( #if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED) if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && PSA_ALG_IS_ECDSA(alg) && - !PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) && PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && psa_get_key_bits(attributes) == 256 ) { diff --git a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.data b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.data index 35073af206..ade9cba3cf 100644 --- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.data +++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.data @@ -4489,11 +4489,11 @@ sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):" PSA sign hash int (ops=inf): det ECDSA not supported depends_on:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_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 -sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":96:PSA_SUCCESS:PSA_ERROR_NOT_SUPPORTED:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":96:PSA_ERROR_NOT_SUPPORTED:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED PSA sign hash int (ops=min): det ECDSA not supported depends_on:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_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 -sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":96:PSA_SUCCESS:PSA_ERROR_NOT_SUPPORTED:0 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":96:PSA_ERROR_NOT_SUPPORTED:PSA_ERROR_BAD_STATE:0 PSA sign/verify hash: RSA PKCS#1 v1.5, raw depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT @@ -4735,6 +4735,29 @@ PSA vrfy hash: det ECDSA SECP384R1 SHA-256 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_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"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 @@ -4844,14 +4867,14 @@ depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:P sign_message_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263":0:PSA_ERROR_INVALID_ARGUMENT PSA sign message: RSA PKCS#1 v1.5 SHA-256, invalid key type -depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_CHACHA20 +depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_CHACHA20 sign_message_fail:PSA_KEY_TYPE_CHACHA20:"4bddc98c551a95395ef719557f813656b566bc45aac04eca3866324cc75489f2":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"616263":128:PSA_ERROR_INVALID_ARGUMENT -PSA sign message: ECDSA SECP256R1 SHA-256, invalid hash (wildcard) +PSA sign message: ECDSA SECP256R1, invalid hash (wildcard) depends_on:PSA_WANT_ALG_ECDSA: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_256 sign_message_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):"616263":64:PSA_ERROR_INVALID_ARGUMENT -PSA sign message: ECDSA SECP256R1 SHA-256, invalid hash algorithm (0) +PSA sign message: ECDSA SECP256R1, invalid hash algorithm (0) depends_on:PSA_WANT_ALG_ECDSA: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_256 sign_message_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(0):"616263":64:PSA_ERROR_INVALID_ARGUMENT diff --git a/tf-psa-crypto/tests/suites/test_suite_psa_crypto_not_supported.function b/tf-psa-crypto/tests/suites/test_suite_psa_crypto_not_supported.function index e5e66f482e..4f15a3f796 100644 --- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto_not_supported.function +++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto_not_supported.function @@ -20,10 +20,28 @@ void import_not_supported(int key_type, data_t *key_material) PSA_ASSERT(psa_crypto_init()); psa_set_key_type(&attributes, key_type); - TEST_EQUAL(psa_import_key(&attributes, - key_material->x, key_material->len, - &key_id), - PSA_ERROR_NOT_SUPPORTED); + psa_status_t actual_status = + psa_import_key(&attributes, key_material->x, key_material->len, &key_id); + +#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), 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)); + } else +#endif /* defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) */ + { + TEST_EQUAL(actual_status, PSA_ERROR_NOT_SUPPORTED); + } TEST_ASSERT(mbedtls_svc_key_id_equal(key_id, MBEDTLS_SVC_KEY_ID_INIT)); exit: diff --git a/tf-psa-crypto/tests/suites/test_suite_psa_crypto_op_fail.function b/tf-psa-crypto/tests/suites/test_suite_psa_crypto_op_fail.function index d88b4fa6f9..c7b6844442 100644 --- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto_op_fail.function +++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto_op_fail.function @@ -223,12 +223,9 @@ void sign_fail(int key_type_arg, data_t *key_data, size_t length = SIZE_MAX; psa_sign_hash_interruptible_operation_t sign_operation = psa_sign_hash_interruptible_operation_init(); - psa_verify_hash_interruptible_operation_t verify_operation = psa_verify_hash_interruptible_operation_init(); - - PSA_INIT(); psa_set_key_type(&attributes, key_type); @@ -252,8 +249,8 @@ void sign_fail(int key_type_arg, data_t *key_data, 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); @@ -277,6 +274,8 @@ void sign_fail(int key_type_arg, data_t *key_data, } exit: + psa_sign_hash_abort(&sign_operation); + psa_verify_hash_abort(&verify_operation); psa_destroy_key(key_id); psa_reset_key_attributes(&attributes); PSA_DONE(); diff --git a/tf-psa-crypto/tests/suites/test_suite_psa_crypto_op_fail.misc.data b/tf-psa-crypto/tests/suites/test_suite_psa_crypto_op_fail.misc.data index 7158f2dcba..0c69fa89d8 100644 --- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto_op_fail.misc.data +++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto_op_fail.misc.data @@ -13,3 +13,24 @@ sign_fail:PSA_KEY_TYPE_AES:"48657265006973206b6579a064617461":PSA_ALG_RSA_PSS(PS 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 diff --git a/tf-psa-crypto/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tf-psa-crypto/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function index efd24e9f29..b43009676a 100644 --- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function +++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function @@ -196,6 +196,9 @@ static psa_status_t mock_export_public(psa_drv_se_context_t *context, return mock_export_public_data.return_value; } +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \ + defined(PSA_WANT_ALG_ECDSA) && \ + defined(PSA_WANT_ALG_SHA_256) static psa_status_t mock_sign(psa_drv_se_context_t *context, psa_key_slot_number_t key_slot, psa_algorithm_t alg, @@ -218,7 +221,9 @@ static psa_status_t mock_sign(psa_drv_se_context_t *context, return mock_sign_data.return_value; } +#endif +#if defined(PSA_WANT_ALG_ECDSA) && defined(PSA_WANT_ALG_SHA_256) static psa_status_t mock_verify(psa_drv_se_context_t *context, psa_key_slot_number_t key_slot, psa_algorithm_t alg, @@ -239,6 +244,7 @@ static psa_status_t mock_verify(psa_drv_se_context_t *context, return mock_verify_data.return_value; } +#endif static psa_status_t mock_allocate(psa_drv_se_context_t *drv_context, void *persistent_data, @@ -550,7 +556,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE */ +/* BEGIN_CASE depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256 */ void mock_sign(int mock_sign_return_value, int expected_result) { psa_drv_se_t driver; @@ -611,7 +617,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE */ +/* BEGIN_CASE depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256 */ void mock_verify(int mock_verify_return_value, int expected_result) { psa_drv_se_t driver;