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,