New algorithm category: key selection

A key selection algorithm is similar to a key derivation algorithm in
that it takes a secret input and produces a secret output stream.
However, unlike key derivation algorithms, there is no expectation
that the input cannot be reconstructed from the output. Key selection
algorithms are exclusively meant to be used on the output of a key
agreement algorithm to select chunks of the shared secret.
This commit is contained in:
Gilles Peskine 2018-09-18 11:52:10 +02:00
parent 92587dbf2b
commit e8f0e3dc3c
4 changed files with 94 additions and 20 deletions

View File

@ -603,6 +603,7 @@ typedef uint32_t psa_algorithm_t;
#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000) #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_AGREEMENT ((psa_algorithm_t)0x22000000)
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x30000000) #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) \ #define PSA_ALG_IS_VENDOR_DEFINED(alg) \
(((alg) & PSA_ALG_VENDOR_FLAG) != 0) (((alg) & PSA_ALG_VENDOR_FLAG) != 0)
@ -674,6 +675,7 @@ typedef uint32_t psa_algorithm_t;
#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \ #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)
#define PSA_ALG_KEY_SELECTION_FLAG ((psa_algorithm_t)0x01000000)
/** Whether the specified algorithm is a key agreement algorithm. /** Whether the specified algorithm is a key agreement algorithm.
* *
* \param alg An algorithm identifier (value of type #psa_algorithm_t). * \param alg An algorithm identifier (value of type #psa_algorithm_t).
@ -683,7 +685,8 @@ typedef uint32_t psa_algorithm_t;
* algorithm identifier. * algorithm identifier.
*/ */
#define PSA_ALG_IS_KEY_AGREEMENT(alg) \ #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. /** 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) \ #define PSA_ALG_IS_KEY_DERIVATION(alg) \
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) (((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_HASH_MASK ((psa_algorithm_t)0x000000ff)
#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001) #define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001)
#define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002) #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) \ #define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) (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 /** \defgroup key_management Key management

View File

@ -1377,7 +1377,11 @@ PSA key derivation: bad key type
depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C 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 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 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 derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_256):"":"":42:PSA_ERROR_INVALID_ARGUMENT

View File

@ -242,6 +242,8 @@ Key derivation: HKDF using SHA-256
depends_on:MBEDTLS_SHA256_C depends_on:MBEDTLS_SHA256_C
key_derivation_algorithm:PSA_ALG_HKDF( PSA_ALG_SHA_256 ):ALG_IS_HKDF 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: raw data
key_type:PSA_KEY_TYPE_RAW_DATA:KEY_TYPE_IS_UNSTRUCTURED key_type:PSA_KEY_TYPE_RAW_DATA:KEY_TYPE_IS_UNSTRUCTURED

View File

@ -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_ASYMMETRIC_ENCRYPTION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
algorithm_classification( alg, classification_flags ); algorithm_classification( alg, classification_flags );
/* Length */ /* 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_ASYMMETRIC_ENCRYPTION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
algorithm_classification( alg, classification_flags ); algorithm_classification( alg, classification_flags );
/* Tag length */ /* 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_ASYMMETRIC_ENCRYPTION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
algorithm_classification( alg, 0 ); algorithm_classification( alg, 0 );
/* Dependent algorithms */ /* 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_ASYMMETRIC_ENCRYPTION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
algorithm_classification( alg, classification_flags ); algorithm_classification( alg, classification_flags );
} }
/* END_CASE */ /* 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_ASYMMETRIC_ENCRYPTION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
algorithm_classification( alg, classification_flags ); algorithm_classification( alg, classification_flags );
} }
/* END_CASE */ /* 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_ASYMMETRIC_ENCRYPTION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
algorithm_classification( alg, classification_flags ); TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
}
/* 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 ) );
algorithm_classification( alg, classification_flags ); algorithm_classification( alg, classification_flags );
} }
/* END_CASE */ /* 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_ASYMMETRIC_ENCRYPTION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ); TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( alg ) ); TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( alg ) );
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
algorithm_classification( alg, classification_flags ); algorithm_classification( alg, classification_flags );
} }
/* END_CASE */ /* 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 */ /* BEGIN_CASE */
void key_type( int type_arg, int classification_flags ) void key_type( int type_arg, int classification_flags )
{ {