Keys may allow a second algorithm
Add a second permitted algorithm to key policies.
This commit includes smoke tests that do not cover psa_copy_key.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 3b9c78f..17f2c22 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -763,6 +763,25 @@
return( 0 );
}
+static int psa_key_algorithm_permits( psa_algorithm_t policy_alg,
+ psa_algorithm_t requested_alg )
+{
+ /* Common case: the policy only allows alg. */
+ if( requested_alg == policy_alg )
+ return( 1 );
+ /* If policy_alg is a hash-and-sign with a wildcard for the hash,
+ * and alg is the same hash-and-sign family with any hash,
+ * then alg is compliant with policy_alg. */
+ if( PSA_ALG_IS_HASH_AND_SIGN( requested_alg ) &&
+ PSA_ALG_SIGN_GET_HASH( policy_alg ) == PSA_ALG_ANY_HASH )
+ {
+ return( ( policy_alg & ~PSA_ALG_HASH_MASK ) ==
+ ( requested_alg & ~PSA_ALG_HASH_MASK ) );
+ }
+ /* If it isn't permitted, it's forbidden. */
+ return( 0 );
+}
+
/** Test whether a policy permits an algorithm.
*
* The caller must test usage flags separately.
@@ -770,20 +789,8 @@
static int psa_key_policy_permits( const psa_key_policy_t *policy,
psa_algorithm_t alg )
{
- /* Common case: the policy only allows alg. */
- if( alg == policy->alg )
- return( 1 );
- /* If policy->alg is a hash-and-sign with a wildcard for the hash,
- * and alg is the same hash-and-sign family with any hash,
- * then alg is compliant with policy->alg. */
- if( PSA_ALG_IS_HASH_AND_SIGN( alg ) &&
- PSA_ALG_SIGN_GET_HASH( policy->alg ) == PSA_ALG_ANY_HASH )
- {
- return( ( policy->alg & ~PSA_ALG_HASH_MASK ) ==
- ( alg & ~PSA_ALG_HASH_MASK ) );
- }
- /* If it isn't permitted, it's forbidden. */
- return( 0 );
+ return( psa_key_algorithm_permits( policy->alg, alg ) ||
+ psa_key_algorithm_permits( policy->alg2, alg ) );
}
/** Restrict a key policy based on a constraint.
@@ -804,10 +811,15 @@
{
psa_algorithm_t intersection_alg =
psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
+ psa_algorithm_t intersection_alg2 =
+ psa_key_policy_algorithm_intersection( policy->alg2, constraint->alg2 );
if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
return( PSA_ERROR_INVALID_ARGUMENT );
+ if( intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0 )
+ return( PSA_ERROR_INVALID_ARGUMENT );
policy->usage &= constraint->usage;
policy->alg = intersection_alg;
+ policy->alg2 = intersection_alg2;
return( PSA_SUCCESS );
}
@@ -3218,6 +3230,18 @@
{
return( policy->alg );
}
+
+void psa_key_policy_set_enrollment_algorithm( psa_key_policy_t *policy,
+ psa_algorithm_t alg2 )
+{
+ policy->alg2 = alg2;
+}
+
+psa_algorithm_t psa_key_policy_get_enrollment_algorithm(
+ const psa_key_policy_t *policy )
+{
+ return( policy->alg2 );
+}
#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */
psa_status_t psa_set_key_policy( psa_key_handle_t handle,