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 <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine 2021-09-22 16:15:05 +02:00
parent c1ec49eb13
commit f7b4137e69
6 changed files with 47 additions and 29 deletions

View file

@ -1597,7 +1597,20 @@
* Hash-and-sign algorithms are asymmetric (public-key) signature algorithms * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms
* structured in two parts: first the calculation of a hash in a way that * 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 * 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). * \param alg An algorithm identifier (value of type #psa_algorithm_t).
* *
@ -1606,9 +1619,8 @@
* algorithm identifier. * algorithm identifier.
*/ */
#define PSA_ALG_IS_HASH_AND_SIGN(alg) \ #define PSA_ALG_IS_HASH_AND_SIGN(alg) \
(PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ (PSA_ALG_IS_SIGN_HASH(alg) && \
PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ ((alg) & PSA_ALG_HASH_MASK) != 0)
PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg))
/** Whether the specified algorithm is a signature algorithm that can be used /** Whether the specified algorithm is a signature algorithm that can be used
* with psa_sign_message() and psa_verify_message(). * with psa_sign_message() and psa_verify_message().
@ -1622,11 +1634,17 @@
* supported algorithm identifier. * supported algorithm identifier.
*/ */
#define PSA_ALG_IS_SIGN_MESSAGE(alg) \ #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 /** Whether the specified algorithm is a signature algorithm that can be used
* with psa_sign_hash() and psa_verify_hash(). * 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). * \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 * \return 1 if alg is a signature algorithm that can be used to sign a
@ -1636,8 +1654,9 @@
* supported algorithm identifier. * supported algorithm identifier.
*/ */
#define PSA_ALG_IS_SIGN_HASH(alg) \ #define PSA_ALG_IS_SIGN_HASH(alg) \
(PSA_ALG_IS_HASH_AND_SIGN(alg) || (alg) == PSA_ALG_ED25519PH || \ (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
(alg) == PSA_ALG_ED448PH) 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. /** Get the hash used by a hash-and-sign signature algorithm.
* *
@ -1659,7 +1678,6 @@
*/ */
#define PSA_ALG_SIGN_GET_HASH(alg) \ #define PSA_ALG_SIGN_GET_HASH(alg) \
(PSA_ALG_IS_HASH_AND_SIGN(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 : \ ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \
0) 0)

View file

@ -623,8 +623,8 @@ static psa_algorithm_t psa_key_policy_algorithm_intersection(
return( alg1 ); return( alg1 );
/* If the policies are from the same hash-and-sign family, check /* 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 one is a wildcard. If so the other has the specific algorithm. */
if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) && if( PSA_ALG_IS_SIGN_HASH( alg1 ) &&
PSA_ALG_IS_HASH_AND_SIGN( alg2 ) && PSA_ALG_IS_SIGN_HASH( alg2 ) &&
( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) ) ( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
{ {
if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH ) if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
@ -726,7 +726,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, /* 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, * and requested_alg is the same hash-and-sign family with any hash,
* then requested_alg is compliant with policy_alg. */ * 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 ) PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
{ {
return( ( policy_alg & ~PSA_ALG_HASH_MASK ) == return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
@ -2644,7 +2644,7 @@ static psa_status_t psa_sign_verify_check_alg( int input_is_message,
if( ! PSA_ALG_IS_SIGN_MESSAGE( alg ) ) if( ! PSA_ALG_IS_SIGN_MESSAGE( alg ) )
return( PSA_ERROR_INVALID_ARGUMENT ); 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 ) ) ) if( ! PSA_ALG_IS_HASH( PSA_ALG_SIGN_GET_HASH( alg ) ) )
return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_INVALID_ARGUMENT );
@ -2802,7 +2802,7 @@ psa_status_t psa_sign_message_builtin(
{ {
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 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; size_t hash_length;
uint8_t hash[PSA_HASH_MAX_SIZE]; uint8_t hash[PSA_HASH_MAX_SIZE];
@ -2849,7 +2849,7 @@ psa_status_t psa_verify_message_builtin(
{ {
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 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; size_t hash_length;
uint8_t hash[PSA_HASH_MAX_SIZE]; uint8_t hash[PSA_HASH_MAX_SIZE];

View file

@ -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 ); psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
/* If the policy allows signing with any hash, just pick one. */ /* 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) #if defined(KNOWN_SUPPORTED_HASH_ALG)
hash_alg = 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_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 ) ) if( PSA_ALG_SIGN_GET_HASH( alg ) )
return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ? return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?

View file

@ -1422,7 +1422,7 @@ void asymmetric_signature_key_policy( int policy_usage_arg,
else else
TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); 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 ) ) ) PSA_ALG_IS_HASH( PSA_ALG_SIGN_GET_HASH( exercise_alg ) ) )
{ {
status = psa_sign_message( key, exercise_alg, status = psa_sign_message( key, exercise_alg,

View file

@ -196,31 +196,31 @@ aead_algorithm:PSA_ALG_CHACHA20_POLY1305:0:16:PSA_KEY_TYPE_CHACHA20:256
Asymmetric signature: RSA PKCS#1 v1.5 raw Asymmetric signature: RSA PKCS#1 v1.5 raw
depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN 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 Asymmetric signature: RSA PKCS#1 v1.5 SHA-256
depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_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 Asymmetric signature: RSA PSS SHA-256
depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_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 Asymmetric signature: RSA PSS-any-salt SHA-256
depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_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) Asymmetric signature: randomized ECDSA (no hashing)
depends_on:PSA_WANT_ALG_ECDSA 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 Asymmetric signature: SHA-256 + randomized ECDSA
depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256 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 Asymmetric signature: SHA-256 + deterministic ECDSA using SHA-256
depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_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 Asymmetric signature: pure EdDSA
depends_on:PSA_WANT_ALG_EDDSA depends_on:PSA_WANT_ALG_EDDSA
@ -228,11 +228,11 @@ asymmetric_signature_algorithm:PSA_ALG_PURE_EDDSA:0
Asymmetric signature: Ed25519ph Asymmetric signature: Ed25519ph
depends_on:PSA_WANT_ALG_EDDSA 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 Asymmetric signature: Ed448ph
depends_on:PSA_WANT_ALG_EDDSA 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 Asymmetric signature: RSA PKCS#1 v1.5 with wildcard hash
depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN

View file

@ -33,7 +33,7 @@
#define ALG_IS_DETERMINISTIC_ECDSA ( 1u << 14 ) #define ALG_IS_DETERMINISTIC_ECDSA ( 1u << 14 )
#define ALG_IS_RANDOMIZED_ECDSA ( 1u << 15 ) #define ALG_IS_RANDOMIZED_ECDSA ( 1u << 15 )
#define ALG_IS_HASH_EDDSA ( 1u << 16 ) #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_RSA_OAEP ( 1u << 18 )
#define ALG_IS_HKDF ( 1u << 19 ) #define ALG_IS_HKDF ( 1u << 19 )
#define ALG_IS_FFDH ( 1u << 20 ) #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_DETERMINISTIC_ECDSA, alg, flags );
TEST_CLASSIFICATION_MACRO( ALG_IS_RANDOMIZED_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_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_RSA_OAEP, alg, flags );
TEST_CLASSIFICATION_MACRO( ALG_IS_HKDF, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_HKDF, alg, flags );
TEST_CLASSIFICATION_MACRO( ALG_IS_WILDCARD, alg, flags ); TEST_CLASSIFICATION_MACRO( ALG_IS_WILDCARD, alg, flags );
@ -490,7 +490,7 @@ void asymmetric_signature_algorithm( int alg_arg, int classification_flags )
/* BEGIN_CASE */ /* BEGIN_CASE */
void asymmetric_signature_wildcard( int alg_arg, int classification_flags ) 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 ); test_asymmetric_signature_algorithm( alg_arg, classification_flags );
/* Any failure of this test function comes from /* Any failure of this test function comes from
* asymmetric_signature_algorithm. Pacify -Werror=unused-label. */ * asymmetric_signature_algorithm. Pacify -Werror=unused-label. */