From d22362c647cb2161b79546e44e40b420e13399ed Mon Sep 17 00:00:00 2001 From: Mateusz Starzyk Date: Thu, 26 Aug 2021 11:46:14 +0200 Subject: [PATCH 01/14] Add missing PSA_ALG_IS_SIGN_HASH macro. Signed-off-by: Mateusz Starzyk --- include/psa/crypto.h | 8 ++++++-- include/psa/crypto_values.h | 15 +++++++++++++++ library/psa_crypto.c | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 73e1a2e97..877c19bfa 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -3019,7 +3019,9 @@ psa_status_t psa_verify_message( mbedtls_svc_key_id_t key, * \param key Identifier of the key to use for the operation. * It must be an asymmetric key pair. The key must * allow the usage #PSA_KEY_USAGE_SIGN_HASH. - * \param alg A signature algorithm that is compatible with + * \param alg A signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) + * is true), that is compatible with * the type of \p key. * \param[in] hash The hash or message to sign. * \param hash_length Size of the \p hash buffer in bytes. @@ -3072,7 +3074,9 @@ psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, * must be a public key or an asymmetric key pair. The * key must allow the usage * #PSA_KEY_USAGE_VERIFY_HASH. - * \param alg A signature algorithm that is compatible with + * \param alg A signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) + * is true), that is compatible with * the type of \p key. * \param[in] hash The hash or message whose signature is to be * verified. diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index ca35a89cc..12358a1e7 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -1569,6 +1569,21 @@ #define PSA_ALG_IS_SIGN_MESSAGE(alg) \ (PSA_ALG_IS_HASH_AND_SIGN(alg) || (alg) == PSA_ALG_PURE_EDDSA ) +/** Whether the specified algorithm is a signature algorithm that can be used + * with psa_sign_hash() and psa_verify_hash(). + * + * \param alg An algorithm identifier (value of type psa_algorithm_t). + * + * \return 1 if alg is a signature algorithm that can be used to sign a + * hash. 0 if alg is a signature algorithm that can only be used + * to sign a message. 0 if alg is not a signature algorithm. + * This macro can return either 0 or 1 if alg is not a + * supported algorithm identifier. + */ +#define PSA_ALG_IS_SIGN_HASH(alg) \ + (PSA_ALG_IS_HASH_AND_SIGN(alg) || (alg) == PSA_ALG_ED25519PH || \ + (alg) == PSA_ALG_ED448PH) + /** Get the hash used by a hash-and-sign signature algorithm. * * A hash-and-sign algorithm is a signature algorithm which is diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 4ece79958..a8e41a217 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2706,7 +2706,7 @@ static psa_status_t psa_sign_verify_check_alg( int input_is_message, } else { - if( ! PSA_ALG_IS_HASH_AND_SIGN( alg ) ) + if( ! PSA_ALG_IS_SIGN_HASH( alg ) ) return( PSA_ERROR_INVALID_ARGUMENT ); } From 294ca3012032571ea70df6965291a68acbbf093c Mon Sep 17 00:00:00 2001 From: Mateusz Starzyk Date: Thu, 26 Aug 2021 12:52:56 +0200 Subject: [PATCH 02/14] Add missing PSA_ALG_NONE macro. Signed-off-by: Mateusz Starzyk --- include/psa/crypto_values.h | 3 +++ programs/psa/psa_constant_names_generated.c | 1 + 2 files changed, 4 insertions(+) diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index 12358a1e7..b30f95567 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -790,6 +790,9 @@ #define PSA_ALG_IS_KEY_DERIVATION(alg) \ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) +/** An invalid algorithm identifier value. */ +#define PSA_ALG_NONE ((psa_algorithm_t)0) + #define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) /** MD2 */ #define PSA_ALG_MD2 ((psa_algorithm_t)0x02000001) diff --git a/programs/psa/psa_constant_names_generated.c b/programs/psa/psa_constant_names_generated.c index 590b000b4..de2971691 100644 --- a/programs/psa/psa_constant_names_generated.c +++ b/programs/psa/psa_constant_names_generated.c @@ -221,6 +221,7 @@ static int psa_snprint_algorithm(char *buffer, size_t buffer_size, case PSA_ALG_MD2: append(&buffer, buffer_size, &required_size, "PSA_ALG_MD2", 11); break; case PSA_ALG_MD4: append(&buffer, buffer_size, &required_size, "PSA_ALG_MD4", 11); break; case PSA_ALG_MD5: append(&buffer, buffer_size, &required_size, "PSA_ALG_MD5", 11); break; + case PSA_ALG_NONE: append(&buffer, buffer_size, &required_size, "PSA_ALG_NONE", 12); break; case PSA_ALG_OFB: append(&buffer, buffer_size, &required_size, "PSA_ALG_OFB", 11); break; case PSA_ALG_PURE_EDDSA: append(&buffer, buffer_size, &required_size, "PSA_ALG_PURE_EDDSA", 18); break; case PSA_ALG_RIPEMD160: append(&buffer, buffer_size, &required_size, "PSA_ALG_RIPEMD160", 17); break; From 272a3d4dd8ba406ce8d7e40daf536a7a54792b6f Mon Sep 17 00:00:00 2001 From: Mateusz Starzyk Date: Thu, 26 Aug 2021 13:28:46 +0200 Subject: [PATCH 03/14] Add missing PSA_HASH_BLOCK_LENGTH macro. Signed-off-by: Mateusz Starzyk --- include/psa/crypto_sizes.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index f51ec87f9..2df315cca 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -85,6 +85,40 @@ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \ 0) +/** The input block size of a hash algorithm, in bytes. + * + * Hash algorithms process their input data in blocks. Hash operations will + * retain any partial blocks until they have enough input to fill the block or + * until the operation is finished. + * This affects the output from psa_hash_suspend(). + * + * \param alg A hash algorithm (\c PSA_ALG_XXX value such that + * PSA_ALG_IS_HASH(\p alg) is true). + * + * \return The block size in bytes for the specified hash algorithm. + * If the hash algorithm is not recognized, return 0. + * An implementation can return either 0 or the correct size for a + * hash algorithm that it recognizes, but does not support. + */ +#define PSA_HASH_BLOCK_LENGTH(alg) \ + ( \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 128 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 128 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 128 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 128 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 144 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 136 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 104 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 72 : \ + 0) + /** \def PSA_HASH_MAX_SIZE * * Maximum size of a hash. From 64010dc544ef02185206e4124fd1296edd5a408a Mon Sep 17 00:00:00 2001 From: Mateusz Starzyk Date: Thu, 26 Aug 2021 13:32:30 +0200 Subject: [PATCH 04/14] Add missing PSA_KEY_ID_NULL macro. Signed-off-by: Mateusz Starzyk --- include/psa/crypto_values.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index b30f95567..524e2dc7a 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -2025,6 +2025,9 @@ #define PSA_KEY_LOCATION_VENDOR_FLAG ((psa_key_location_t)0x800000) +/** The null key identifier. + */ +#define PSA_KEY_ID_NULL ((psa_key_id_t)0) /** The minimum value for a key identifier chosen by the application. */ #define PSA_KEY_ID_USER_MIN ((psa_key_id_t)0x00000001) From 21cac076263c4b24e885935aa93d9feed93c9ff9 Mon Sep 17 00:00:00 2001 From: Mateusz Starzyk Date: Thu, 26 Aug 2021 14:29:02 +0200 Subject: [PATCH 05/14] Add changelog entry for new PSA Crypto API macros. Signed-off-by: Mateusz Starzyk --- ChangeLog.d/psa_crypto_api_macros.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/psa_crypto_api_macros.txt diff --git a/ChangeLog.d/psa_crypto_api_macros.txt b/ChangeLog.d/psa_crypto_api_macros.txt new file mode 100644 index 000000000..c695ff5c9 --- /dev/null +++ b/ChangeLog.d/psa_crypto_api_macros.txt @@ -0,0 +1,3 @@ +Features + * Add missing PSA macros declared by PSA Crypto API 1.0.0: + PSA_ALG_IS_SIGN_HASH, PSA_ALG_NONE, PSA_HASH_BLOCK_LENGTH, PSA_KEY_ID_NULL From 285f2133f5a6e5a008133662916ac63225f58c7a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Sep 2021 14:44:28 +0200 Subject: [PATCH 06/14] Use the new macro PSA_HASH_BLOCK_LENGTH Replace an equivalent internal function. Signed-off-by: Gilles Peskine --- library/psa_crypto_mac.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 135fa352d..7e0a8325d 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -42,33 +42,6 @@ #endif #if defined(BUILTIN_ALG_HMAC) -static size_t psa_get_hash_block_size( psa_algorithm_t alg ) -{ - switch( alg ) - { - case PSA_ALG_MD2: - return( 16 ); - case PSA_ALG_MD4: - return( 64 ); - case PSA_ALG_MD5: - return( 64 ); - case PSA_ALG_RIPEMD160: - return( 64 ); - case PSA_ALG_SHA_1: - return( 64 ); - case PSA_ALG_SHA_224: - return( 64 ); - case PSA_ALG_SHA_256: - return( 64 ); - case PSA_ALG_SHA_384: - return( 128 ); - case PSA_ALG_SHA_512: - return( 128 ); - default: - return( 0 ); - } -} - static psa_status_t psa_hmac_abort_internal( mbedtls_psa_hmac_operation_t *hmac ) { @@ -85,7 +58,7 @@ static psa_status_t psa_hmac_setup_internal( uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; size_t i; size_t hash_size = PSA_HASH_LENGTH( hash_alg ); - size_t block_size = psa_get_hash_block_size( hash_alg ); + size_t block_size = PSA_HASH_BLOCK_LENGTH( hash_alg ); psa_status_t status; hmac->alg = hash_alg; @@ -157,7 +130,7 @@ static psa_status_t psa_hmac_finish_internal( uint8_t tmp[MBEDTLS_MD_MAX_SIZE]; psa_algorithm_t hash_alg = hmac->alg; size_t hash_size = 0; - size_t block_size = psa_get_hash_block_size( hash_alg ); + size_t block_size = PSA_HASH_BLOCK_LENGTH( hash_alg ); psa_status_t status; status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size ); From 1b06d09fc62453a9de67655e14c8f272b86bad51 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Sep 2021 14:47:26 +0200 Subject: [PATCH 07/14] Test PSA_HASH_BLOCK_LENGTH Only tested for algorithms for which we support HMAC, since that's all we use PSA_HASH_BLOCK_LENGTH for at the moment. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_psa_crypto_metadata.function | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function index 7002034ab..827ad1b36 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -350,6 +350,7 @@ void hmac_algorithm( int alg_arg, TEST_ASSERT( PSA_ALG_IS_HASH( hash_alg ) ); TEST_EQUAL( PSA_ALG_HMAC( hash_alg ), alg ); + TEST_ASSERT( block_size == PSA_HASH_BLOCK_LENGTH( alg ) ); TEST_ASSERT( block_size <= PSA_HMAC_MAX_HASH_BLOCK_SIZE ); test_mac_algorithm( alg_arg, ALG_IS_HMAC, length, From 8cb22c8d875fd52fa336db35d1d59d6ac8fc533d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Sep 2021 16:15:05 +0200 Subject: [PATCH 08/14] Untangle PSA_ALG_IS_HASH_AND_SIGN and PSA_ALG_IS_SIGN_HASH The current definition of PSA_ALG_IS_HASH_AND_SIGN includes PSA_ALG_RSA_PKCS1V15_SIGN_RAW and PSA_ALG_ECDSA_ANY, which don't strictly follow the hash-and-sign paradigm: the algorithm does not encode a hash algorithm that is applied prior to the signature step. The definition in fact encompasses what can be used with psa_sign_hash/psa_verify_hash, so it's the correct definition for PSA_ALG_IS_SIGN_HASH. Therefore this commit moves definition of PSA_ALG_IS_HASH_AND_SIGN to PSA_ALG_IS_SIGN_HASH, and replace the definition of PSA_ALG_IS_HASH_AND_SIGN by a correct one (based on PSA_ALG_IS_SIGN_HASH, excluding the algorithms where the pre-signature step isn't to apply the hash encoded in the algorithm). In the definition of PSA_ALG_SIGN_GET_HASH, keep the condition for a nonzero output to be PSA_ALG_IS_HASH_AND_SIGN. Everywhere else in the code base (definition of PSA_ALG_IS_SIGN_MESSAGE, and every use of PSA_ALG_IS_HASH_AND_SIGN outside of crypto_values.h), we meant PSA_ALG_IS_SIGN_HASH where we wrote PSA_ALG_IS_HASH_AND_SIGN, so do a global replacement. ``` git grep -l IS_HASH_AND_SIGN ':!include/psa/crypto_values.h' | xargs perl -i -pe 's/ALG_IS_HASH_AND_SIGN/ALG_IS_SIGN_HASH/g' ``` Signed-off-by: Gilles Peskine --- include/psa/crypto_values.h | 34 ++++++++++++++----- library/psa_crypto.c | 12 +++---- tests/src/psa_exercise_key.c | 4 +-- tests/suites/test_suite_psa_crypto.function | 2 +- .../test_suite_psa_crypto_metadata.data | 18 +++++----- .../test_suite_psa_crypto_metadata.function | 6 ++-- 6 files changed, 47 insertions(+), 29 deletions(-) diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index 524e2dc7a..a29beb565 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -1545,7 +1545,20 @@ * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms * structured in two parts: first the calculation of a hash in a way that * does not depend on the key, then the calculation of a signature from the - * hash value and the key. + * hash value and the key. Hash-and-sign algorithms encode the hash + * used for the hashing step, and you can call #PSA_ALG_SIGN_GET_HASH + * to extract this algorithm. + * + * Thus, for a hash-and-sign algorithm, + * `psa_sign_message(key, alg, input, ...)` is equivalent to + * ``` + * psa_hash_compute(PSA_ALG_SIGN_GET_HASH(alg), input, ..., hash, ...); + * psa_sign_hash(key, alg, hash, ..., signature, ...); + * ``` + * Most usefully, separating the hash from the signature allows the hash + * to be calculated in multiple steps with psa_hash_setup(), psa_hash_update() + * and psa_hash_finish(). Likewise psa_verify_message() is equivalent to + * calculating the hash and then calling psa_verify_hash(). * * \param alg An algorithm identifier (value of type #psa_algorithm_t). * @@ -1554,9 +1567,8 @@ * algorithm identifier. */ #define PSA_ALG_IS_HASH_AND_SIGN(alg) \ - (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ - PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ - PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg)) + (PSA_ALG_IS_SIGN_HASH(alg) && \ + ((alg) & PSA_ALG_HASH_MASK) != 0) /** Whether the specified algorithm is a signature algorithm that can be used * with psa_sign_message() and psa_verify_message(). @@ -1570,11 +1582,17 @@ * supported algorithm identifier. */ #define PSA_ALG_IS_SIGN_MESSAGE(alg) \ - (PSA_ALG_IS_HASH_AND_SIGN(alg) || (alg) == PSA_ALG_PURE_EDDSA ) + (PSA_ALG_IS_SIGN_HASH(alg) || (alg) == PSA_ALG_PURE_EDDSA ) /** Whether the specified algorithm is a signature algorithm that can be used * with psa_sign_hash() and psa_verify_hash(). * + * This encompasses all strict hash-and-sign algorithms categorized by + * PSA_ALG_IS_HASH_AND_SIGN(), as well as algorithms that follow the + * paradigm more loosely: + * - #PSA_ALG_RSA_PKCS1V15_SIGN_RAW (expects its input to be an encoded hash) + * - #PSA_ALG_ECDSA_ANY (doesn't specify what kind of hash the input is) + * * \param alg An algorithm identifier (value of type psa_algorithm_t). * * \return 1 if alg is a signature algorithm that can be used to sign a @@ -1584,8 +1602,9 @@ * supported algorithm identifier. */ #define PSA_ALG_IS_SIGN_HASH(alg) \ - (PSA_ALG_IS_HASH_AND_SIGN(alg) || (alg) == PSA_ALG_ED25519PH || \ - (alg) == PSA_ALG_ED448PH) + (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ + PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ + PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg)) /** Get the hash used by a hash-and-sign signature algorithm. * @@ -1607,7 +1626,6 @@ */ #define PSA_ALG_SIGN_GET_HASH(alg) \ (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \ - ((alg) & PSA_ALG_HASH_MASK) == 0 ? /*"raw" algorithm*/ 0 : \ ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \ 0) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a8e41a217..406e6c4cf 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -705,8 +705,8 @@ static psa_algorithm_t psa_key_policy_algorithm_intersection( return( alg1 ); /* If the policies are from the same hash-and-sign family, check * if one is a wildcard. If so the other has the specific algorithm. */ - if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) && - PSA_ALG_IS_HASH_AND_SIGN( alg2 ) && + if( PSA_ALG_IS_SIGN_HASH( alg1 ) && + PSA_ALG_IS_SIGN_HASH( alg2 ) && ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) ) { if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH ) @@ -808,7 +808,7 @@ static int psa_key_algorithm_permits( psa_key_type_t key_type, /* If policy_alg is a hash-and-sign with a wildcard for the hash, * and requested_alg is the same hash-and-sign family with any hash, * then requested_alg is compliant with policy_alg. */ - if( PSA_ALG_IS_HASH_AND_SIGN( requested_alg ) && + if( PSA_ALG_IS_SIGN_HASH( requested_alg ) && PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH ) { return( ( policy_alg & ~PSA_ALG_HASH_MASK ) == @@ -2698,7 +2698,7 @@ 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_HASH_AND_SIGN( alg ) ) + if ( PSA_ALG_IS_SIGN_HASH( alg ) ) { if( ! PSA_ALG_IS_HASH( PSA_ALG_SIGN_GET_HASH( alg ) ) ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -2856,7 +2856,7 @@ psa_status_t psa_sign_message_builtin( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - if ( PSA_ALG_IS_HASH_AND_SIGN( alg ) ) + if ( PSA_ALG_IS_SIGN_HASH( alg ) ) { size_t hash_length; uint8_t hash[PSA_HASH_MAX_SIZE]; @@ -2903,7 +2903,7 @@ psa_status_t psa_verify_message_builtin( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - if ( PSA_ALG_IS_HASH_AND_SIGN( alg ) ) + if ( PSA_ALG_IS_SIGN_HASH( alg ) ) { size_t hash_length; uint8_t hash[PSA_HASH_MAX_SIZE]; diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 923d2c136..91bac678e 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -306,7 +306,7 @@ static int exercise_signature_key( mbedtls_svc_key_id_t key, psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg ); /* If the policy allows signing with any hash, just pick one. */ - if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH ) + if( PSA_ALG_IS_SIGN_HASH( alg ) && hash_alg == PSA_ALG_ANY_HASH ) { #if defined(KNOWN_SUPPORTED_HASH_ALG) hash_alg = KNOWN_SUPPORTED_HASH_ALG; @@ -925,7 +925,7 @@ psa_key_usage_t mbedtls_test_psa_usage_to_exercise( psa_key_type_t type, { if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) ) { - if( PSA_ALG_IS_HASH_AND_SIGN( alg ) ) + if( PSA_ALG_IS_SIGN_HASH( alg ) ) { if( PSA_ALG_SIGN_GET_HASH( alg ) ) return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ? diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 5fa45d8e7..2eab8e50a 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1159,7 +1159,7 @@ void asymmetric_signature_key_policy( int policy_usage_arg, else TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); - if( PSA_ALG_IS_HASH_AND_SIGN( exercise_alg ) && + if( PSA_ALG_IS_SIGN_HASH( exercise_alg ) && PSA_ALG_IS_HASH( PSA_ALG_SIGN_GET_HASH( exercise_alg ) ) ) { status = psa_sign_message( key, exercise_alg, diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data index 1ea8e6332..89705e8fb 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.data +++ b/tests/suites/test_suite_psa_crypto_metadata.data @@ -212,31 +212,31 @@ aead_algorithm:PSA_ALG_CHACHA20_POLY1305:0:16:PSA_KEY_TYPE_CHACHA20:256 Asymmetric signature: RSA PKCS#1 v1.5 raw depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN -asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_SIGN_HASH Asymmetric signature: RSA PKCS#1 v1.5 SHA-256 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_256 ):ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_256 ):ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_SIGN_HASH Asymmetric signature: RSA PSS SHA-256 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_STANDARD_SALT | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_STANDARD_SALT | ALG_IS_SIGN_HASH Asymmetric signature: RSA PSS-any-salt SHA-256 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_RSA_PSS_ANY_SALT( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_ANY_SALT | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_RSA_PSS_ANY_SALT( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_ANY_SALT | ALG_IS_SIGN_HASH Asymmetric signature: randomized ECDSA (no hashing) depends_on:PSA_WANT_ALG_ECDSA -asymmetric_signature_algorithm:PSA_ALG_ECDSA_ANY:ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_ECDSA_ANY:ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_SIGN_HASH Asymmetric signature: SHA-256 + randomized ECDSA depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_SIGN_HASH Asymmetric signature: SHA-256 + deterministic ECDSA using SHA-256 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_DETERMINISTIC_ECDSA | ALG_ECDSA_IS_DETERMINISTIC | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_DETERMINISTIC_ECDSA | ALG_ECDSA_IS_DETERMINISTIC | ALG_IS_SIGN_HASH Asymmetric signature: pure EdDSA depends_on:PSA_WANT_ALG_EDDSA @@ -244,11 +244,11 @@ asymmetric_signature_algorithm:PSA_ALG_PURE_EDDSA:0 Asymmetric signature: Ed25519ph depends_on:PSA_WANT_ALG_EDDSA -asymmetric_signature_algorithm:PSA_ALG_ED25519PH:ALG_IS_HASH_EDDSA | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_ED25519PH:ALG_IS_HASH_EDDSA | ALG_IS_SIGN_HASH Asymmetric signature: Ed448ph depends_on:PSA_WANT_ALG_EDDSA -asymmetric_signature_algorithm:PSA_ALG_ED448PH:ALG_IS_HASH_EDDSA | ALG_IS_HASH_AND_SIGN +asymmetric_signature_algorithm:PSA_ALG_ED448PH:ALG_IS_HASH_EDDSA | ALG_IS_SIGN_HASH Asymmetric signature: RSA PKCS#1 v1.5 with wildcard hash depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function index 827ad1b36..e6d2127be 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -33,7 +33,7 @@ #define ALG_IS_DETERMINISTIC_ECDSA ( 1u << 14 ) #define ALG_IS_RANDOMIZED_ECDSA ( 1u << 15 ) #define ALG_IS_HASH_EDDSA ( 1u << 16 ) -#define ALG_IS_HASH_AND_SIGN ( 1u << 17 ) +#define ALG_IS_SIGN_HASH ( 1u << 17 ) #define ALG_IS_RSA_OAEP ( 1u << 18 ) #define ALG_IS_HKDF ( 1u << 19 ) #define ALG_IS_FFDH ( 1u << 20 ) @@ -114,7 +114,7 @@ void algorithm_classification( psa_algorithm_t alg, unsigned flags ) TEST_CLASSIFICATION_MACRO( ALG_IS_DETERMINISTIC_ECDSA, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_RANDOMIZED_ECDSA, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_HASH_EDDSA, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_HASH_AND_SIGN, alg, flags ); + TEST_CLASSIFICATION_MACRO( ALG_IS_SIGN_HASH, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_OAEP, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_HKDF, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_WILDCARD, alg, flags ); @@ -485,7 +485,7 @@ void asymmetric_signature_algorithm( int alg_arg, int classification_flags ) /* BEGIN_CASE */ void asymmetric_signature_wildcard( int alg_arg, int classification_flags ) { - classification_flags |= ALG_IS_HASH_AND_SIGN | ALG_IS_WILDCARD; + classification_flags |= ALG_IS_SIGN_HASH | ALG_IS_WILDCARD; test_asymmetric_signature_algorithm( alg_arg, classification_flags ); /* Any failure of this test function comes from * asymmetric_signature_algorithm. Pacify -Werror=unused-label. */ From 4bdcf9a35acc7adf972fcfa61668ff4649a523b1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Sep 2021 16:42:02 +0200 Subject: [PATCH 09/14] Reorder macro definitions Definition before mention Signed-off-by: Gilles Peskine --- include/psa/crypto_values.h | 72 ++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index a29beb565..fafe93cf9 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -1540,6 +1540,42 @@ * file. */ #define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) 0 +/** Whether the specified algorithm is a signature algorithm that can be used + * with psa_sign_hash() and psa_verify_hash(). + * + * This encompasses all strict hash-and-sign algorithms categorized by + * PSA_ALG_IS_HASH_AND_SIGN(), as well as algorithms that follow the + * paradigm more loosely: + * - #PSA_ALG_RSA_PKCS1V15_SIGN_RAW (expects its input to be an encoded hash) + * - #PSA_ALG_ECDSA_ANY (doesn't specify what kind of hash the input is) + * + * \param alg An algorithm identifier (value of type psa_algorithm_t). + * + * \return 1 if alg is a signature algorithm that can be used to sign a + * hash. 0 if alg is a signature algorithm that can only be used + * to sign a message. 0 if alg is not a signature algorithm. + * This macro can return either 0 or 1 if alg is not a + * supported algorithm identifier. + */ +#define PSA_ALG_IS_SIGN_HASH(alg) \ + (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ + PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ + PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg)) + +/** Whether the specified algorithm is a signature algorithm that can be used + * with psa_sign_message() and psa_verify_message(). + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if alg is a signature algorithm that can be used to sign a + * message. 0 if \p alg is a signature algorithm that can only be used + * to sign an already-calculated hash. 0 if \p alg is not a signature + * algorithm. This macro can return either 0 or 1 if \p alg is not a + * supported algorithm identifier. + */ +#define PSA_ALG_IS_SIGN_MESSAGE(alg) \ + (PSA_ALG_IS_SIGN_HASH(alg) || (alg) == PSA_ALG_PURE_EDDSA ) + /** Whether the specified algorithm is a hash-and-sign algorithm. * * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms @@ -1570,42 +1606,6 @@ (PSA_ALG_IS_SIGN_HASH(alg) && \ ((alg) & PSA_ALG_HASH_MASK) != 0) -/** Whether the specified algorithm is a signature algorithm that can be used - * with psa_sign_message() and psa_verify_message(). - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if alg is a signature algorithm that can be used to sign a - * message. 0 if \p alg is a signature algorithm that can only be used - * to sign an already-calculated hash. 0 if \p alg is not a signature - * algorithm. This macro can return either 0 or 1 if \p alg is not a - * supported algorithm identifier. - */ -#define PSA_ALG_IS_SIGN_MESSAGE(alg) \ - (PSA_ALG_IS_SIGN_HASH(alg) || (alg) == PSA_ALG_PURE_EDDSA ) - -/** Whether the specified algorithm is a signature algorithm that can be used - * with psa_sign_hash() and psa_verify_hash(). - * - * This encompasses all strict hash-and-sign algorithms categorized by - * PSA_ALG_IS_HASH_AND_SIGN(), as well as algorithms that follow the - * paradigm more loosely: - * - #PSA_ALG_RSA_PKCS1V15_SIGN_RAW (expects its input to be an encoded hash) - * - #PSA_ALG_ECDSA_ANY (doesn't specify what kind of hash the input is) - * - * \param alg An algorithm identifier (value of type psa_algorithm_t). - * - * \return 1 if alg is a signature algorithm that can be used to sign a - * hash. 0 if alg is a signature algorithm that can only be used - * to sign a message. 0 if alg is not a signature algorithm. - * This macro can return either 0 or 1 if alg is not a - * supported algorithm identifier. - */ -#define PSA_ALG_IS_SIGN_HASH(alg) \ - (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ - PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ - PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg)) - /** Get the hash used by a hash-and-sign signature algorithm. * * A hash-and-sign algorithm is a signature algorithm which is From cc14ce08c2322a0842222b5b50c9849da5d3abb1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Sep 2021 18:12:31 +0200 Subject: [PATCH 10/14] Add PSA_ALG_IS_HASH_AND_SIGN to the metadata tests The status of signature wildcards with respect to PSA_ALG_IS_HASH_AND_SIGN is unclear in the specification. A wildcard is usually instantiated with a specific hash, making the implementation hash-and-sign, but it could also be instantiated with a non-hash-and-sign algorithm. For the time being, go with what's currently implemented, which is that they are considered hash-and-sign. Signed-off-by: Gilles Peskine --- .../test_suite_psa_crypto_metadata.data | 14 +++++----- .../test_suite_psa_crypto_metadata.function | 28 +++++++++++-------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data index 89705e8fb..bab7ee711 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.data +++ b/tests/suites/test_suite_psa_crypto_metadata.data @@ -216,15 +216,15 @@ asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:ALG_IS_RSA_PKCS1V15 Asymmetric signature: RSA PKCS#1 v1.5 SHA-256 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_256 ):ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_SIGN_HASH +asymmetric_signature_algorithm:PSA_ALG_RSA_PKCS1V15_SIGN( PSA_ALG_SHA_256 ):ALG_IS_RSA_PKCS1V15_SIGN | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN Asymmetric signature: RSA PSS SHA-256 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_STANDARD_SALT | ALG_IS_SIGN_HASH +asymmetric_signature_algorithm:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_STANDARD_SALT | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN Asymmetric signature: RSA PSS-any-salt SHA-256 depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_RSA_PSS_ANY_SALT( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_ANY_SALT | ALG_IS_SIGN_HASH +asymmetric_signature_algorithm:PSA_ALG_RSA_PSS_ANY_SALT( PSA_ALG_SHA_256 ):ALG_IS_RSA_PSS | ALG_IS_RSA_PSS_ANY_SALT | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN Asymmetric signature: randomized ECDSA (no hashing) depends_on:PSA_WANT_ALG_ECDSA @@ -232,11 +232,11 @@ asymmetric_signature_algorithm:PSA_ALG_ECDSA_ANY:ALG_IS_ECDSA | ALG_IS_RANDOMIZE Asymmetric signature: SHA-256 + randomized ECDSA depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_SIGN_HASH +asymmetric_signature_algorithm:PSA_ALG_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN Asymmetric signature: SHA-256 + deterministic ECDSA using SHA-256 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256 -asymmetric_signature_algorithm:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_DETERMINISTIC_ECDSA | ALG_ECDSA_IS_DETERMINISTIC | ALG_IS_SIGN_HASH +asymmetric_signature_algorithm:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):ALG_IS_ECDSA | ALG_IS_DETERMINISTIC_ECDSA | ALG_ECDSA_IS_DETERMINISTIC | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN Asymmetric signature: pure EdDSA depends_on:PSA_WANT_ALG_EDDSA @@ -244,11 +244,11 @@ asymmetric_signature_algorithm:PSA_ALG_PURE_EDDSA:0 Asymmetric signature: Ed25519ph depends_on:PSA_WANT_ALG_EDDSA -asymmetric_signature_algorithm:PSA_ALG_ED25519PH:ALG_IS_HASH_EDDSA | ALG_IS_SIGN_HASH +asymmetric_signature_algorithm:PSA_ALG_ED25519PH:ALG_IS_HASH_EDDSA | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN Asymmetric signature: Ed448ph depends_on:PSA_WANT_ALG_EDDSA -asymmetric_signature_algorithm:PSA_ALG_ED448PH:ALG_IS_HASH_EDDSA | ALG_IS_SIGN_HASH +asymmetric_signature_algorithm:PSA_ALG_ED448PH:ALG_IS_HASH_EDDSA | ALG_IS_SIGN_HASH | ALG_IS_HASH_AND_SIGN Asymmetric signature: RSA PKCS#1 v1.5 with wildcard hash depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function index e6d2127be..577b6dbd0 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -33,16 +33,17 @@ #define ALG_IS_DETERMINISTIC_ECDSA ( 1u << 14 ) #define ALG_IS_RANDOMIZED_ECDSA ( 1u << 15 ) #define ALG_IS_HASH_EDDSA ( 1u << 16 ) -#define ALG_IS_SIGN_HASH ( 1u << 17 ) -#define ALG_IS_RSA_OAEP ( 1u << 18 ) -#define ALG_IS_HKDF ( 1u << 19 ) -#define ALG_IS_FFDH ( 1u << 20 ) -#define ALG_IS_ECDH ( 1u << 21 ) -#define ALG_IS_WILDCARD ( 1u << 22 ) -#define ALG_IS_RAW_KEY_AGREEMENT ( 1u << 23 ) -#define ALG_IS_AEAD_ON_BLOCK_CIPHER ( 1u << 24 ) -#define ALG_IS_TLS12_PRF ( 1u << 25 ) -#define ALG_IS_TLS12_PSK_TO_MS ( 1u << 26 ) +#define ALG_IS_SIGN_HASH ( 1u << 17 ) +#define ALG_IS_HASH_AND_SIGN ( 1u << 18 ) +#define ALG_IS_RSA_OAEP ( 1u << 19 ) +#define ALG_IS_HKDF ( 1u << 20 ) +#define ALG_IS_FFDH ( 1u << 21 ) +#define ALG_IS_ECDH ( 1u << 22 ) +#define ALG_IS_WILDCARD ( 1u << 23 ) +#define ALG_IS_RAW_KEY_AGREEMENT ( 1u << 24 ) +#define ALG_IS_AEAD_ON_BLOCK_CIPHER ( 1u << 25 ) +#define ALG_IS_TLS12_PRF ( 1u << 26 ) +#define ALG_IS_TLS12_PSK_TO_MS ( 1u << 27 ) /* Flags for key type classification macros. There is a flag for every * key type classification macro PSA_KEY_TYPE_IS_xxx except for some that @@ -51,7 +52,7 @@ #define KEY_TYPE_IS_VENDOR_DEFINED ( 1u << 0 ) #define KEY_TYPE_IS_UNSTRUCTURED ( 1u << 1 ) #define KEY_TYPE_IS_PUBLIC_KEY ( 1u << 2 ) -#define KEY_TYPE_IS_KEY_PAIR ( 1u << 3 ) +#define KEY_TYPE_IS_KEY_PAIR ( 1u << 3 ) #define KEY_TYPE_IS_RSA ( 1u << 4 ) #define KEY_TYPE_IS_DSA ( 1u << 5 ) #define KEY_TYPE_IS_ECC ( 1u << 6 ) @@ -115,6 +116,7 @@ void algorithm_classification( psa_algorithm_t alg, unsigned flags ) TEST_CLASSIFICATION_MACRO( ALG_IS_RANDOMIZED_ECDSA, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_HASH_EDDSA, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_SIGN_HASH, alg, flags ); + TEST_CLASSIFICATION_MACRO( ALG_IS_HASH_AND_SIGN, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_OAEP, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_HKDF, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_WILDCARD, alg, flags ); @@ -485,7 +487,9 @@ void asymmetric_signature_algorithm( int alg_arg, int classification_flags ) /* BEGIN_CASE */ void asymmetric_signature_wildcard( int alg_arg, int classification_flags ) { - classification_flags |= ALG_IS_SIGN_HASH | ALG_IS_WILDCARD; + classification_flags |= ALG_IS_WILDCARD; + classification_flags |= ALG_IS_SIGN_HASH; + classification_flags |= ALG_IS_HASH_AND_SIGN; test_asymmetric_signature_algorithm( alg_arg, classification_flags ); /* Any failure of this test function comes from * asymmetric_signature_algorithm. Pacify -Werror=unused-label. */ From 19191039f91d55f00ea4bb0725833518c8bee0a7 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 15 Oct 2021 21:38:35 +0200 Subject: [PATCH 11/14] Note the change to PSA_ALG_IS_HASH_AND_SIGN in the changelog Signed-off-by: Gilles Peskine --- ChangeLog.d/psa_crypto_api_macros.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog.d/psa_crypto_api_macros.txt b/ChangeLog.d/psa_crypto_api_macros.txt index c695ff5c9..ff53e33c2 100644 --- a/ChangeLog.d/psa_crypto_api_macros.txt +++ b/ChangeLog.d/psa_crypto_api_macros.txt @@ -1,3 +1,11 @@ Features * Add missing PSA macros declared by PSA Crypto API 1.0.0: - PSA_ALG_IS_SIGN_HASH, PSA_ALG_NONE, PSA_HASH_BLOCK_LENGTH, PSA_KEY_ID_NULL + PSA_ALG_IS_SIGN_HASH, PSA_ALG_NONE, PSA_HASH_BLOCK_LENGTH, PSA_KEY_ID_NULL. + +Bugfix + * The existing predicate macro name PSA_ALG_IS_HASH_AND_SIGN is now reserved + for algorithm values that fully encode the hashing step, as per the PSA + Crypto API specification. This excludes PSA_ALG_RSA_PKCS1V15_SIGN_RAW and + PSA_ALG_ECDSA_ANY. The new predicate macro PSA_ALG_IS_SIGN_HASH covers + all algorithms that can be used with psa_{sign,verify}_hash(), including + these two. From e65be27eea33538b20d70cad36b73a22e389c7ec Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 27 Oct 2021 21:37:45 +0200 Subject: [PATCH 12/14] Correct block size for MD2 Signed-off-by: Gilles Peskine --- tests/suites/test_suite_psa_crypto_metadata.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data index bab7ee711..72a11ab73 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.data +++ b/tests/suites/test_suite_psa_crypto_metadata.data @@ -36,7 +36,7 @@ hash_algorithm:PSA_ALG_SHA_512:64 MAC: HMAC-MD2 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_MD2 -hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_MD2 ):16:64 +hmac_algorithm:PSA_ALG_HMAC( PSA_ALG_MD2 ):16:16 MAC: HMAC-MD4 depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_MD4 From 31b95155ba779ea3f1f4d8f36fb36db76bfaf865 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 3 Nov 2021 14:18:08 +0100 Subject: [PATCH 13/14] Ensure that all flags are actually tested At least twice, we added a classification flag but forgot to test it in the relevant test functions. Add some protection so that this doesn't happen again. In each classification category, put a macro xxx_FLAG_MASK_PLUS_ONE at the end. In the corresponding test function, keep track of the flags that are tested, and check that their mask is xxx_FLAG_MASK_PLUS_ONE - 1 which is all the bits of the previous flags set. Now, if we add a flag without testing it, the test TEST_EQUAL( classification_flags_tested, xxx_FLAG_MASK_PLUS_ONE - 1 ) will fail. It will also fail if we make the set of flag numbers non-consecutive, which is ok. This reveals that three algorithm flags had been added but not tested (in two separate occasions). Also, one key type flag that is no longer used by the library was still defined but not tested, which is not a test gap but is inconsistent. It's for DSA, which is relevant to the PSA encoding even if Mbed TLS doesn't implement it, so keep the flag and do test it. Signed-off-by: Gilles Peskine --- .../test_suite_psa_crypto_metadata.function | 112 +++++++++++------- 1 file changed, 69 insertions(+), 43 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function index 577b6dbd0..3cbc6ba76 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -44,6 +44,7 @@ #define ALG_IS_AEAD_ON_BLOCK_CIPHER ( 1u << 25 ) #define ALG_IS_TLS12_PRF ( 1u << 26 ) #define ALG_IS_TLS12_PSK_TO_MS ( 1u << 27 ) +#define ALG_FLAG_MASK_PLUS_ONE ( 1u << 28 ) /* must be last! */ /* Flags for key type classification macros. There is a flag for every * key type classification macro PSA_KEY_TYPE_IS_xxx except for some that @@ -57,21 +58,38 @@ #define KEY_TYPE_IS_DSA ( 1u << 5 ) #define KEY_TYPE_IS_ECC ( 1u << 6 ) #define KEY_TYPE_IS_DH ( 1u << 7 ) +#define KEY_TYPE_FLAG_MASK_PLUS_ONE ( 1u << 8 ) /* must be last! */ /* Flags for lifetime classification macros. There is a flag for every * lifetime classification macro PSA_KEY_LIFETIME_IS_xxx. The name of the * flag is the name of the classification macro without the PSA_ prefix. */ #define KEY_LIFETIME_IS_VOLATILE ( 1u << 0 ) #define KEY_LIFETIME_IS_READ_ONLY ( 1u << 1 ) +#define KEY_LIFETIME_FLAG_MASK_PLUS_ONE ( 1u << 2 ) /* must be last! */ -#define TEST_CLASSIFICATION_MACRO( flag, alg, flags ) \ - do \ - { \ - if( ( flags ) & ( flag ) ) \ - TEST_ASSERT( PSA_##flag( alg ) ); \ - else \ - TEST_ASSERT( ! PSA_##flag( alg ) ); \ - } \ +/* Check that in the value of flags, the bit flag (which should be a macro + * expanding to a number of the form 1 << k) is set if and only if + * PSA_##flag(alg) is true. + * + * Only perform this check if cond is true. Typically cond is 1, but it can + * be different if the value of the flag bit is only specified under specific + * conditions. + * + * Unconditionally mask flag into the ambient variable + * classification_flags_tested. + */ +#define TEST_CLASSIFICATION_MACRO( cond, flag, alg, flags ) \ + do \ + { \ + if( cond ) \ + { \ + if( ( flags ) & ( flag ) ) \ + TEST_ASSERT( PSA_##flag( alg ) ); \ + else \ + TEST_ASSERT( ! PSA_##flag( alg ) ); \ + } \ + classification_flags_tested |= ( flag ); \ + } \ while( 0 ) /* Check the parity of value. @@ -98,45 +116,50 @@ int has_even_parity( uint32_t value ) void algorithm_classification( psa_algorithm_t alg, unsigned flags ) { - TEST_CLASSIFICATION_MACRO( ALG_IS_VENDOR_DEFINED, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_HMAC, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_BLOCK_CIPHER_MAC, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_STREAM_CIPHER, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_PKCS1V15_SIGN, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_PSS, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_DSA, alg, flags ); - if ( PSA_ALG_IS_DSA( alg ) ) - TEST_CLASSIFICATION_MACRO( ALG_DSA_IS_DETERMINISTIC, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_DETERMINISTIC_DSA, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_RANDOMIZED_DSA, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_ECDSA, alg, flags ); - if ( PSA_ALG_IS_ECDSA( alg ) ) - TEST_CLASSIFICATION_MACRO( ALG_ECDSA_IS_DETERMINISTIC, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_DETERMINISTIC_ECDSA, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_RANDOMIZED_ECDSA, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_HASH_EDDSA, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_SIGN_HASH, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_HASH_AND_SIGN, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_OAEP, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_HKDF, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_WILDCARD, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_ECDH, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_FFDH, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_RAW_KEY_AGREEMENT, alg, flags ); - TEST_CLASSIFICATION_MACRO( ALG_IS_AEAD_ON_BLOCK_CIPHER, alg, flags ); + unsigned classification_flags_tested = 0; + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_VENDOR_DEFINED, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HMAC, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_BLOCK_CIPHER_MAC, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_STREAM_CIPHER, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PKCS1V15_SIGN, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DSA, alg, flags ); + TEST_CLASSIFICATION_MACRO( PSA_ALG_IS_DSA( alg ), + ALG_DSA_IS_DETERMINISTIC, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DETERMINISTIC_DSA, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RANDOMIZED_DSA, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_ECDSA, alg, flags ); + TEST_CLASSIFICATION_MACRO( PSA_ALG_IS_ECDSA( alg ), + ALG_ECDSA_IS_DETERMINISTIC, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DETERMINISTIC_ECDSA, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RANDOMIZED_ECDSA, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HASH_EDDSA, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_SIGN_HASH, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HASH_AND_SIGN, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_OAEP, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HKDF, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_WILDCARD, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_ECDH, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_FFDH, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RAW_KEY_AGREEMENT, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_AEAD_ON_BLOCK_CIPHER, alg, flags ); + TEST_EQUAL( classification_flags_tested, ALG_FLAG_MASK_PLUS_ONE - 1 ); exit: ; } void key_type_classification( psa_key_type_t type, unsigned flags ) { + unsigned classification_flags_tested = 0; + /* Macros tested based on the test case parameter */ - TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_VENDOR_DEFINED, type, flags ); - TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_UNSTRUCTURED, type, flags ); - TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_PUBLIC_KEY, type, flags ); - TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_KEY_PAIR, type, flags ); - TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_RSA, type, flags ); - TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_ECC, type, flags ); - TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_DH, type, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_VENDOR_DEFINED, type, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_UNSTRUCTURED, type, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_PUBLIC_KEY, type, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_KEY_PAIR, type, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_RSA, type, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_ECC, type, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_DH, type, flags ); + TEST_EQUAL( classification_flags_tested, KEY_TYPE_FLAG_MASK_PLUS_ONE - 1 ); /* Macros with derived semantics */ TEST_EQUAL( PSA_KEY_TYPE_IS_ASYMMETRIC( type ), @@ -672,9 +695,12 @@ void lifetime( int lifetime_arg, int classification_flags, psa_key_persistence_t persistence = persistence_arg; psa_key_location_t location = location_arg; unsigned flags = classification_flags; + unsigned classification_flags_tested = 0; - TEST_CLASSIFICATION_MACRO( KEY_LIFETIME_IS_VOLATILE, lifetime, flags ); - TEST_CLASSIFICATION_MACRO( KEY_LIFETIME_IS_READ_ONLY, lifetime, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_LIFETIME_IS_VOLATILE, lifetime, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_LIFETIME_IS_READ_ONLY, lifetime, flags ); + TEST_EQUAL( classification_flags_tested, + KEY_LIFETIME_FLAG_MASK_PLUS_ONE - 1 ); TEST_EQUAL( PSA_KEY_LIFETIME_GET_PERSISTENCE( lifetime ), persistence ); TEST_EQUAL( PSA_KEY_LIFETIME_GET_LOCATION( lifetime ), location ); From adcfdbf2c6187f647382f368baa30d947083c6b6 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 3 Nov 2021 13:56:47 +0100 Subject: [PATCH 14/14] Fix test bug: some classification flags were not tested Signed-off-by: Gilles Peskine --- tests/suites/test_suite_psa_crypto_metadata.function | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function index 3cbc6ba76..f2ba16a28 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -123,6 +123,8 @@ void algorithm_classification( psa_algorithm_t alg, unsigned flags ) TEST_CLASSIFICATION_MACRO( 1, ALG_IS_STREAM_CIPHER, alg, flags ); TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PKCS1V15_SIGN, alg, flags ); TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS_ANY_SALT, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS_STANDARD_SALT, alg, flags ); TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DSA, alg, flags ); TEST_CLASSIFICATION_MACRO( PSA_ALG_IS_DSA( alg ), ALG_DSA_IS_DETERMINISTIC, alg, flags ); @@ -143,6 +145,8 @@ void algorithm_classification( psa_algorithm_t alg, unsigned flags ) TEST_CLASSIFICATION_MACRO( 1, ALG_IS_FFDH, alg, flags ); TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RAW_KEY_AGREEMENT, alg, flags ); TEST_CLASSIFICATION_MACRO( 1, ALG_IS_AEAD_ON_BLOCK_CIPHER, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_TLS12_PRF, alg, flags ); + TEST_CLASSIFICATION_MACRO( 1, ALG_IS_TLS12_PSK_TO_MS, alg, flags ); TEST_EQUAL( classification_flags_tested, ALG_FLAG_MASK_PLUS_ONE - 1 ); exit: ; } @@ -157,6 +161,7 @@ void key_type_classification( psa_key_type_t type, unsigned flags ) TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_PUBLIC_KEY, type, flags ); TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_KEY_PAIR, type, flags ); TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_RSA, type, flags ); + TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_DSA, type, flags ); TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_ECC, type, flags ); TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_DH, type, flags ); TEST_EQUAL( classification_flags_tested, KEY_TYPE_FLAG_MASK_PLUS_ONE - 1 );