diff --git a/include/psa/crypto.h b/include/psa/crypto.h index f344e1467..515e65f3d 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -1218,6 +1218,73 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \ ((alg) & ~PSA_ALG_KEY_DERIVATION_MASK) + +#define PSA_ALG_FFDH_BASE ((psa_algorithm_t)0x22100000) +/** The Diffie-Hellman key agreement algorithm. + * + * This algorithm combines the finite-field Diffie-Hellman-Merkle key + * agreement to produce a shared secret from a private key and the peer's + * public key, with a key selection or key derivation algorithm to produce + * one or more shared keys and other shared cryptographic material. + * + * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true) + * or a key selection algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_SELECTION(\p hash_alg) is true). + * + * \return The Diffie-Hellman algorithm with the specified + * selection or derivation algorithm. + */ +#define PSA_ALG_FFDH(kdf_alg) \ + (PSA_ALG_FFDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK)) +/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm. + * + * This includes every supported key selection or key agreement algorithm + * for the output of the Diffie-Hellman calculation. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is a finite field Diffie-Hellman algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key agreement algorithm identifier. + */ +#define PSA_ALG_IS_FFDH(alg) \ + (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH_BASE) + +#define PSA_ALG_ECDH_BASE ((psa_algorithm_t)0x22200000) +/** The elliptic curve Diffie-Hellman key agreement algorithm. + * + * This algorithm combines the elliptic curve Diffie-Hellman key + * agreement to produce a shared secret from a private key and the peer's + * public key, with a key selection or key derivation algorithm to produce + * one or more shared keys and other shared cryptographic material. + * + * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true) + * or a selection algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true). + * + * \return The Diffie-Hellman algorithm with the specified + * selection or derivation algorithm. + */ +#define PSA_ALG_ECDH(kdf_alg) \ + (PSA_ALG_ECDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK)) +/** Whether the specified algorithm is an elliptic curve Diffie-Hellman + * algorithm. + * + * This includes every supported key selection or key agreement algorithm + * for the output of the Diffie-Hellman calculation. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is an elliptic curve Diffie-Hellman algorithm, + * 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key agreement algorithm identifier. + */ +#define PSA_ALG_IS_ECDH(alg) \ + (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH_BASE) + /**@}*/ /** \defgroup key_management Key management diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data index 09544f4fb..b61d8e1aa 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.data +++ b/tests/suites/test_suite_psa_crypto_metadata.data @@ -244,6 +244,23 @@ 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 agreement: FFDH, raw output +depends_on:MBEDTLS_DHM_C +key_agreement_algorithm:PSA_ALG_FFDH( PSA_ALG_SELECT_RAW ):ALG_IS_FFDH:PSA_ALG_SELECT_RAW + +Key agreement: FFDH, HKDF using SHA-256 +depends_on:MBEDTLS_DHM_C +key_agreement_algorithm:PSA_ALG_FFDH( PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):ALG_IS_FFDH:PSA_ALG_HKDF( PSA_ALG_SHA_256 ) + +Key agreement: ECDH, raw output +depends_on:MBEDTLS_ECDH_C +key_agreement_algorithm:PSA_ALG_ECDH( PSA_ALG_SELECT_RAW ):ALG_IS_ECDH:PSA_ALG_SELECT_RAW + +Key agreement: ECDH, HKDF using SHA-256 +depends_on:MBEDTLS_ECDH_C +key_agreement_algorithm:PSA_ALG_ECDH( PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):ALG_IS_ECDH:PSA_ALG_HKDF( PSA_ALG_SHA_256 ) + 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 4faa4341e..a8316c40d 100644 --- a/tests/suites/test_suite_psa_crypto_metadata.function +++ b/tests/suites/test_suite_psa_crypto_metadata.function @@ -31,6 +31,8 @@ #define ALG_IS_RANDOMIZED_ECDSA ( 1u << 13 ) #define ALG_IS_RSA_OAEP ( 1u << 14 ) #define ALG_IS_HKDF ( 1u << 15 ) +#define ALG_IS_FFDH ( 1u << 16 ) +#define ALG_IS_ECDH ( 1u << 17 ) /* 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 @@ -357,6 +359,12 @@ void key_derivation_algorithm( int alg_arg, int classification_flags ) TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, classification_flags ); + + /* Check combinations with key agreements */ + TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_FFDH( alg ) ) ); + TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_ECDH( alg ) ) ); + TEST_ASSERT( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_ECDH( alg ) ) == alg ); + TEST_ASSERT( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_FFDH( alg ) ) == alg ); } /* END_CASE */ @@ -376,6 +384,12 @@ void key_selection_algorithm( int alg_arg, int classification_flags ) TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( PSA_ALG_IS_KEY_SELECTION( alg ) ); algorithm_classification( alg, classification_flags ); + + /* Check combinations with key agreements */ + TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_FFDH( alg ) ) ); + TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_ECDH( alg ) ) ); + TEST_ASSERT( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_ECDH( alg ) ) == alg ); + TEST_ASSERT( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_FFDH( alg ) ) == alg ); } /* END_CASE */