psasim: add support for psa_copy_key()

Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
This commit is contained in:
Tom Cosgrove 2024-06-21 17:18:35 +01:00 committed by Valerio Setti
parent 05c99e13e6
commit feb021695a
4 changed files with 255 additions and 0 deletions

View File

@ -35,6 +35,7 @@ enum {
PSA_CIPHER_GENERATE_IV, PSA_CIPHER_GENERATE_IV,
PSA_CIPHER_SET_IV, PSA_CIPHER_SET_IV,
PSA_CIPHER_UPDATE, PSA_CIPHER_UPDATE,
PSA_COPY_KEY,
PSA_DESTROY_KEY, PSA_DESTROY_KEY,
PSA_EXPORT_KEY, PSA_EXPORT_KEY,
PSA_EXPORT_PUBLIC_KEY, PSA_EXPORT_PUBLIC_KEY,

View File

@ -2056,6 +2056,81 @@ fail:
} }
psa_status_t psa_copy_key(
mbedtls_svc_key_id_t source_key,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *target_key
)
{
uint8_t *ser_params = NULL;
uint8_t *ser_result = NULL;
size_t result_length;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t needed = psasim_serialise_begin_needs() +
psasim_serialise_mbedtls_svc_key_id_t_needs(source_key) +
psasim_serialise_psa_key_attributes_t_needs(*attributes) +
psasim_serialise_mbedtls_svc_key_id_t_needs(*target_key);
ser_params = malloc(needed);
if (ser_params == NULL) {
status = PSA_ERROR_INSUFFICIENT_MEMORY;
goto fail;
}
uint8_t *pos = ser_params;
size_t remaining = needed;
int ok;
ok = psasim_serialise_begin(&pos, &remaining);
if (!ok) {
goto fail;
}
ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, source_key);
if (!ok) {
goto fail;
}
ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes);
if (!ok) {
goto fail;
}
ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *target_key);
if (!ok) {
goto fail;
}
ok = psa_crypto_call(PSA_COPY_KEY,
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
if (!ok) {
printf("PSA_COPY_KEY server call failed\n");
goto fail;
}
uint8_t *rpos = ser_result;
size_t rremain = result_length;
ok = psasim_deserialise_begin(&rpos, &rremain);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, target_key);
if (!ok) {
goto fail;
}
fail:
free(ser_params);
free(ser_result);
return status;
}
psa_status_t psa_destroy_key( psa_status_t psa_destroy_key(
mbedtls_svc_key_id_t key mbedtls_svc_key_id_t key
) )

View File

