diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 6efaa0242..f344e1467 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -603,6 +603,7 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000) #define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x22000000) #define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x30000000) +#define PSA_ALG_CATEGORY_KEY_SELECTION ((psa_algorithm_t)0x31000000) #define PSA_ALG_IS_VENDOR_DEFINED(alg) \ (((alg) & PSA_ALG_VENDOR_FLAG) != 0) @@ -674,6 +675,7 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION) +#define PSA_ALG_KEY_SELECTION_FLAG ((psa_algorithm_t)0x01000000) /** Whether the specified algorithm is a key agreement algorithm. * * \param alg An algorithm identifier (value of type #psa_algorithm_t). @@ -683,7 +685,8 @@ typedef uint32_t psa_algorithm_t; * algorithm identifier. */ #define PSA_ALG_IS_KEY_AGREEMENT(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT) + (((alg) & PSA_ALG_CATEGORY_MASK & ~PSA_ALG_KEY_SELECTION_FLAG) == \ + PSA_ALG_CATEGORY_KEY_AGREEMENT) /** Whether the specified algorithm is a key derivation algorithm. * @@ -696,6 +699,17 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_IS_KEY_DERIVATION(alg) \ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) +/** Whether the specified algorithm is a key selection algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a key selection algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_KEY_SELECTION(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_SELECTION) + #define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) #define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001) #define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002) @@ -1185,6 +1199,25 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x010fffff) + +/** Use a shared secret as is. + * + * Specify this algorithm as the selection component of a key agreement + * to use the raw result of the key agreement as key material. + * + * \warning The raw result of a key agreement algorithm such as finite-field + * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should + * not be used directly as key material. It can however be used as the secret + * input in a key derivation algorithm. + */ +#define PSA_ALG_SELECT_RAW ((psa_algorithm_t)0x31000001) + +#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) \ + (((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION) + +#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \ + ((alg) & ~PSA_ALG_KEY_DERIVATION_MASK) /**@}*/ /** \defgroup key_management Key management diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 229fa81c5..5759a15df 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1377,7 +1377,11 @@ PSA key derivation: bad key type depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C derive_setup:PSA_KEY_TYPE_RAW_DATA:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_256):"":"":42:PSA_ERROR_INVALID_ARGUMENT -PSA key derivation: not a key derivation algorithm +PSA key derivation: not a key derivation algorithm (selection) +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_SELECT_RAW:"":"":42:PSA_ERROR_INVALID_ARGUMENT + +PSA key derivation: not a key derivation algorithm (HMAC) depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_256):"":"":42:PSA_ERROR_INVALID_ARGUMENT diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data index c9df6c74e..09544f4fb 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.data +++ b/tests/suites/test_suite_psa_crypto_metadata.data @@ -242,6 +242,8 @@ Key derivation: HKDF using SHA-256 depends_on:MBEDTLS_SHA256_C key_derivation_algorithm:PSA_ALG_HKDF( PSA_ALG_SHA_256 ):ALG_IS_HKDF +Key selection: raw +key_selection_algorithm:PSA_ALG_SELECT_RAW:0 Key type: raw data key_type:PSA_KEY_TYPE_RAW_DATA:KEY_TYPE_IS_UNSTRUCTURED diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function index 215110a32..4faa4341e 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -107,6 +107,7 @@ void mac_algorithm_core( psa_algorithm_t alg, int classification_flags, TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, classification_flags ); /* Length */ @@ -127,6 +128,7 @@ void aead_algorithm_core( psa_algorithm_t alg, int classification_flags, TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, classification_flags ); /* Tag length */ @@ -166,6 +168,7 @@ void hash_algorithm( int alg_arg, int length_arg ) TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, 0 ); /* Dependent algorithms */ @@ -262,6 +265,7 @@ void cipher_algorithm( int alg_arg, int classification_flags ) TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, classification_flags ); } /* END_CASE */ @@ -313,6 +317,7 @@ void asymmetric_signature_algorithm( int alg_arg, int classification_flags ) TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, classification_flags ); } /* END_CASE */ @@ -331,24 +336,7 @@ void asymmetric_encryption_algorithm( int alg_arg, int classification_flags ) TEST_ASSERT( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); - algorithm_classification( alg, classification_flags ); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void key_agreement_algorithm( int alg_arg, int classification_flags ) -{ - psa_algorithm_t alg = alg_arg; - - /* Algorithm classification */ - TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) ); - TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) ); - TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) ); - TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) ); - TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) ); - TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); - TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( alg ) ); - TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, classification_flags ); } /* END_CASE */ @@ -367,10 +355,57 @@ void key_derivation_algorithm( int alg_arg, int classification_flags ) TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, classification_flags ); } /* END_CASE */ +/* BEGIN_CASE */ +void key_selection_algorithm( int alg_arg, int classification_flags ) +{ + psa_algorithm_t alg = alg_arg; + + /* Algorithm classification */ + TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( PSA_ALG_IS_KEY_SELECTION( alg ) ); + algorithm_classification( alg, classification_flags ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void key_agreement_algorithm( int alg_arg, int classification_flags, + int post_alg_arg ) +{ + psa_algorithm_t alg = alg_arg; + psa_algorithm_t actual_post_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ); + psa_algorithm_t expected_post_alg = post_alg_arg; + + /* Algorithm classification */ + TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ); + TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); + TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); + algorithm_classification( alg, classification_flags ); + + /* Shared secret derivation properties */ + TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( actual_post_alg ) || + PSA_ALG_IS_KEY_SELECTION( actual_post_alg ) ); + TEST_ASSERT( actual_post_alg == expected_post_alg ); +} +/* END_CASE */ + /* BEGIN_CASE */ void key_type( int type_arg, int classification_flags ) {