mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-04 04:32:24 -05:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									d3bb7bb2f2
								
							
						
					
					
						commit
						96f0b3b1d3
					
				@ -62,6 +62,50 @@ extern "C" {
 | 
			
		||||
    MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_INSUFFICIENT_DATA )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** \addtogroup attributes
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \brief Declare the enrollment algorithm for a key.
 | 
			
		||||
 *
 | 
			
		||||
 * An operation on a key may indifferently use the algorithm set with
 | 
			
		||||
 * psa_set_key_algorithm() or with this function.
 | 
			
		||||
 *
 | 
			
		||||
 * \param[out] attributes       The attribute structure to write to.
 | 
			
		||||
 * \param alg2                  A second algorithm that the key may be used
 | 
			
		||||
 *                              for, in addition to the algorithm set with
 | 
			
		||||
 *                              psa_set_key_algorithm().
 | 
			
		||||
 *
 | 
			
		||||
 * \warning Setting an enrollment algorithm is not recommended, because
 | 
			
		||||
 *          using the same key with different algorithms can allow some
 | 
			
		||||
 *          attacks based on arithmetic relations between different
 | 
			
		||||
 *          computations made with the same key, or can escalate harmless
 | 
			
		||||
 *          side channels into exploitable ones. Use this function only
 | 
			
		||||
 *          if it is necessary to support a protocol for which is has been
 | 
			
		||||
 *          verified that the usage of the key with multiple algorithms
 | 
			
		||||
 *          is safe.
 | 
			
		||||
 */
 | 
			
		||||
static inline void psa_set_key_enrollment_algorithm(
 | 
			
		||||
    psa_key_attributes_t *attributes,
 | 
			
		||||
    psa_algorithm_t alg2)
 | 
			
		||||
{
 | 
			
		||||
    attributes->policy.alg2 = alg2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Retrieve the enrollment algorithm policy from key attributes.
 | 
			
		||||
 *
 | 
			
		||||
 * \param[in] attributes        The key attribute structure to query.
 | 
			
		||||
 *
 | 
			
		||||
 * \return The enrollment algorithm stored in the attribute structure.
 | 
			
		||||
 */
 | 
			
		||||
static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
 | 
			
		||||
    const psa_key_attributes_t *attributes)
 | 
			
		||||
{
 | 
			
		||||
    return( attributes->policy.alg2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**@}*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Library deinitialization.
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
@ -251,10 +251,11 @@ struct psa_key_policy_s
 | 
			
		||||
{
 | 
			
		||||
    psa_key_usage_t usage;
 | 
			
		||||
    psa_algorithm_t alg;
 | 
			
		||||
    psa_algorithm_t alg2;
 | 
			
		||||
};
 | 
			
		||||
typedef struct psa_key_policy_s psa_key_policy_t;
 | 
			
		||||
 | 
			
		||||
#define PSA_KEY_POLICY_INIT {0, 0}
 | 
			
		||||
#define PSA_KEY_POLICY_INIT {0, 0, 0}
 | 
			
		||||
static inline struct psa_key_policy_s psa_key_policy_init( void )
 | 
			
		||||
{
 | 
			
		||||
    const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT;
 | 
			
		||||
@ -272,7 +273,7 @@ struct psa_key_attributes_s
 | 
			
		||||
    size_t domain_parameters_size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PSA_KEY_ATTRIBUTES_INIT {0, 0, {0, 0}, 0, 0, NULL, 0}
 | 
			
		||||
#define PSA_KEY_ATTRIBUTES_INIT {0, 0, {0, 0, 0}, 0, 0, NULL, 0}
 | 
			
		||||
static inline struct psa_key_attributes_s psa_key_attributes_init( void )
 | 
			
		||||
{
 | 
			
		||||
    const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
 | 
			
		||||
 | 
			
		||||
@ -786,6 +786,25 @@ static psa_algorithm_t psa_key_policy_algorithm_intersection(
 | 
			
		||||
    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.
 | 
			
		||||
@ -793,20 +812,8 @@ static psa_algorithm_t psa_key_policy_algorithm_intersection(
 | 
			
		||||
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.
 | 
			
		||||
@ -827,10 +834,15 @@ static psa_status_t psa_restrict_key_policy(
 | 
			
		||||
{
 | 
			
		||||
    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 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -516,6 +516,14 @@ PSA key policy: raw agreement, key only permits a KDF
 | 
			
		||||
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
 | 
			
		||||
raw_agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256))
 | 
			
		||||
 | 
			
		||||
PSA key policy algorithm2: CTR, CBC
 | 
			
		||||
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_CIPHER_MODE_CBC_NOPAD
 | 
			
		||||
key_policy_alg2:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING
 | 
			
		||||
 | 
			
		||||
PSA key policy algorithm2: ECDH, ECDSA
 | 
			
		||||
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_ECDSA_C
 | 
			
		||||
key_policy_alg2:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDH:PSA_ALG_ECDSA_ANY
 | 
			
		||||
 | 
			
		||||
Copy key: raw, 0 bytes
 | 
			
		||||
copy_success:PSA_KEY_USAGE_COPY:0:PSA_KEY_TYPE_RAW_DATA:"":1:-1:-1:PSA_KEY_USAGE_COPY:0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1912,6 +1912,43 @@ exit:
 | 
			
		||||
}
 | 
			
		||||
/* END_CASE */
 | 
			
		||||
 | 
			
		||||
/* BEGIN_CASE */
 | 
			
		||||
void key_policy_alg2( int key_type_arg, data_t *key_data,
 | 
			
		||||
                      int usage_arg, int alg_arg, int alg2_arg )
 | 
			
		||||
{
 | 
			
		||||
    psa_key_handle_t handle = 0;
 | 
			
		||||
    psa_key_type_t key_type = key_type_arg;
 | 
			
		||||
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 | 
			
		||||
    psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
 | 
			
		||||
    psa_key_usage_t usage = usage_arg;
 | 
			
		||||
    psa_algorithm_t alg = alg_arg;
 | 
			
		||||
    psa_algorithm_t alg2 = alg2_arg;
 | 
			
		||||
 | 
			
		||||
    PSA_ASSERT( psa_crypto_init( ) );
 | 
			
		||||
 | 
			
		||||
    psa_set_key_usage_flags( &attributes, usage );
 | 
			
		||||
    psa_set_key_algorithm( &attributes, alg );
 | 
			
		||||
    psa_set_key_enrollment_algorithm( &attributes, alg2 );
 | 
			
		||||
    psa_set_key_type( &attributes, key_type );
 | 
			
		||||
    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
 | 
			
		||||
                                &handle ) );
 | 
			
		||||
 | 
			
		||||
    PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) );
 | 
			
		||||
    TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage );
 | 
			
		||||
    TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg );
 | 
			
		||||
    TEST_EQUAL( psa_get_key_enrollment_algorithm( &got_attributes ), alg2 );
 | 
			
		||||
 | 
			
		||||
    if( ! exercise_key( handle, usage, alg ) )
 | 
			
		||||
        goto exit;
 | 
			
		||||
    if( ! exercise_key( handle, usage, alg2 ) )
 | 
			
		||||
        goto exit;
 | 
			
		||||
 | 
			
		||||
exit:
 | 
			
		||||
    psa_destroy_key( handle );
 | 
			
		||||
    mbedtls_psa_crypto_free( );
 | 
			
		||||
}
 | 
			
		||||
/* END_CASE */
 | 
			
		||||
 | 
			
		||||
/* BEGIN_CASE */
 | 
			
		||||
void raw_agreement_key_policy( int policy_usage,
 | 
			
		||||
                               int policy_alg,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user