psasim: add support for psa_generate_key*() to the simulator

Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
This commit is contained in:
Tom Cosgrove 2024-06-21 16:13:01 +01:00 committed by Valerio Setti
parent c3236b85da
commit 5d4b9cb2e2
4 changed files with 423 additions and 0 deletions

View File

@ -34,6 +34,8 @@ enum {
PSA_CIPHER_SET_IV,
PSA_CIPHER_UPDATE,
PSA_DESTROY_KEY,
PSA_GENERATE_KEY,
PSA_GENERATE_KEY_EXT,
PSA_GENERATE_RANDOM,
PSA_GET_KEY_ATTRIBUTES,
PSA_HASH_ABORT,

View File

@ -1918,6 +1918,150 @@ fail:
}
psa_status_t psa_generate_key(
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *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_psa_key_attributes_t_needs(*attributes) +
psasim_serialise_mbedtls_svc_key_id_t_needs(*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_psa_key_attributes_t(&pos, &remaining, *attributes);
if (!ok) {
goto fail;
}
ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key);
if (!ok) {
goto fail;
}
ok = psa_crypto_call(PSA_GENERATE_KEY,
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
if (!ok) {
printf("PSA_GENERATE_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, key);
if (!ok) {
goto fail;
}
fail:
free(ser_params);
free(ser_result);
return status;
}
psa_status_t psa_generate_key_ext(
const psa_key_attributes_t *attributes,
const psa_key_production_parameters_t *params, size_t params_data_length,
mbedtls_svc_key_id_t *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_psa_key_attributes_t_needs(*attributes) +
psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) +
psasim_serialise_mbedtls_svc_key_id_t_needs(*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_psa_key_attributes_t(&pos, &remaining, *attributes);
if (!ok) {
goto fail;
}
ok = psasim_serialise_psa_key_production_parameters_t(&pos, &remaining, params, params_data_length);
if (!ok) {
goto fail;
}
ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key);
if (!ok) {
goto fail;
}
ok = psa_crypto_call(PSA_GENERATE_KEY_EXT,
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
if (!ok) {
printf("PSA_GENERATE_KEY_EXT 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, key);
if (!ok) {
goto fail;
}
fail:
free(ser_params);
free(ser_result);
return status;
}
psa_status_t psa_generate_random(
uint8_t *output, size_t output_size
)

View File

@ -2172,6 +2172,170 @@ fail:
return 0; // This shouldn't happen!
}
// Returns 1 for success, 0 for failure
int psa_generate_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;
psa_key_attributes_t attributes;
mbedtls_svc_key_id_t 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_psa_key_attributes_t(&pos, &remaining, &attributes);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key);
if (!ok) {
goto fail;
}
// Now we call the actual target function
status = psa_generate_key(
&attributes,
&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(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, 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
int psa_generate_key_ext_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;
psa_key_attributes_t attributes;
psa_key_production_parameters_t *params = NULL;
size_t params_data_length;
mbedtls_svc_key_id_t 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_psa_key_attributes_t(&pos, &remaining, &attributes);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_psa_key_production_parameters_t(&pos, &remaining, &params, &params_data_length);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key);
if (!ok) {
goto fail;
}
// Now we call the actual target function
status = psa_generate_key_ext(
&attributes,
params, params_data_length,
&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(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, key);
if (!ok) {
goto fail;
}
*out_params = result;
*out_params_len = result_size;
free(params);
return 1; // success
fail:
free(result);
free(params);
return 0; // This shouldn't happen!
}
// Returns 1 for success, 0 for failure
int psa_generate_random_wrapper(
uint8_t *in_params, size_t in_params_len,
@ -4944,6 +5108,14 @@ psa_status_t psa_crypto_call(psa_msg_t msg)
ok = psa_destroy_key_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
case PSA_GENERATE_KEY:
ok = psa_generate_key_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
case PSA_GENERATE_KEY_EXT:
ok = psa_generate_key_ext_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
case PSA_GENERATE_RANDOM:
ok = psa_generate_random_wrapper(in_params, in_params_len,
&out_params, &out_params_len);

View File

@ -4198,3 +4198,108 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
uint8_t *output,
size_t output_size,
size_t *output_length);
/**
* \brief Generate a key or key pair.
*
* The key is generated randomly.
* Its location, usage policy, type and size are taken from \p attributes.
*
* Implementations must reject an attempt to generate a key of size 0.
*
* The following type-specific considerations apply:
* - For RSA keys (#PSA_KEY_TYPE_RSA_KEY_PAIR),
* the public exponent is 65537.
* The modulus is a product of two probabilistic primes
* between 2^{n-1} and 2^n where n is the bit size specified in the
* attributes.
*
* \note This function is equivalent to calling psa_generate_key_ext()
* with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
* and `params_data_length == 0` (i.e. `params->data` is empty).
*
* \param[in] attributes The attributes for the new key.
* \param[out] 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
* Success.
* If the key is persistent, the key material and the key's metadata
* have been saved to persistent storage.
* \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_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \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_generate_key(const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key);
/**
* \brief Generate a key or key pair using custom production parameters.
*
* See the description of psa_generate_key() for the operation of this
* function with the default production parameters. In addition, this function
* supports the following production customizations, described in more detail
* in the documentation of ::psa_key_production_parameters_t:
*
* - RSA keys: generation with a custom public exponent.
*
* \note This function is experimental and may change in future minor
* versions of Mbed TLS.
*
* \param[in] attributes The attributes for the new key.
* \param[in] params Customization parameters for the key generation.
* When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
* with \p params_data_length = 0,
* this function is equivalent to
* psa_generate_key().
* \param params_data_length
* Length of `params->data` in bytes.
* \param[out] 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
* Success.
* If the key is persistent, the key material and the key's metadata
* have been saved to persistent storage.
* \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_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \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_generate_key_ext(const psa_key_attributes_t *attributes,
const psa_key_production_parameters_t *params,
size_t params_data_length,
mbedtls_svc_key_id_t *key);