Move MAC default length checking into psa_key_policy_permits
Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
This commit is contained in:
parent
328f11c50e
commit
5ad4bf75e3
2 changed files with 116 additions and 48 deletions
|
@ -545,6 +545,68 @@ static inline size_t psa_get_key_slot_bits( const psa_key_slot_t *slot )
|
|||
return( slot->attr.bits );
|
||||
}
|
||||
|
||||
/** Return the output MAC length of a MAC algorithm, in bytes
|
||||
*
|
||||
* \param[in] algorithm The specific MAC algorithm
|
||||
* \param[in] key_type The key type of the key to be used with the
|
||||
* \p algorithm.
|
||||
* \param[out] length The calculated output length of the given MAC
|
||||
* \p algorithm when used with a key corresponding to
|
||||
* the given \p key_type
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The \p length has been successfully calculated
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p algorithm is a MAC algorithm, but ubsupported by this PSA core.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p algorithm is not a valid, specific MAC algorithm or \p key_type
|
||||
* describes a key incompatible with the specified \p algorithm.
|
||||
*/
|
||||
static psa_status_t psa_get_mac_output_length( psa_algorithm_t algorithm,
|
||||
psa_key_type_t key_type,
|
||||
size_t *length )
|
||||
{
|
||||
if( !PSA_ALG_IS_MAC( algorithm ) || PSA_ALG_IS_WILDCARD( algorithm ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
size_t default_length = 0;
|
||||
|
||||
if( PSA_ALG_FULL_LENGTH_MAC( algorithm ) == PSA_ALG_CMAC ||
|
||||
PSA_ALG_FULL_LENGTH_MAC( algorithm ) == PSA_ALG_CBC_MAC )
|
||||
{
|
||||
default_length = PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type );
|
||||
/* CMAC and CBC-MAC are only defined on block ciphers */
|
||||
if( default_length == 0 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
else if( PSA_ALG_IS_HMAC( algorithm ) )
|
||||
{
|
||||
/* HMAC output length is dictated by the underlying hash operation */
|
||||
psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( algorithm );
|
||||
default_length = PSA_HASH_LENGTH( hash_alg );
|
||||
|
||||
if( hash_alg == 0 || default_length == 0 )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
else
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
/* Output the expected (potentially truncated) length as long as it can
|
||||
* actually be output by the algorithm */
|
||||
if( PSA_ALG_FULL_LENGTH_MAC( algorithm ) == algorithm )
|
||||
{
|
||||
*length = default_length;
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
else if( PSA_MAC_TRUNCATED_LENGTH( algorithm ) <= default_length )
|
||||
{
|
||||
*length = PSA_MAC_TRUNCATED_LENGTH( algorithm );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
else
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
|
||||
/** Try to allocate a buffer to an empty key slot.
|
||||
*
|
||||
* \param[in,out] slot Key slot to attach buffer to.
|
||||
|
@ -741,7 +803,8 @@ static psa_algorithm_t psa_key_policy_algorithm_intersection(
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
static int psa_key_algorithm_permits( psa_algorithm_t policy_alg,
|
||||
static int psa_key_algorithm_permits( psa_key_type_t key_type,
|
||||
psa_algorithm_t policy_alg,
|
||||
psa_algorithm_t requested_alg )
|
||||
{
|
||||
/* Common case: the policy only allows requested_alg. */
|
||||
|
@ -768,22 +831,49 @@ static int psa_key_algorithm_permits( psa_algorithm_t policy_alg,
|
|||
return( PSA_ALG_AEAD_GET_TAG_LENGTH( policy_alg ) <=
|
||||
PSA_ALG_AEAD_GET_TAG_LENGTH( requested_alg ) );
|
||||
}
|
||||
/* If policy_alg is a wildcard MAC algorithm of the same base as
|
||||
* the requested algorithm, check the requested tag length to be
|
||||
* equal-length or longer than the wildcard-specified length. */
|
||||
if( PSA_ALG_IS_MAC( policy_alg ) &&
|
||||
PSA_ALG_IS_MAC( requested_alg ) &&
|
||||
( PSA_ALG_FULL_LENGTH_MAC( policy_alg ) ==
|
||||
PSA_ALG_FULL_LENGTH_MAC( requested_alg ) ) &&
|
||||
( ( policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 ) )
|
||||
PSA_ALG_FULL_LENGTH_MAC( requested_alg ) ) )
|
||||
{
|
||||
/* Special case: full-length MAC is encoded with 0-length.
|
||||
* A minimum-length policy will always allow a full-length MAC. */
|
||||
if( PSA_ALG_FULL_LENGTH_MAC( requested_alg ) == requested_alg )
|
||||
return( 1 );
|
||||
size_t actual_output_length;
|
||||
size_t default_output_length;
|
||||
if( PSA_SUCCESS != psa_get_mac_output_length(
|
||||
requested_alg,
|
||||
key_type,
|
||||
&actual_output_length ) )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
if( PSA_SUCCESS != psa_get_mac_output_length(
|
||||
PSA_ALG_FULL_LENGTH_MAC( requested_alg ),
|
||||
key_type,
|
||||
&default_output_length ) )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) <=
|
||||
PSA_MAC_TRUNCATED_LENGTH( requested_alg ) );
|
||||
/* If the policy is default-length, only allow an algorithm with
|
||||
* a declared exact-length matching the default. */
|
||||
if( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) == 0 )
|
||||
return( actual_output_length == default_output_length );
|
||||
|
||||
/* If the requested algorithm is default-length, allow it if the policy
|
||||
* is exactly the default length. */
|
||||
if( PSA_MAC_TRUNCATED_LENGTH( requested_alg ) == 0 &&
|
||||
PSA_MAC_TRUNCATED_LENGTH( policy_alg ) == default_output_length )
|
||||
{
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* If policy_alg is a wildcard MAC algorithm of the same base as
|
||||
* the requested algorithm, check the requested tag length to be
|
||||
* equal-length or longer than the wildcard-specified length. */
|
||||
if( ( policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) != 0 )
|
||||
{
|
||||
return( PSA_MAC_TRUNCATED_LENGTH( policy_alg ) <=
|
||||
actual_output_length );
|
||||
}
|
||||
}
|
||||
/* If policy_alg is a generic key agreement operation, then using it for
|
||||
* a key derivation with that key agreement should also be allowed. This
|
||||
|
@ -809,6 +899,7 @@ static int psa_key_algorithm_permits( psa_algorithm_t policy_alg,
|
|||
* the \p policy does not allow it.
|
||||
*/
|
||||
static psa_status_t psa_key_policy_permits( const psa_key_policy_t *policy,
|
||||
psa_key_type_t key_type,
|
||||
psa_algorithm_t alg )
|
||||
{
|
||||
/* '0' is not a valid algorithm */
|
||||
|
@ -819,8 +910,8 @@ static psa_status_t psa_key_policy_permits( const psa_key_policy_t *policy,
|
|||
if( PSA_ALG_IS_WILDCARD( alg ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
if( psa_key_algorithm_permits( policy->alg, alg ) ||
|
||||
psa_key_algorithm_permits( policy->alg2, alg ) )
|
||||
if( psa_key_algorithm_permits( key_type, policy->alg, alg ) ||
|
||||
psa_key_algorithm_permits( key_type, policy->alg2, alg ) )
|
||||
return( PSA_SUCCESS );
|
||||
else
|
||||
return( PSA_ERROR_NOT_PERMITTED );
|
||||
|
@ -899,7 +990,9 @@ static psa_status_t psa_get_and_lock_key_slot_with_policy(
|
|||
/* Enforce that the usage policy permits the requested algortihm. */
|
||||
if( alg != 0 )
|
||||
{
|
||||
status = psa_key_policy_permits( &slot->attr.policy, alg );
|
||||
status = psa_key_policy_permits( &slot->attr.policy,
|
||||
slot->attr.type,
|
||||
alg );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto error;
|
||||
}
|
||||
|
@ -2934,36 +3027,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
|
|||
|
||||
if( truncated == 0 )
|
||||
{
|
||||
/* The "normal" case: untruncated algorithm. Re-validate the
|
||||
* key policy with explicit MAC length set in the algorithm
|
||||
* when the algorithm policy is at-least-this-length to catch
|
||||
* a corner case due to the default MAC length being unknown
|
||||
* at key loading time. */
|
||||
if( PSA_ALG_IS_MAC( slot->attr.policy.alg ) &&
|
||||
( PSA_ALG_FULL_LENGTH_MAC( slot->attr.policy.alg ) ==
|
||||
full_length_alg ) &&
|
||||
( slot->attr.policy.alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) )
|
||||
{
|
||||
/* validate policy length */
|
||||
if( PSA_MAC_TRUNCATED_LENGTH( slot->attr.policy.alg ) >
|
||||
operation->mac_size )
|
||||
{
|
||||
status = PSA_ERROR_NOT_PERMITTED;
|
||||
}
|
||||
}
|
||||
|
||||
if( PSA_ALG_IS_MAC( slot->attr.policy.alg2 ) &&
|
||||
( PSA_ALG_FULL_LENGTH_MAC( slot->attr.policy.alg2 ) ==
|
||||
full_length_alg ) &&
|
||||
( slot->attr.policy.alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) )
|
||||
{
|
||||
/* validate policy length */
|
||||
if( PSA_MAC_TRUNCATED_LENGTH( slot->attr.policy.alg2 ) >
|
||||
operation->mac_size )
|
||||
{
|
||||
status = PSA_ERROR_NOT_PERMITTED;
|
||||
}
|
||||
}
|
||||
/* The "normal" case: untruncated algorithm. Nothing to do. */
|
||||
}
|
||||
else if( truncated < 4 )
|
||||
{
|
||||
|
|
|
@ -1085,8 +1085,12 @@ PSA MAC setup: good, AES-CMAC
|
|||
depends_on:MBEDTLS_AES_C:MBEDTLS_CMAC_C
|
||||
mac_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_SUCCESS
|
||||
|
||||
PSA MAC setup: bad algorithm (unknown MAC algorithm)
|
||||
mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(0):PSA_ERROR_NOT_SUPPORTED
|
||||
PSA MAC setup: bad algorithm (HMAC without specified hash)
|
||||
mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(0):PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
PSA MAC setup: bad algorithm (unsupported HMAC hash algorithm)
|
||||
depends_on:!PSA_WANT_ALG_MD2
|
||||
mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(PSA_ALG_MD2):PSA_ERROR_NOT_SUPPORTED
|
||||
|
||||
PSA MAC setup: bad algorithm (not a MAC algorithm)
|
||||
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
|
||||
|
@ -1107,7 +1111,7 @@ mac_setup:PSA_KEY_TYPE_RAW_DATA:"000102030405060708090a0b0c0d0e0f101112131415161
|
|||
PSA MAC setup: incompatible key HMAC for CMAC
|
||||
depends_on:MBEDTLS_CMAC_C
|
||||
# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
|
||||
mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_ERROR_NOT_SUPPORTED
|
||||
mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
PSA MAC setup: algorithm known but not supported, long key
|
||||
depends_on:!MBEDTLS_MD5_C
|
||||
|
|
Loading…
Reference in a new issue