mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-10-31 03:30:35 -04: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
							
								
									8bf196b303
								
							
						
					
					
						commit
						d6f371b1ba
					
				| @ -62,6 +62,45 @@ extern "C" { | |||||||
|     MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_INSUFFICIENT_DATA ) |     MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_INSUFFICIENT_DATA ) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | /** \addtogroup policy
 | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /** \brief Set the enrollment algorithm in a key policy.
 | ||||||
|  |  * | ||||||
|  |  * An operation on a key may indifferently use the algorithm set with | ||||||
|  |  * psa_key_policy_set_usage() or with this function. | ||||||
|  |  * | ||||||
|  |  * \param[in,out] policy The key policy to modify. It must have been | ||||||
|  |  *                       initialized as per the documentation for | ||||||
|  |  *                       #psa_key_policy_t. | ||||||
|  |  * \param alg2           A second algorithm that the key may be used for, | ||||||
|  |  *                       in addition to the algorithm set with | ||||||
|  |  *                       psa_key_policy_set_usage(). | ||||||
|  |  * | ||||||
|  |  * \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. | ||||||
|  |  */ | ||||||
|  | void psa_key_policy_set_enrollment_algorithm(psa_key_policy_t *policy, | ||||||
|  |                                              psa_algorithm_t alg2); | ||||||
|  | 
 | ||||||
|  | /** \brief Retrieve the enrollment algorithm field of a policy structure.
 | ||||||
|  |  * | ||||||
|  |  * \param[in] policy    The policy object to query. | ||||||
|  |  * | ||||||
|  |  * \return The enrollment algorithm for a key with this policy. | ||||||
|  |  */ | ||||||
|  | psa_algorithm_t psa_key_policy_get_enrollment_algorithm( | ||||||
|  |     const psa_key_policy_t *policy); | ||||||
|  | 
 | ||||||
|  | /**@}*/ | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \brief Library deinitialization. |  * \brief Library deinitialization. | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -228,9 +228,10 @@ struct psa_key_policy_s | |||||||
| { | { | ||||||
|     psa_key_usage_t usage; |     psa_key_usage_t usage; | ||||||
|     psa_algorithm_t alg; |     psa_algorithm_t alg; | ||||||
|  |     psa_algorithm_t alg2; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #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 ) | static inline struct psa_key_policy_s psa_key_policy_init( void ) | ||||||
| { | { | ||||||
|     const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT; |     const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT; | ||||||
|  | |||||||
| @ -763,6 +763,25 @@ static psa_algorithm_t psa_key_policy_algorithm_intersection( | |||||||
|     return( 0 ); |     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.
 | /** Test whether a policy permits an algorithm.
 | ||||||
|  * |  * | ||||||
|  * The caller must test usage flags separately. |  * The caller must test usage flags separately. | ||||||
| @ -770,20 +789,8 @@ static psa_algorithm_t psa_key_policy_algorithm_intersection( | |||||||
| static int psa_key_policy_permits( const psa_key_policy_t *policy, | static int psa_key_policy_permits( const psa_key_policy_t *policy, | ||||||
|                                    psa_algorithm_t alg ) |                                    psa_algorithm_t alg ) | ||||||
| { | { | ||||||
|     /* Common case: the policy only allows alg. */ |     return( psa_key_algorithm_permits( policy->alg, alg ) || | ||||||
|     if( alg == policy->alg ) |             psa_key_algorithm_permits( policy->alg2, 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 ); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** Restrict a key policy based on a constraint.
 | /** Restrict a key policy based on a constraint.
 | ||||||
| @ -804,10 +811,15 @@ static psa_status_t psa_restrict_key_policy( | |||||||
| { | { | ||||||
|     psa_algorithm_t intersection_alg = |     psa_algorithm_t intersection_alg = | ||||||
|         psa_key_policy_algorithm_intersection( policy->alg, constraint->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 ) |     if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 ) | ||||||
|         return( PSA_ERROR_INVALID_ARGUMENT ); |         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->usage &= constraint->usage; | ||||||
|     policy->alg = intersection_alg; |     policy->alg = intersection_alg; | ||||||
|  |     policy->alg2 = intersection_alg2; | ||||||
|     return( PSA_SUCCESS ); |     return( PSA_SUCCESS ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -3218,6 +3230,18 @@ psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy ) | |||||||
| { | { | ||||||
|     return( policy->alg ); |     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) */ | #endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */ | ||||||
| 
 | 
 | ||||||
| psa_status_t psa_set_key_policy( psa_key_handle_t handle, | psa_status_t psa_set_key_policy( psa_key_handle_t handle, | ||||||
|  | |||||||
| @ -492,6 +492,14 @@ PSA key policy: agreement, wrong algorithm | |||||||
| depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C | depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C | ||||||
| agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_FFDH(PSA_ALG_SELECT_RAW) | agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_FFDH(PSA_ALG_SELECT_RAW) | ||||||
| 
 | 
 | ||||||
|  | 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_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_ALG_ECDSA_ANY | ||||||
|  | 
 | ||||||
| Copy key: raw, 0 bytes | Copy key: raw, 0 bytes | ||||||
| copy_key_policy:0:0:PSA_KEY_TYPE_RAW_DATA:"":0:0:-1:-1:0:0 | copy_key_policy:0:0:PSA_KEY_TYPE_RAW_DATA:"":0:0:-1:-1:0:0 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1932,6 +1932,43 @@ exit: | |||||||
| } | } | ||||||
| /* END_CASE */ | /* 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_policy_t policy = PSA_KEY_POLICY_INIT; | ||||||
|  |     psa_key_policy_t got_policy = PSA_KEY_POLICY_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_ASSERT( psa_allocate_key( &handle ) ); | ||||||
|  |     psa_key_policy_set_usage( &policy, usage, alg ); | ||||||
|  |     psa_key_policy_set_enrollment_algorithm( &policy, alg2 ); | ||||||
|  |     PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); | ||||||
|  |     PSA_ASSERT( psa_import_key( handle, key_type, | ||||||
|  |                                 key_data->x, key_data->len ) ); | ||||||
|  | 
 | ||||||
|  |     PSA_ASSERT( psa_get_key_policy( handle, &got_policy ) ); | ||||||
|  |     TEST_EQUAL( psa_key_policy_get_usage( &got_policy ), usage ); | ||||||
|  |     TEST_EQUAL( psa_key_policy_get_algorithm( &got_policy ), alg ); | ||||||
|  |     TEST_EQUAL( psa_key_policy_get_enrollment_algorithm( &got_policy ), 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 */ | /* BEGIN_CASE */ | ||||||
| void copy_key_policy( int source_usage_arg, int source_alg_arg, | void copy_key_policy( int source_usage_arg, int source_alg_arg, | ||||||
|                       int type_arg, data_t *material, |                       int type_arg, data_t *material, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Gilles Peskine
						Gilles Peskine