mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-23 19:25:28 +00:00
New function psa_copy_key
Copy a key from one slot to another. Implemented and smoke-tested.
This commit is contained in:
parent
0ce26e35d6
commit
4cb9dde84a
|
@ -93,6 +93,140 @@ psa_status_t psa_crypto_init(void);
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
/** \defgroup policy Key policies
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** The type of the key policy data structure.
|
||||||
|
*
|
||||||
|
* Before calling any function on a key policy, the application must initialize
|
||||||
|
* it by any of the following means:
|
||||||
|
* - Set the structure to all-bits-zero, for example:
|
||||||
|
* \code
|
||||||
|
* psa_key_policy_t policy;
|
||||||
|
* memset(&policy, 0, sizeof(policy));
|
||||||
|
* \endcode
|
||||||
|
* - Initialize the structure to logical zero values, for example:
|
||||||
|
* \code
|
||||||
|
* psa_key_policy_t policy = {0};
|
||||||
|
* \endcode
|
||||||
|
* - Initialize the structure to the initializer #PSA_KEY_POLICY_INIT,
|
||||||
|
* for example:
|
||||||
|
* \code
|
||||||
|
* psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||||
|
* \endcode
|
||||||
|
* - Assign the result of the function psa_key_policy_init()
|
||||||
|
* to the structure, for example:
|
||||||
|
* \code
|
||||||
|
* psa_key_policy_t policy;
|
||||||
|
* policy = psa_key_policy_init();
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* This is an implementation-defined \c struct. Applications should not
|
||||||
|
* make any assumptions about the content of this structure except
|
||||||
|
* as directed by the documentation of a specific implementation. */
|
||||||
|
typedef struct psa_key_policy_s psa_key_policy_t;
|
||||||
|
|
||||||
|
/** \def PSA_KEY_POLICY_INIT
|
||||||
|
*
|
||||||
|
* This macro returns a suitable initializer for a key policy object of type
|
||||||
|
* #psa_key_policy_t.
|
||||||
|
*/
|
||||||
|
#ifdef __DOXYGEN_ONLY__
|
||||||
|
/* This is an example definition for documentation purposes.
|
||||||
|
* Implementations should define a suitable value in `crypto_struct.h`.
|
||||||
|
*/
|
||||||
|
#define PSA_KEY_POLICY_INIT {0}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Return an initial value for a key policy that forbids all usage of the key.
|
||||||
|
*/
|
||||||
|
static psa_key_policy_t psa_key_policy_init(void);
|
||||||
|
|
||||||
|
/** \brief Set the standard fields of a policy structure.
|
||||||
|
*
|
||||||
|
* Note that this function does not make any consistency check of the
|
||||||
|
* parameters. The values are only checked when applying the policy to
|
||||||
|
* a key slot with psa_set_key_policy().
|
||||||
|
*
|
||||||
|
* \param[in,out] policy The key policy to modify. It must have been
|
||||||
|
* initialized as per the documentation for
|
||||||
|
* #psa_key_policy_t.
|
||||||
|
* \param usage The permitted uses for the key.
|
||||||
|
* \param alg The algorithm that the key may be used for.
|
||||||
|
*/
|
||||||
|
void psa_key_policy_set_usage(psa_key_policy_t *policy,
|
||||||
|
psa_key_usage_t usage,
|
||||||
|
psa_algorithm_t alg);
|
||||||
|
|
||||||
|
/** \brief Retrieve the usage field of a policy structure.
|
||||||
|
*
|
||||||
|
* \param[in] policy The policy object to query.
|
||||||
|
*
|
||||||
|
* \return The permitted uses for a key with this policy.
|
||||||
|
*/
|
||||||
|
psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy);
|
||||||
|
|
||||||
|
/** \brief Retrieve the algorithm field of a policy structure.
|
||||||
|
*
|
||||||
|
* \param[in] policy The policy object to query.
|
||||||
|
*
|
||||||
|
* \return The permitted algorithm for a key with this policy.
|
||||||
|
*/
|
||||||
|
psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy);
|
||||||
|
|
||||||
|
/** \brief Set the usage policy on a key slot.
|
||||||
|
*
|
||||||
|
* This function must be called on an empty key slot, before importing,
|
||||||
|
* generating or creating a key in the slot. Changing the policy of an
|
||||||
|
* existing key is not permitted.
|
||||||
|
*
|
||||||
|
* Implementations may set restrictions on supported key policies
|
||||||
|
* depending on the key type and the key slot.
|
||||||
|
*
|
||||||
|
* \param handle Handle to the key whose policy is to be changed.
|
||||||
|
* \param[in] policy The policy object to query.
|
||||||
|
*
|
||||||
|
* \retval #PSA_SUCCESS
|
||||||
|
* Success.
|
||||||
|
* If the key is persistent, it is implementation-defined whether
|
||||||
|
* the policy has been saved to persistent storage. Implementations
|
||||||
|
* may defer saving the policy until the key material is created.
|
||||||
|
* \retval #PSA_ERROR_INVALID_HANDLE
|
||||||
|
* \retval #PSA_ERROR_OCCUPIED_SLOT
|
||||||
|
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||||
|
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||||
|
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||||
|
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||||
|
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||||
|
* \retval #PSA_ERROR_BAD_STATE
|
||||||
|
* The library has not been previously initialized by psa_crypto_init().
|
||||||
|
* It is implementation-dependent whether a failure to initialize
|
||||||
|
* results in this error code.
|
||||||
|
*/
|
||||||
|
psa_status_t psa_set_key_policy(psa_key_handle_t handle,
|
||||||
|
const psa_key_policy_t *policy);
|
||||||
|
|
||||||
|
/** \brief Get the usage policy for a key slot.
|
||||||
|
*
|
||||||
|
* \param handle Handle to the key slot whose policy is being queried.
|
||||||
|
* \param[out] policy On success, the key's policy.
|
||||||
|
*
|
||||||
|
* \retval #PSA_SUCCESS
|
||||||
|
* \retval #PSA_ERROR_INVALID_HANDLE
|
||||||
|
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||||
|
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||||
|
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||||
|
* \retval #PSA_ERROR_BAD_STATE
|
||||||
|
* The library has not been previously initialized by psa_crypto_init().
|
||||||
|
* It is implementation-dependent whether a failure to initialize
|
||||||
|
* results in this error code.
|
||||||
|
*/
|
||||||
|
psa_status_t psa_get_key_policy(psa_key_handle_t handle,
|
||||||
|
psa_key_policy_t *policy);
|
||||||
|
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
/** \defgroup key_management Key management
|
/** \defgroup key_management Key management
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
@ -545,139 +679,70 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle,
|
||||||
size_t data_size,
|
size_t data_size,
|
||||||
size_t *data_length);
|
size_t *data_length);
|
||||||
|
|
||||||
/**@}*/
|
/** Make a copy of a key.
|
||||||
|
|
||||||
/** \defgroup policy Key policies
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** The type of the key policy data structure.
|
|
||||||
*
|
*
|
||||||
* Before calling any function on a key policy, the application must initialize
|
* Copy key material from one location to another.
|
||||||
* it by any of the following means:
|
|
||||||
* - Set the structure to all-bits-zero, for example:
|
|
||||||
* \code
|
|
||||||
* psa_key_policy_t policy;
|
|
||||||
* memset(&policy, 0, sizeof(policy));
|
|
||||||
* \endcode
|
|
||||||
* - Initialize the structure to logical zero values, for example:
|
|
||||||
* \code
|
|
||||||
* psa_key_policy_t policy = {0};
|
|
||||||
* \endcode
|
|
||||||
* - Initialize the structure to the initializer #PSA_KEY_POLICY_INIT,
|
|
||||||
* for example:
|
|
||||||
* \code
|
|
||||||
* psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
|
||||||
* \endcode
|
|
||||||
* - Assign the result of the function psa_key_policy_init()
|
|
||||||
* to the structure, for example:
|
|
||||||
* \code
|
|
||||||
* psa_key_policy_t policy;
|
|
||||||
* policy = psa_key_policy_init();
|
|
||||||
* \endcode
|
|
||||||
*
|
*
|
||||||
* This is an implementation-defined \c struct. Applications should not
|
* This function is primarily useful to copy a key from one lifetime
|
||||||
* make any assumptions about the content of this structure except
|
* to another. The target key retains its lifetime and location.
|
||||||
* as directed by the documentation of a specific implementation. */
|
|
||||||
typedef struct psa_key_policy_s psa_key_policy_t;
|
|
||||||
|
|
||||||
/** \def PSA_KEY_POLICY_INIT
|
|
||||||
*
|
*
|
||||||
* This macro returns a suitable initializer for a key policy object of type
|
* In an implementation where slots have different ownerships,
|
||||||
* #psa_key_policy_t.
|
* this functin may be used to share a key with a different party,
|
||||||
*/
|
* subject to implementation-defined restrictions on key sharing.
|
||||||
#ifdef __DOXYGEN_ONLY__
|
* In this case \p constraint would typically prevent the recipient
|
||||||
/* This is an example definition for documentation purposes.
|
* from exporting the key.
|
||||||
* Implementations should define a suitable value in `crypto_struct.h`.
|
|
||||||
*/
|
|
||||||
#define PSA_KEY_POLICY_INIT {0}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Return an initial value for a key policy that forbids all usage of the key.
|
|
||||||
*/
|
|
||||||
static psa_key_policy_t psa_key_policy_init(void);
|
|
||||||
|
|
||||||
/** \brief Set the standard fields of a policy structure.
|
|
||||||
*
|
*
|
||||||
* Note that this function does not make any consistency check of the
|
* The resulting key may only be used in a way that conforms to all
|
||||||
* parameters. The values are only checked when applying the policy to
|
* three of: the policy of the source key, the policy previously set
|
||||||
* a key slot with psa_set_key_policy().
|
* on the target, and the \p constraint parameter passed when calling
|
||||||
|
* this function.
|
||||||
|
* - The usage flags on the resulting key are the bitwise-and of the
|
||||||
|
* usage flags on the source policy, the previously-set target policy
|
||||||
|
* and the policy constraint.
|
||||||
|
* - If all three policies allow the same algorithm or wildcard-based
|
||||||
|
* algorithm policy, the resulting key has the same algorithm policy.
|
||||||
|
* - If one of the policies allows an algorithm and all the other policies
|
||||||
|
* either allow the same algorithm or a wildcard-based algorithm policy
|
||||||
|
* that includes this algorithm, the resulting key allows the same
|
||||||
|
* algorithm.
|
||||||
*
|
*
|
||||||
* \param[in,out] policy The key policy to modify. It must have been
|
* The effect of this function on implementation-defined metadata is
|
||||||
* initialized as per the documentation for
|
* implementation-defined.
|
||||||
* #psa_key_policy_t.
|
|
||||||
* \param usage The permitted uses for the key.
|
|
||||||
* \param alg The algorithm that the key may be used for.
|
|
||||||
*/
|
|
||||||
void psa_key_policy_set_usage(psa_key_policy_t *policy,
|
|
||||||
psa_key_usage_t usage,
|
|
||||||
psa_algorithm_t alg);
|
|
||||||
|
|
||||||
/** \brief Retrieve the usage field of a policy structure.
|
|
||||||
*
|
*
|
||||||
* \param[in] policy The policy object to query.
|
* \param source_handle The key to copy. It must be a handle to an
|
||||||
*
|
* occupied slot.
|
||||||
* \return The permitted uses for a key with this policy.
|
* \param target_handle A handle to the target slot. It must not contain
|
||||||
*/
|
* key material yet.
|
||||||
psa_key_usage_t psa_key_policy_get_usage(const psa_key_policy_t *policy);
|
* \param[in] constraint An optional policy constraint. If this parameter
|
||||||
|
* is non-null then the resulting key will conform
|
||||||
/** \brief Retrieve the algorithm field of a policy structure.
|
* to this policy in addition to the source policy
|
||||||
*
|
* and the policy already present on the target
|
||||||
* \param[in] policy The policy object to query.
|
* slot. If this parameter is null then the
|
||||||
*
|
* function behaves in the same way as if it was
|
||||||
* \return The permitted algorithm for a key with this policy.
|
* the target policy, i.e. only the source and
|
||||||
*/
|
* target policies apply.
|
||||||
psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy);
|
|
||||||
|
|
||||||
/** \brief Set the usage policy on a key slot.
|
|
||||||
*
|
|
||||||
* This function must be called on an empty key slot, before importing,
|
|
||||||
* generating or creating a key in the slot. Changing the policy of an
|
|
||||||
* existing key is not permitted.
|
|
||||||
*
|
|
||||||
* Implementations may set restrictions on supported key policies
|
|
||||||
* depending on the key type and the key slot.
|
|
||||||
*
|
|
||||||
* \param handle Handle to the key whose policy is to be changed.
|
|
||||||
* \param[in] policy The policy object to query.
|
|
||||||
*
|
*
|
||||||
* \retval #PSA_SUCCESS
|
* \retval #PSA_SUCCESS
|
||||||
* Success.
|
|
||||||
* If the key is persistent, it is implementation-defined whether
|
|
||||||
* the policy has been saved to persistent storage. Implementations
|
|
||||||
* may defer saving the policy until the key material is created.
|
|
||||||
* \retval #PSA_ERROR_INVALID_HANDLE
|
* \retval #PSA_ERROR_INVALID_HANDLE
|
||||||
* \retval #PSA_ERROR_OCCUPIED_SLOT
|
* \retval #PSA_ERROR_OCCUPIED_SLOT
|
||||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
* \p target already contains key material.
|
||||||
|
* \retval #PSA_ERROR_EMPTY_SLOT
|
||||||
|
* \p source does not contain key material.
|
||||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||||
|
* The policy constraints on the source, on the target and
|
||||||
|
* \p constraints are incompatible.
|
||||||
|
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||||
|
* The source key is not exportable and its lifetime does not
|
||||||
|
* allow copying it to the target's lifetime.
|
||||||
|
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||||
|
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
|
||||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||||
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||||
* \retval #PSA_ERROR_BAD_STATE
|
|
||||||
* The library has not been previously initialized by psa_crypto_init().
|
|
||||||
* It is implementation-dependent whether a failure to initialize
|
|
||||||
* results in this error code.
|
|
||||||
*/
|
*/
|
||||||
psa_status_t psa_set_key_policy(psa_key_handle_t handle,
|
psa_status_t psa_copy_key(psa_key_handle_t source_handle,
|
||||||
const psa_key_policy_t *policy);
|
psa_key_handle_t target_handle,
|
||||||
|
const psa_key_policy_t *constraint);
|
||||||
/** \brief Get the usage policy for a key slot.
|
|
||||||
*
|
|
||||||
* \param handle Handle to the key slot whose policy is being queried.
|
|
||||||
* \param[out] policy On success, the key's policy.
|
|
||||||
*
|
|
||||||
* \retval #PSA_SUCCESS
|
|
||||||
* \retval #PSA_ERROR_INVALID_HANDLE
|
|
||||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
|
||||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
|
||||||
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
|
||||||
* \retval #PSA_ERROR_BAD_STATE
|
|
||||||
* The library has not been previously initialized by psa_crypto_init().
|
|
||||||
* It is implementation-dependent whether a failure to initialize
|
|
||||||
* results in this error code.
|
|
||||||
*/
|
|
||||||
psa_status_t psa_get_key_policy(psa_key_handle_t handle,
|
|
||||||
psa_key_policy_t *policy);
|
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
|
|
@ -713,6 +713,32 @@ static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle,
|
||||||
return( status );
|
return( status );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Calculate the intersection of two algorithm usage policies.
|
||||||
|
*
|
||||||
|
* Return 0 (which allows no operation) on incompatibility.
|
||||||
|
*/
|
||||||
|
static psa_algorithm_t psa_key_policy_algorithm_intersection(
|
||||||
|
psa_algorithm_t alg1,
|
||||||
|
psa_algorithm_t alg2 )
|
||||||
|
{
|
||||||
|
/* Common case: the policy only allows alg. */
|
||||||
|
if( alg1 == alg2 )
|
||||||
|
return( alg1 );
|
||||||
|
/* If the policies are from the same hash-and-sign family, check
|
||||||
|
* if one is a wildcard. */
|
||||||
|
if( PSA_ALG_IS_HASH_AND_SIGN( alg1 ) &&
|
||||||
|
PSA_ALG_IS_HASH_AND_SIGN( alg2 ) &&
|
||||||
|
( alg1 & ~PSA_ALG_HASH_MASK ) == ( alg2 & ~PSA_ALG_HASH_MASK ) )
|
||||||
|
{
|
||||||
|
if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
|
||||||
|
return( alg2 );
|
||||||
|
if( PSA_ALG_SIGN_GET_HASH( alg1 ) == PSA_ALG_ANY_HASH )
|
||||||
|
return( alg1 );
|
||||||
|
}
|
||||||
|
/* If the policies are incompatible, allow nothing. */
|
||||||
|
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.
|
||||||
|
@ -736,6 +762,18 @@ static int psa_key_policy_permits( const psa_key_policy_t *policy,
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static psa_status_t psa_restrict_key_policy(
|
||||||
|
psa_key_policy_t *policy,
|
||||||
|
const psa_key_policy_t *constraint )
|
||||||
|
{
|
||||||
|
psa_algorithm_t intersection_alg =
|
||||||
|
psa_key_policy_algorithm_intersection( policy->alg, constraint->alg );
|
||||||
|
if( intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0 )
|
||||||
|
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||||
|
policy->usage &= constraint->usage;
|
||||||
|
return( PSA_SUCCESS );
|
||||||
|
}
|
||||||
|
|
||||||
/** Retrieve a slot which must contain a key. The key must have allow all the
|
/** Retrieve a slot which must contain a key. The key must have allow all the
|
||||||
* usage flags set in \p usage. If \p alg is nonzero, the key must allow
|
* usage flags set in \p usage. If \p alg is nonzero, the key must allow
|
||||||
* operations with this algorithm. */
|
* operations with this algorithm. */
|
||||||
|
@ -923,11 +961,11 @@ psa_status_t psa_get_key_information( psa_key_handle_t handle,
|
||||||
return( PSA_SUCCESS );
|
return( PSA_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
||||||
static psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
|
static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot,
|
||||||
uint8_t *data,
|
uint8_t *data,
|
||||||
size_t data_size,
|
size_t data_size,
|
||||||
size_t *data_length,
|
size_t *data_length,
|
||||||
int export_public_key )
|
int export_public_key )
|
||||||
{
|
{
|
||||||
*data_length = 0;
|
*data_length = 0;
|
||||||
|
|
||||||
|
@ -1110,6 +1148,65 @@ exit:
|
||||||
}
|
}
|
||||||
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||||
|
|
||||||
|
static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
|
||||||
|
psa_key_handle_t target )
|
||||||
|
{
|
||||||
|
psa_status_t status;
|
||||||
|
uint8_t *buffer = NULL;
|
||||||
|
size_t buffer_size = 0;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->type,
|
||||||
|
psa_get_key_bits( source ) );
|
||||||
|
buffer = mbedtls_calloc( 1, buffer_size );
|
||||||
|
if( buffer == NULL )
|
||||||
|
{
|
||||||
|
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
goto exit;
|
||||||
|
status = psa_import_key( target, source->type, buffer, length );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t psa_copy_key(psa_key_handle_t source_handle,
|
||||||
|
psa_key_handle_t target_handle,
|
||||||
|
const psa_key_policy_t *constraint)
|
||||||
|
{
|
||||||
|
psa_key_slot_t *source_slot = NULL;
|
||||||
|
psa_key_slot_t *target_slot = NULL;
|
||||||
|
psa_key_policy_t new_policy;
|
||||||
|
psa_status_t status;
|
||||||
|
status = psa_get_key_from_slot( source_handle, &source_slot, 0, 0 );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
return( status );
|
||||||
|
status = psa_get_empty_key_slot( target_handle, &target_slot );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
return( status );
|
||||||
|
|
||||||
|
new_policy = target_slot->policy;
|
||||||
|
status = psa_restrict_key_policy( &new_policy, &source_slot->policy );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
return( status );
|
||||||
|
if( constraint != NULL )
|
||||||
|
{
|
||||||
|
status = psa_restrict_key_policy( &new_policy, constraint );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
|
||||||
|
status = psa_copy_key_material( source_slot, target_handle );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
return( status );
|
||||||
|
|
||||||
|
target_slot->policy = new_policy;
|
||||||
|
return( PSA_SUCCESS );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
|
|
@ -65,6 +65,18 @@ Create not supported
|
||||||
depends_on:!MBEDTLS_PSA_CRYPTO_STORAGE_C
|
depends_on:!MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||||
create_fail:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_NOT_SUPPORTED
|
create_fail:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_NOT_SUPPORTED
|
||||||
|
|
||||||
|
Copy volatile to volatile
|
||||||
|
copy_across_lifetimes:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:-1:-1:PSA_KEY_USAGE_EXPORT:0
|
||||||
|
|
||||||
|
Copy volatile to persistent
|
||||||
|
copy_across_lifetimes:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:-1:-1:PSA_KEY_USAGE_EXPORT:0
|
||||||
|
|
||||||
|
Copy persistent to volatile
|
||||||
|
copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:-1:-1:PSA_KEY_USAGE_EXPORT:0
|
||||||
|
|
||||||
|
Copy persistent to persistent
|
||||||
|
copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:0:-1:-1:PSA_KEY_USAGE_EXPORT:0
|
||||||
|
|
||||||
Close/destroy invalid handle
|
Close/destroy invalid handle
|
||||||
invalid_handle:
|
invalid_handle:
|
||||||
|
|
||||||
|
|
|
@ -293,6 +293,115 @@ exit:
|
||||||
}
|
}
|
||||||
/* END_CASE */
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg,
|
||||||
|
int source_usage_arg, int source_alg_arg,
|
||||||
|
int type_arg, data_t *material,
|
||||||
|
int target_lifetime_arg, int target_id_arg,
|
||||||
|
int target_usage_arg, int target_alg_arg,
|
||||||
|
int constraint_usage_arg, int constraint_alg_arg,
|
||||||
|
int expected_usage_arg, int expected_alg_arg )
|
||||||
|
{
|
||||||
|
psa_key_lifetime_t source_lifetime = source_lifetime_arg;
|
||||||
|
psa_key_id_t source_id = source_id_arg;
|
||||||
|
psa_key_usage_t source_usage = source_usage_arg;
|
||||||
|
psa_algorithm_t source_alg = source_alg_arg;
|
||||||
|
psa_key_handle_t source_handle = 0;
|
||||||
|
psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
|
||||||
|
psa_key_type_t source_type = type_arg;
|
||||||
|
size_t source_bits;
|
||||||
|
psa_key_lifetime_t target_lifetime = target_lifetime_arg;
|
||||||
|
psa_key_id_t target_id = target_id_arg;
|
||||||
|
psa_key_usage_t target_usage = target_usage_arg;
|
||||||
|
psa_algorithm_t target_alg = target_alg_arg;
|
||||||
|
psa_key_handle_t target_handle = 0;
|
||||||
|
psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
|
||||||
|
psa_key_type_t target_type;
|
||||||
|
size_t target_bits;
|
||||||
|
psa_key_usage_t constraint_usage = constraint_usage_arg;
|
||||||
|
psa_algorithm_t constraint_alg = constraint_alg_arg;
|
||||||
|
psa_key_policy_t constraint = PSA_KEY_POLICY_INIT;
|
||||||
|
psa_key_policy_t *p_constraint = NULL;
|
||||||
|
psa_key_usage_t expected_usage = expected_usage_arg;
|
||||||
|
psa_algorithm_t expected_alg = expected_alg_arg;
|
||||||
|
uint8_t *export_buffer = NULL;
|
||||||
|
|
||||||
|
if( constraint_usage_arg != -1 )
|
||||||
|
{
|
||||||
|
p_constraint = &constraint;
|
||||||
|
psa_key_policy_set_usage( p_constraint,
|
||||||
|
constraint_usage, constraint_alg );
|
||||||
|
}
|
||||||
|
TEST_MAX_KEY_ID( source_id );
|
||||||
|
TEST_MAX_KEY_ID( target_id );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_crypto_init( ) );
|
||||||
|
|
||||||
|
/* Populate the source slot. */
|
||||||
|
if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||||
|
PSA_ASSERT( psa_allocate_key( &source_handle ) );
|
||||||
|
else
|
||||||
|
PSA_ASSERT( psa_create_key( source_lifetime, source_id,
|
||||||
|
&source_handle ) );
|
||||||
|
psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
|
||||||
|
PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
|
||||||
|
PSA_ASSERT( psa_import_key( source_handle, source_type,
|
||||||
|
material->x, material->len ) );
|
||||||
|
PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
|
||||||
|
|
||||||
|
/* Prepare the target slot. */
|
||||||
|
if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||||
|
PSA_ASSERT( psa_allocate_key( &target_handle ) );
|
||||||
|
else
|
||||||
|
PSA_ASSERT( psa_create_key( target_lifetime, target_id,
|
||||||
|
&target_handle ) );
|
||||||
|
psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
|
||||||
|
PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
|
||||||
|
target_policy = psa_key_policy_init();
|
||||||
|
|
||||||
|
/* Copy the key. */
|
||||||
|
PSA_ASSERT( psa_copy_key( source_handle, target_handle, p_constraint ) );
|
||||||
|
|
||||||
|
/* Destroy the source to ensure that this doesn't affect the target. */
|
||||||
|
PSA_ASSERT( psa_destroy_key( source_handle ) );
|
||||||
|
|
||||||
|
/* If the target key is persistent, restart the system to make
|
||||||
|
* sure that the material is still alive. */
|
||||||
|
if( target_lifetime != PSA_KEY_LIFETIME_VOLATILE )
|
||||||
|
{
|
||||||
|
mbedtls_psa_crypto_free( );
|
||||||
|
PSA_ASSERT( psa_crypto_init( ) );
|
||||||
|
PSA_ASSERT( psa_open_key( target_lifetime, target_id,
|
||||||
|
&target_handle ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test that the target slot has the expected content. */
|
||||||
|
PSA_ASSERT( psa_get_key_information( target_handle,
|
||||||
|
&target_type, &target_bits ) );
|
||||||
|
TEST_ASSERT( source_type == target_type );
|
||||||
|
TEST_ASSERT( source_bits == target_bits );
|
||||||
|
PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
|
||||||
|
TEST_ASSERT( expected_usage == psa_key_policy_get_usage( &target_policy ) );
|
||||||
|
TEST_ASSERT( expected_alg == psa_key_policy_get_algorithm( &target_policy ) );
|
||||||
|
if( expected_usage & PSA_KEY_USAGE_EXPORT )
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
ASSERT_ALLOC( export_buffer, material->len );
|
||||||
|
PSA_ASSERT( psa_export_key( target_handle, export_buffer,
|
||||||
|
material->len, &length ) );
|
||||||
|
ASSERT_COMPARE( material->x, material->len,
|
||||||
|
export_buffer, length );
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_psa_crypto_free( );
|
||||||
|
mbedtls_free( export_buffer );
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||||
|
psa_purge_key_storage( );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
/* BEGIN_CASE */
|
/* BEGIN_CASE */
|
||||||
void invalid_handle( )
|
void invalid_handle( )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue