From 95370ba50d435f6fc7ba6f9219ba001f332d43dc Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Tue, 26 Jan 2021 17:26:28 +0100 Subject: [PATCH] Add support for key policies in addition to specific algorithms Initially contributed: minimum-tag-length AEAD and MAC policies. Includes tests. Signed-off-by: Steven Cooreman --- ChangeLog.d/psa-crypto-key-policies.txt | 5 + include/psa/crypto.h | 2 + include/psa/crypto_values.h | 135 ++++++++++++++++++-- library/psa_crypto.c | 23 ++++ tests/suites/test_suite_psa_crypto.data | 66 ++++++++-- tests/suites/test_suite_psa_crypto.function | 35 ++--- 6 files changed, 226 insertions(+), 40 deletions(-) create mode 100644 ChangeLog.d/psa-crypto-key-policies.txt diff --git a/ChangeLog.d/psa-crypto-key-policies.txt b/ChangeLog.d/psa-crypto-key-policies.txt new file mode 100644 index 000000000..6fe180aa4 --- /dev/null +++ b/ChangeLog.d/psa-crypto-key-policies.txt @@ -0,0 +1,5 @@ +Features + * A key in PSA Crypto can now be defined with a policy instead of a specific + algorithm. Policies describe a collection of allowed specific algorithms. + Initial policies are PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH and + PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH. diff --git a/include/psa/crypto.h b/include/psa/crypto.h index b41a20bfc..58d366b63 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -260,6 +260,8 @@ static psa_key_usage_t psa_get_key_usage_flags( * - An algorithm value permits this particular algorithm. * - An algorithm wildcard built from #PSA_ALG_ANY_HASH allows the specified * signature scheme with any hash algorithm. + * - An algorithm with the #PSA_ALG_POLICY_FLAG bit set allows the + * algorithm collection specified by that algorithm policy definition. * * This function overwrites any algorithm policy * previously set in \p attributes. diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index 9610d5f55..3261b6304 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -608,7 +608,17 @@ */ #define PSA_ALG_VENDOR_FLAG ((psa_algorithm_t)0x80000000) -#define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t)0x7f000000) +/** Policy-only flag. + * + * An algorithm defined by this standard can have the #PSA_ALG_POLICY_FLAG bit + * set to indicate the value can only be used in a usage policy definition. + * The use case is primarily defining key usage policies, where a policy can + * encompass more than one specific algorithm, e.g. AEAD or MAC algorithms + * with multiple tag lengths. + */ +#define PSA_ALG_POLICY_FLAG ((psa_algorithm_t)0x40000000) + +#define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t)0x3f000000) #define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t)0x02000000) #define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x03000000) #define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t)0x04000000) @@ -625,6 +635,13 @@ #define PSA_ALG_IS_VENDOR_DEFINED(alg) \ (((alg) & PSA_ALG_VENDOR_FLAG) != 0) +/** Whether an algorithm is a policy (collection of algorithms). + * + * See also #PSA_ALG_POLICY_FLAG. + */ +#define PSA_ALG_IS_POLICY(alg) \ + (((alg) & PSA_ALG_POLICY_FLAG) != 0) + /** Whether the specified algorithm is a hash algorithm. * * \param alg An algorithm identifier (value of type #psa_algorithm_t). @@ -634,7 +651,8 @@ * algorithm identifier. */ #define PSA_ALG_IS_HASH(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH) + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH) && \ + !PSA_ALG_IS_POLICY(alg)) /** Whether the specified algorithm is a MAC algorithm. * @@ -645,7 +663,23 @@ * algorithm identifier. */ #define PSA_ALG_IS_MAC(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC) + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC) && \ + !PSA_ALG_IS_POLICY(alg)) + +/** Whether the specified algorithm is a policy containing a MAC + * algorithm collection, sharing the same base algorithm but multiple + * allowed tag lengths. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a MAC algorithm policy with minimum tag length, + * 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH(alg) \ + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC) && \ + PSA_ALG_IS_POLICY(alg)) /** Whether the specified algorithm is a symmetric cipher algorithm. * @@ -656,7 +690,8 @@ * algorithm identifier. */ #define PSA_ALG_IS_CIPHER(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER) + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER) && \ + !PSA_ALG_IS_POLICY(alg)) /** Whether the specified algorithm is an authenticated encryption * with associated data (AEAD) algorithm. @@ -668,7 +703,23 @@ * algorithm identifier. */ #define PSA_ALG_IS_AEAD(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD) + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD) && \ + !PSA_ALG_IS_POLICY(alg)) + +/** Whether the specified algorithm is a policy containing an authenticated + * encryption with associated data (AEAD) algorithm collection, sharing the + * same base algorithm but multiple allowed tag lengths. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is an AEAD algorithm policy with minimum tag length, + * 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH(alg) \ + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD) && \ + PSA_ALG_IS_POLICY(alg)) /** Whether the specified algorithm is an asymmetric signature algorithm, * also known as public-key signature algorithm. @@ -680,7 +731,8 @@ * algorithm identifier. */ #define PSA_ALG_IS_SIGN(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN) + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN) && \ + !PSA_ALG_IS_POLICY(alg)) /** Whether the specified algorithm is an asymmetric encryption algorithm, * also known as public-key encryption algorithm. @@ -692,7 +744,8 @@ * algorithm identifier. */ #define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION) + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION) && \ + !PSA_ALG_IS_POLICY(alg)) /** Whether the specified algorithm is a key agreement algorithm. * @@ -702,8 +755,9 @@ * This macro may return either 0 or 1 if \p alg is not a supported * algorithm identifier. */ -#define PSA_ALG_IS_KEY_AGREEMENT(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT) +#define PSA_ALG_IS_KEY_AGREEMENT(alg) \ + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT) && \ + !PSA_ALG_IS_POLICY(alg)) /** Whether the specified algorithm is a key derivation algorithm. * @@ -713,8 +767,9 @@ * This macro may return either 0 or 1 if \p alg is not a supported * algorithm identifier. */ -#define PSA_ALG_IS_KEY_DERIVATION(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) +#define PSA_ALG_IS_KEY_DERIVATION(alg) \ + ((((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) && \ + !PSA_ALG_IS_POLICY(alg)) #define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) /** MD2 */ @@ -914,6 +969,27 @@ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \ PSA_ALG_CIPHER_MAC_BASE) +/** Macro to build a MAC minimum-tag-length algorithm policy. + * + * A mininimum-tag-length MAC algorithm policy contains all MAC algorithms + * sharing the same base algorithm, and where the tag length of the specific + * algorithm is equal to or larger then the policy's minimum tag length. + * + * \param mac_alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) + * is true). + * \param tag_length Desired minimum length of the authentication tag in + * bytes. + * + * \return The corresponding MAC algorithm policy with the + * specified minimum length. + * \return Unspecified if \p alg is not a supported + * MAC algorithm or if \p tag_length is not valid + * for the specified MAC algorithm. + */ +#define PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH(mac_alg, tag_length) \ + ( PSA_ALG_TRUNCATED_MAC(mac_alg, tag_length) | PSA_ALG_POLICY_FLAG ) + #define PSA_ALG_CIPHER_STREAM_FLAG ((psa_algorithm_t)0x00800000) #define PSA_ALG_CIPHER_FROM_BLOCK_FLAG ((psa_algorithm_t)0x00400000) @@ -1075,6 +1151,21 @@ ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \ PSA_ALG_AEAD_TAG_LENGTH_MASK)) +/** Retrieve the tag length of a specified AEAD algorithm + * + * \param aead_alg An AEAD algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p alg) + * is true). + * + * \return The tag length specified by the input algorithm. + * \return Unspecified if \p alg is not a supported + * AEAD algorithm or if \p tag_length is not valid + * for the specified AEAD algorithm. + */ +#define PSA_ALG_AEAD_GET_TAG_LENGTH(aead_alg) \ + (((aead_alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> \ + PSA_AEAD_TAG_LENGTH_OFFSET ) + /** Calculate the corresponding AEAD algorithm with the default tag length. * * \param aead_alg An AEAD algorithm (\c PSA_ALG_XXX value such that @@ -1094,6 +1185,28 @@ PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \ ref : +/** Macro to build an AEAD minimum-tag-length algorithm policy. + * + * A mininimum-tag-length AEAD algorithm policy contains all AEAD algorithms + * sharing the same base algorithm, and where the tag length of the specific + * algorithm is equal to or larger then the policy's minimum tag length. + * + * \param aead_alg An AEAD algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p alg) + * is true). + * \param tag_length Desired minimum length of the authentication tag in + * bytes. + * + * \return The corresponding AEAD algorithm policy with the + * specified minimum length. + * \return Unspecified if \p alg is not a supported + * AEAD algorithm or if \p tag_length is not valid + * for the specified AEAD algorithm. + */ +#define PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH(aead_alg, tag_length) \ + ( PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, tag_length) | \ + PSA_ALG_POLICY_FLAG ) + #define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x06000200) /** RSA PKCS#1 v1.5 signature with hashing. * diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 7ea2a1a9a..51e8bbbc9 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1179,6 +1179,9 @@ static psa_algorithm_t psa_key_policy_algorithm_intersection( static int psa_key_algorithm_permits( psa_algorithm_t policy_alg, psa_algorithm_t requested_alg ) { + /* A requested algorithm cannot be a collection. */ + if( PSA_ALG_IS_POLICY( requested_alg ) ) + return( 0 ); /* Common case: the policy only allows requested_alg. */ if( requested_alg == policy_alg ) return( 1 ); @@ -1200,6 +1203,26 @@ static int psa_key_algorithm_permits( psa_algorithm_t policy_alg, return( PSA_ALG_KEY_AGREEMENT_GET_BASE( requested_alg ) == policy_alg ); } + /* If policy_alg is a policy, then special rules apply. */ + if( PSA_ALG_IS_POLICY( policy_alg ) ) + { + if( PSA_ALG_IS_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH( policy_alg ) && + PSA_ALG_IS_AEAD( requested_alg ) && + ( PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH( requested_alg, 0 ) == + PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH( policy_alg, 0 ) ) ) + { + return( PSA_ALG_AEAD_GET_TAG_LENGTH( policy_alg ) <= + PSA_ALG_AEAD_GET_TAG_LENGTH( requested_alg ) ); + } + if( PSA_ALG_IS_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH( policy_alg ) && + PSA_ALG_IS_MAC( requested_alg ) && + ( PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH( requested_alg, 0 ) == + PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH( policy_alg, 0 ) ) ) + { + return( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) <= + PSA_MAC_TRUNCATED_LENGTH( requested_alg ) ); + } + } /* If it isn't permitted, it's forbidden. */ return( 0 ); } diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index f267c1587..fe589db9b 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -393,31 +393,51 @@ key_attributes_init: PSA key policy: MAC, sign | verify depends_on:MBEDTLS_SHA256_C -mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS PSA key policy: MAC, wrong algorithm depends_on:MBEDTLS_SHA256_C -mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224) +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224):PSA_ERROR_NOT_PERMITTED PSA key policy: MAC, alg=0 in policy depends_on:MBEDTLS_SHA256_C -mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:0:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED PSA key policy: MAC, ANY_HASH in policy is not meaningful depends_on:MBEDTLS_SHA256_C -mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED PSA key policy: MAC, sign but not verify depends_on:MBEDTLS_SHA256_C -mac_key_policy:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS PSA key policy: MAC, verify but not sign depends_on:MBEDTLS_SHA256_C -mac_key_policy:PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) +mac_key_policy:PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS PSA key policy: MAC, neither sign nor verify depends_on:MBEDTLS_SHA256_C -mac_key_policy:0:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) +mac_key_policy:0:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_NOT_PERMITTED + +PSA key policy: MAC, sign-verify, policy smaller than alg +depends_on:MBEDTLS_SHA256_C +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 30):PSA_SUCCESS + +PSA key policy: MAC, sign-verify, policy same-length as alg +depends_on:MBEDTLS_SHA256_C +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_SUCCESS + +PSA key policy: MAC, sign-verify, policy larger than alg +depends_on:MBEDTLS_SHA256_C +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_256), 10):PSA_ERROR_NOT_PERMITTED + +PSA key policy: MAC, sign-verify, policy alg does not match base alg +depends_on:MBEDTLS_SHA256_C:MBEDTLS_CMAC_C +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 20):PSA_ERROR_NOT_PERMITTED + +PSA key policy: MAC, sign-verify, exercise with policy +depends_on:MBEDTLS_SHA256_C +mac_key_policy:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_MAC_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_HMAC(PSA_ALG_SHA_256), 20):PSA_ERROR_NOT_PERMITTED PSA key policy: cipher, encrypt | decrypt depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR @@ -445,27 +465,47 @@ cipher_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:PSA_KEY_TYPE_A PSA key policy: AEAD, encrypt | decrypt depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C -aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM:PSA_SUCCESS PSA key policy: AEAD, wrong algorithm depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_GCM_C -aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":16:16:PSA_ALG_GCM +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":16:16:PSA_ALG_GCM:PSA_ERROR_NOT_PERMITTED PSA key policy: AEAD, alg=0 in policy depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C -aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":16:16:PSA_ALG_CCM +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":16:16:PSA_ALG_CCM:PSA_ERROR_NOT_PERMITTED PSA key policy: AEAD, encrypt but not decrypt depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C -aead_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM +aead_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM:PSA_SUCCESS PSA key policy: AEAD, decrypt but not encrypt depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C -aead_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM +aead_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM:PSA_SUCCESS PSA key policy: AEAD, neither encrypt nor decrypt depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C -aead_key_policy:0:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM +aead_key_policy:0:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM:PSA_ERROR_NOT_PERMITTED + +PSA key policy: AEAD, exercise policy with larger tag length alg +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_CCM, 4):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:8:PSA_ALG_AEAD_WITH_TAG_LENGTH(PSA_ALG_CCM, 8):PSA_SUCCESS + +PSA key policy: AEAD, exercise policy with same-length alg +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_CCM, 4):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:4:PSA_ALG_AEAD_WITH_TAG_LENGTH(PSA_ALG_CCM, 4):PSA_SUCCESS + +PSA key policy: AEAD, exercise policy with lesser-length alg +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_CCM, 8):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:4:PSA_ALG_AEAD_WITH_TAG_LENGTH(PSA_ALG_CCM, 4):PSA_ERROR_NOT_PERMITTED + +PSA key policy: AEAD, exercise policy with different base alg +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_GCM_C +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_CCM, 4):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:4:PSA_ALG_AEAD_WITH_TAG_LENGTH(PSA_ALG_GCM, 4):PSA_ERROR_NOT_PERMITTED + +PSA key policy: AEAD, exercise algorithm with a policy +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_CCM, 8):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:8:PSA_ALG_AEAD_POLICY_WITH_MINIMUM_TAG_LENGTH(PSA_ALG_CCM, 8):PSA_ERROR_NOT_PERMITTED PSA key policy: asymmetric encryption, encrypt | decrypt depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 8e71610ac..88d9d66ba 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1956,12 +1956,14 @@ void mac_key_policy( int policy_usage, int policy_alg, int key_type, data_t *key_data, - int exercise_alg ) + int exercise_alg, + int expected_status_arg ) { mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; psa_status_t status; + psa_status_t expected_status = expected_status_arg; unsigned char mac[PSA_MAC_MAX_SIZE]; PSA_ASSERT( psa_crypto_init( ) ); @@ -1974,20 +1976,19 @@ void mac_key_policy( int policy_usage, &key ) ); status = psa_mac_sign_setup( &operation, key, exercise_alg ); - if( policy_alg == exercise_alg && - ( policy_usage & PSA_KEY_USAGE_SIGN_HASH ) != 0 ) - PSA_ASSERT( status ); - else + if( ( policy_usage & PSA_KEY_USAGE_SIGN_HASH ) == 0 ) TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); + else + TEST_EQUAL( status, expected_status ); + psa_mac_abort( &operation ); memset( mac, 0, sizeof( mac ) ); status = psa_mac_verify_setup( &operation, key, exercise_alg ); - if( policy_alg == exercise_alg && - ( policy_usage & PSA_KEY_USAGE_VERIFY_HASH ) != 0 ) - PSA_ASSERT( status ); - else + if( ( policy_usage & PSA_KEY_USAGE_VERIFY_HASH ) == 0 ) TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); + else + TEST_EQUAL( status, expected_status ); exit: psa_mac_abort( &operation ); @@ -2046,11 +2047,13 @@ void aead_key_policy( int policy_usage, data_t *key_data, int nonce_length_arg, int tag_length_arg, - int exercise_alg ) + int exercise_alg, + int expected_status_arg ) { mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t status; + psa_status_t expected_status = expected_status_arg; unsigned char nonce[16] = {0}; size_t nonce_length = nonce_length_arg; unsigned char tag[16]; @@ -2075,9 +2078,8 @@ void aead_key_policy( int policy_usage, NULL, 0, tag, tag_length, &output_length ); - if( policy_alg == exercise_alg && - ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 ) - PSA_ASSERT( status ); + if( ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 ) + TEST_EQUAL( status, expected_status ); else TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); @@ -2088,11 +2090,12 @@ void aead_key_policy( int policy_usage, tag, tag_length, NULL, 0, &output_length ); - if( policy_alg == exercise_alg && - ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 ) + if( ( policy_usage & PSA_KEY_USAGE_DECRYPT ) == 0 ) + TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); + else if( expected_status == PSA_SUCCESS ) TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE ); else - TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); + TEST_EQUAL( status, expected_status ); exit: psa_destroy_key( key );