From acd2d0e92389a7e64a7d8d1b7d3e1d2077124dfb Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Oct 2021 18:10:38 +0200 Subject: [PATCH] New algorithm PSA_ALG_RSA_PSS_ANY_SALT This is a variant of PSA_ALG_RSA_PSS which currently has exactly the same behavior, but is intended to have a different behavior when verifying signatures. In a subsequent commit, PSA_ALG_RSA_PSS will change to requiring the salt length to be what it would produce when signing, as is currently documented, whereas PSA_ALG_RSA_PSS_ANY_SALT will retain the current behavior of allowing any salt length (including 0). Changes in this commit: * New algorithm constructor PSA_ALG_RSA_PSS_ANY_SALT. * New predicates PSA_ALG_IS_RSA_PSS_STANDARD_SALT (corresponding to PSA_ALG_RSA_PSS) and PSA_ALG_IS_RSA_PSS_ANY_SALT (corresponding to PSA_ALG_RSA_PSS_ANY_SALT). * Support for the new predicates in macro_collector.py (needed for generate_psa_constant_names). Signed-off-by: Gilles Peskine --- include/psa/crypto_values.h | 68 ++++++++++++++++++- scripts/mbedtls_dev/macro_collector.py | 2 + .../test_suite_psa_crypto_metadata.data | 8 +++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index daef9416c..aa7d02ef3 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -886,7 +886,7 @@ * algorithm parametrized with any supported hash. * * That is, suppose that `PSA_xxx_SIGNATURE` is one of the following macros: - * - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS, + * - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS, #PSA_ALG_RSA_PSS_ANY_SALT, * - #PSA_ALG_ECDSA, #PSA_ALG_DETERMINISTIC_ECDSA. * Then you may create and use a key as follows: * - Set the key usage field using #PSA_ALG_ANY_HASH, for example: @@ -1341,6 +1341,7 @@ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE) #define PSA_ALG_RSA_PSS_BASE ((psa_algorithm_t)0x06000300) +#define PSA_ALG_RSA_PSS_ANY_SALT_BASE ((psa_algorithm_t)0x06001300) /** RSA PSS signature with hashing. * * This is the signature scheme defined by RFC 8017 @@ -1361,9 +1362,72 @@ */ #define PSA_ALG_RSA_PSS(hash_alg) \ (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_IS_RSA_PSS(alg) \ + +/** RSA PSS signature with hashing with relaxed verification. + * + * This algorithm has the same behavior as #PSA_ALG_RSA_PSS when signing, + * but allows an arbitrary salt length (including \c 0) when verifying a + * signature. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * This includes #PSA_ALG_ANY_HASH + * when specifying the algorithm in a usage policy. + * + * \return The corresponding RSA PSS signature algorithm. + * \return Unspecified if \p hash_alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_RSA_PSS_ANY_SALT(hash_alg) \ + (PSA_ALG_RSA_PSS_ANY_SALT_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) + +/** Whether the specified algorithm is RSA PSS with standard salt. + * + * \param alg An algorithm value or an algorithm policy wildcard. + * + * \return 1 if \p alg is of the form + * #PSA_ALG_RSA_PSS(\c hash_alg), + * where \c hash_alg is a hash algorithm or + * #PSA_ALG_ANY_HASH. 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not + * a supported algorithm identifier or policy. + */ +#define PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg) \ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE) +/** Whether the specified algorithm is RSA PSS with any salt. + * + * \param alg An algorithm value or an algorithm policy wildcard. + * + * \return 1 if \p alg is of the form + * #PSA_ALG_RSA_PSS_ANY_SALT_BASE(\c hash_alg), + * where \c hash_alg is a hash algorithm or + * #PSA_ALG_ANY_HASH. 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not + * a supported algorithm identifier or policy. + */ +#define PSA_ALG_IS_RSA_PSS_ANY_SALT(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_ANY_SALT_BASE) + +/** Whether the specified algorithm is RSA PSS. + * + * This includes any of the RSA PSS algorithm variants, regardless of the + * constraints on salt length. + * + * \param alg An algorithm value or an algorithm policy wildcard. + * + * \return 1 if \p alg is of the form + * #PSA_ALG_RSA_PSS(\c hash_alg) or + * #PSA_ALG_RSA_PSS_ANY_SALT_BASE(\c hash_alg), + * where \c hash_alg is a hash algorithm or + * #PSA_ALG_ANY_HASH. 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not + * a supported algorithm identifier or policy. + */ +#define PSA_ALG_IS_RSA_PSS(alg) \ + ((((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE) || \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_ANY_SALT_BASE)) + #define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x06000600) /** ECDSA signature with hashing. * diff --git a/scripts/mbedtls_dev/macro_collector.py b/scripts/mbedtls_dev/macro_collector.py index bd2d296c0..bf82f13dc 100644 --- a/scripts/mbedtls_dev/macro_collector.py +++ b/scripts/mbedtls_dev/macro_collector.py @@ -250,6 +250,8 @@ class PSAMacroCollector(PSAMacroEnumerator): suffix = name[len(prefix):] if suffix in ['DSA', 'ECDSA']: midfix += 'RANDOMIZED_' + elif suffix == 'RSA_PSS': + suffix += '_STANDARD_SALT' return prefix + midfix + suffix def record_algorithm_subtype(self, name: str, expansion: str) -> None: diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data index a3668fcc9..f2b43741a 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.data +++ b/tests/suites/test_suite_psa_crypto_metadata.data @@ -182,6 +182,10 @@ 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_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_HASH_AND_SIGN + 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 @@ -214,6 +218,10 @@ Asymmetric signature: RSA PSS with wildcard hash depends_on:PSA_WANT_ALG_RSA_PSS asymmetric_signature_wildcard:PSA_ALG_RSA_PSS( PSA_ALG_ANY_HASH ):ALG_IS_RSA_PSS +Asymmetric signature: RSA PSS-any-salt with wildcard hash +depends_on:PSA_WANT_ALG_RSA_PSS +asymmetric_signature_wildcard:PSA_ALG_RSA_PSS_ANY_SALT( PSA_ALG_ANY_HASH ):ALG_IS_RSA_PSS + Asymmetric signature: randomized ECDSA with wildcard hash depends_on:PSA_WANT_ALG_ECDSA asymmetric_signature_wildcard:PSA_ALG_ECDSA( PSA_ALG_ANY_HASH ):ALG_IS_ECDSA | ALG_IS_RANDOMIZED_ECDSA