@ -2351,6 +2351,89 @@ fail:
return 0; // This shouldn't happen! return 0; // This shouldn't happen!
} }
// Returns 1 for success, 0 for failure
int psa_copy_key_wrapper(
uint8_t *in_params, size_t in_params_len,
uint8_t **out_params, size_t *out_params_len)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_svc_key_id_t source_key;
psa_key_attributes_t attributes;
mbedtls_svc_key_id_t target_key;
uint8_t *pos = in_params;
size_t remaining = in_params_len;
uint8_t *result = NULL;
int ok;
ok = psasim_deserialise_begin(&pos, &remaining);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &source_key);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &target_key);
if (!ok) {
goto fail;
}
// Now we call the actual target function
status = psa_copy_key(
source_key,
&attributes,
&target_key
);
// NOTE: Should really check there is no overflow as we go along.
size_t result_size =
psasim_serialise_begin_needs() +
psasim_serialise_psa_status_t_needs(status) +
psasim_serialise_mbedtls_svc_key_id_t_needs(target_key);
result = malloc(result_size);
if (result == NULL) {
goto fail;
}
uint8_t *rpos = result;
size_t rremain = result_size;
ok = psasim_serialise_begin(&rpos, &rremain);
if (!ok) {
goto fail;
}
ok = psasim_serialise_psa_status_t(&rpos, &rremain, status);
if (!ok) {
goto fail;
}
ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, target_key);
if (!ok) {
goto fail;
}
*out_params = result;
*out_params_len = result_size;
return 1; // success
fail:
free(result);
return 0; // This shouldn't happen!
}
// Returns 1 for success, 0 for failure // Returns 1 for success, 0 for failure
int psa_destroy_key_wrapper( int psa_destroy_key_wrapper(
uint8_t *in_params, size_t in_params_len, uint8_t *in_params, size_t in_params_len,
@ -6749,6 +6832,10 @@ psa_status_t psa_crypto_call(psa_msg_t msg)
ok = psa_cipher_update_wrapper(in_params, in_params_len, ok = psa_cipher_update_wrapper(in_params, in_params_len,
&out_params, &out_params_len); &out_params, &out_params_len);
break; break;
case PSA_COPY_KEY:
ok = psa_copy_key_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
case PSA_DESTROY_KEY: case PSA_DESTROY_KEY:
ok = psa_destroy_key_wrapper(in_params, in_params_len, ok = psa_destroy_key_wrapper(in_params, in_params_len,
&out_params, &out_params_len); &out_params, &out_params_len);

View File

@ -5424,3 +5424,95 @@ psa_status_t psa_verify_hash_complete(
*/ */
psa_status_t psa_verify_hash_abort( psa_status_t psa_verify_hash_abort(
psa_verify_hash_interruptible_operation_t *operation); psa_verify_hash_interruptible_operation_t *operation);
/** Make a copy of a key.
*
* Copy key material from one location to another.
*
* This function is primarily useful to copy a key from one location
* to another, since it populates a key using the material from
* another key which may have a different lifetime.
*
* This function may be used to share a key with a different party,
* subject to implementation-defined restrictions on key sharing.
*
* The policy on the source key must have the usage flag
* #PSA_KEY_USAGE_COPY set.
* This flag is sufficient to permit the copy if the key has the lifetime
* #PSA_KEY_LIFETIME_VOLATILE or #PSA_KEY_LIFETIME_PERSISTENT.
* Some secure elements do not provide a way to copy a key without
* making it extractable from the secure element. If a key is located
* in such a secure element, then the key must have both usage flags
* #PSA_KEY_USAGE_COPY and #PSA_KEY_USAGE_EXPORT in order to make
* a copy of the key outside the secure element.
*
* The resulting key may only be used in a way that conforms to
* both the policy of the original key and the policy specified in
* the \p attributes parameter:
* - The usage flags on the resulting key are the bitwise-and of the
* usage flags on the source policy and the usage flags in \p attributes.
* - If both allow the same algorithm or wildcard-based
* algorithm policy, the resulting key has the same algorithm policy.
* - If either of the policies allows an algorithm and the other policy
* allows a wildcard-based algorithm policy that includes this algorithm,
* the resulting key allows the same algorithm.
* - If the policies do not allow any algorithm in common, this function
* fails with the status #PSA_ERROR_INVALID_ARGUMENT.
*
* The effect of this function on implementation-defined attributes is
* implementation-defined.
*
* \param source_key The key to copy. It must allow the usage
* #PSA_KEY_USAGE_COPY. If a private or secret key is
* being copied outside of a secure element it must
* also allow #PSA_KEY_USAGE_EXPORT.
* \param[in] attributes The attributes for the new key.
* They are used as follows:
* - The key type and size may be 0. If either is
* nonzero, it must match the corresponding
* attribute of the source key.
* - The key location (the lifetime and, for
* persistent keys, the key identifier) is
* used directly.
* - The policy constraints (usage flags and
* algorithm policy) are combined from
* the source key and \p attributes so that
* both sets of restrictions apply, as
* described in the documentation of this function.
* \param[out] target_key On success, an identifier for the newly created
* key. For persistent keys, this is the key
* identifier defined in \p attributes.
* \c 0 on failure.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_HANDLE
* \p source_key is invalid.
* \retval #PSA_ERROR_ALREADY_EXISTS
* This is an attempt to create a persistent key, and there is
* already a persistent key with the given identifier.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The lifetime or identifier in \p attributes are invalid, or
* the policy constraints on the source and specified in
* \p attributes are incompatible, or
* \p attributes specifies a key type or key size
* which does not match the attributes of the source key.
* \retval #PSA_ERROR_NOT_PERMITTED
* The source key does not have the #PSA_KEY_USAGE_COPY usage flag, or
* the source key is not exportable and its lifetime does not
* allow copying it to the target's lifetime.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \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_copy_key(mbedtls_svc_key_id_t source_key,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *target_key);