psasim: add support for psa_{sign,verify}_{message,hash}() to the simulator

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

View File

@ -67,6 +67,10 @@ enum {
PSA_MAC_VERIFY_FINISH,
PSA_MAC_VERIFY_SETUP,
PSA_RAW_KEY_AGREEMENT,
PSA_SIGN_HASH,
PSA_SIGN_MESSAGE,
PSA_VERIFY_HASH,
PSA_VERIFY_MESSAGE,
};
#endif /* _PSA_FUNCTIONS_CODES_H_ */

View File

@ -4359,3 +4359,339 @@ fail:
return status;
}
psa_status_t psa_sign_hash(
mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
uint8_t *signature, size_t signature_size,
size_t *signature_length
)
{
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(key) +
psasim_serialise_psa_algorithm_t_needs(alg) +
psasim_serialise_buffer_needs(hash, hash_length) +
psasim_serialise_buffer_needs(signature, signature_size) +
psasim_serialise_size_t_needs(*signature_length);
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, key);
if (!ok) {
goto fail;
}
ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg);
if (!ok) {
goto fail;
}
ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length);
if (!ok) {
goto fail;
}
ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_size);
if (!ok) {
goto fail;
}
ok = psasim_serialise_size_t(&pos, &remaining, *signature_length);
if (!ok) {
goto fail;
}
ok = psa_crypto_call(PSA_SIGN_HASH,
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
if (!ok) {
printf("PSA_SIGN_HASH 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_return_buffer(&rpos, &rremain, signature, signature_size);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_size_t(&rpos, &rremain, signature_length);
if (!ok) {
goto fail;
}
fail:
free(ser_params);
free(ser_result);
return status;
}
psa_status_t psa_sign_message(
mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *input, size_t input_length,
uint8_t *signature, size_t signature_size,
size_t *signature_length
)
{
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(key) +
psasim_serialise_psa_algorithm_t_needs(alg) +
psasim_serialise_buffer_needs(input, input_length) +
psasim_serialise_buffer_needs(signature, signature_size) +
psasim_serialise_size_t_needs(*signature_length);
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, key);
if (!ok) {
goto fail;
}
ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg);
if (!ok) {
goto fail;
}
ok = psasim_serialise_buffer(&pos, &remaining, input, input_length);
if (!ok) {
goto fail;
}
ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_size);
if (!ok) {
goto fail;
}
ok = psasim_serialise_size_t(&pos, &remaining, *signature_length);
if (!ok) {
goto fail;
}
ok = psa_crypto_call(PSA_SIGN_MESSAGE,
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
if (!ok) {
printf("PSA_SIGN_MESSAGE 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_return_buffer(&rpos, &rremain, signature, signature_size);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_size_t(&rpos, &rremain, signature_length);
if (!ok) {
goto fail;
}
fail:
free(ser_params);
free(ser_result);
return status;
}
psa_status_t psa_verify_hash(
mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length
)
{
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(key) +
psasim_serialise_psa_algorithm_t_needs(alg) +
psasim_serialise_buffer_needs(hash, hash_length) +
psasim_serialise_buffer_needs(signature, signature_length);
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, key);
if (!ok) {
goto fail;
}
ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg);
if (!ok) {
goto fail;
}
ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length);
if (!ok) {
goto fail;
}
ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length);
if (!ok) {
goto fail;
}
ok = psa_crypto_call(PSA_VERIFY_HASH,
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
if (!ok) {
printf("PSA_VERIFY_HASH 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;
}
fail:
free(ser_params);
free(ser_result);
return status;
}
psa_status_t psa_verify_message(
mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *input, size_t input_length,
const uint8_t *signature, size_t signature_length
)
{
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(key) +
psasim_serialise_psa_algorithm_t_needs(alg) +
psasim_serialise_buffer_needs(input, input_length) +
psasim_serialise_buffer_needs(signature, signature_length);
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, key);
if (!ok) {
goto fail;
}
ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg);
if (!ok) {
goto fail;
}
ok = psasim_serialise_buffer(&pos, &remaining, input, input_length);
if (!ok) {
goto fail;
}
ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length);
if (!ok) {
goto fail;
}
ok = psa_crypto_call(PSA_VERIFY_MESSAGE,
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
if (!ok) {
printf("PSA_VERIFY_MESSAGE 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;
}
fail:
free(ser_params);
free(ser_result);
return status;
}

View File

@ -4980,6 +4980,412 @@ fail:
return 0; // This shouldn't happen!
}
// Returns 1 for success, 0 for failure
int psa_sign_hash_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 key;
psa_algorithm_t alg;
uint8_t *hash = NULL;
size_t hash_length;
uint8_t *signature = NULL;
size_t signature_size;
size_t signature_length;
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, &key);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_size);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_size_t(&pos, &remaining, &signature_length);
if (!ok) {
goto fail;
}
// Now we call the actual target function
status = psa_sign_hash(
key,
alg,
hash, hash_length,
signature, signature_size,
&signature_length
);
// 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_buffer_needs(signature, signature_size) +
psasim_serialise_size_t_needs(signature_length);
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_buffer(&rpos, &rremain, signature, signature_size);
if (!ok) {
goto fail;
}
ok = psasim_serialise_size_t(&rpos, &rremain, signature_length);
if (!ok) {
goto fail;
}
*out_params = result;
*out_params_len = result_size;
free(hash);
free(signature);
return 1; // success
fail:
free(result);
free(hash);
free(signature);
return 0; // This shouldn't happen!
}
// Returns 1 for success, 0 for failure
int psa_sign_message_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 key;
psa_algorithm_t alg;
uint8_t *input = NULL;
size_t input_length;
uint8_t *signature = NULL;
size_t signature_size;
size_t signature_length;
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, &key);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_size);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_size_t(&pos, &remaining, &signature_length);
if (!ok) {
goto fail;
}
// Now we call the actual target function
status = psa_sign_message(
key,
alg,
input, input_length,
signature, signature_size,
&signature_length
);
// 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_buffer_needs(signature, signature_size) +
psasim_serialise_size_t_needs(signature_length);
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_buffer(&rpos, &rremain, signature, signature_size);
if (!ok) {
goto fail;
}
ok = psasim_serialise_size_t(&rpos, &rremain, signature_length);
if (!ok) {
goto fail;
}
*out_params = result;
*out_params_len = result_size;
free(input);
free(signature);
return 1; // success
fail:
free(result);
free(input);
free(signature);
return 0; // This shouldn't happen!
}
// Returns 1 for success, 0 for failure
int psa_verify_hash_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 key;
psa_algorithm_t alg;
uint8_t *hash = NULL;
size_t hash_length;
uint8_t *signature = NULL;
size_t signature_length;
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, &key);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length);
if (!ok) {
goto fail;
}
// Now we call the actual target function
status = psa_verify_hash(
key,
alg,
hash, hash_length,
signature, signature_length
);
// 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);
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;
}
*out_params = result;
*out_params_len = result_size;
free(hash);
free(signature);
return 1; // success
fail:
free(result);
free(hash);
free(signature);
return 0; // This shouldn't happen!
}
// Returns 1 for success, 0 for failure
int psa_verify_message_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 key;
psa_algorithm_t alg;
uint8_t *input = NULL;
size_t input_length;
uint8_t *signature = NULL;
size_t signature_length;
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, &key);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length);
if (!ok) {
goto fail;
}
ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length);
if (!ok) {
goto fail;
}
// Now we call the actual target function
status = psa_verify_message(
key,
alg,
input, input_length,
signature, signature_length
);
// 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);
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;
}
*out_params = result;
*out_params_len = result_size;
free(input);
free(signature);
return 1; // success
fail:
free(result);
free(input);
free(signature);
return 0; // This shouldn't happen!
}
psa_status_t psa_crypto_call(psa_msg_t msg)
{
int ok = 0;
@ -5240,6 +5646,22 @@ psa_status_t psa_crypto_call(psa_msg_t msg)
ok = psa_raw_key_agreement_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
case PSA_SIGN_HASH:
ok = psa_sign_hash_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
case PSA_SIGN_MESSAGE:
ok = psa_sign_message_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
case PSA_VERIFY_HASH:
ok = psa_verify_hash_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
case PSA_VERIFY_MESSAGE:
ok = psa_verify_message_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
break;
}
free(in_params);

View File

@ -4303,3 +4303,224 @@ 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);
/**
* \brief Sign a message with a private key. For hash-and-sign algorithms,
* this includes the hashing step.
*
* \note To perform a multi-part hash-and-sign signature algorithm, first use
* a multi-part hash operation and then pass the resulting hash to
* psa_sign_hash(). PSA_ALG_GET_HASH(\p alg) can be used to determine the
* hash algorithm to use.
*
* \param[in] key Identifier of the key to use for the operation.
* It must be an asymmetric key pair. The key must
* allow the usage #PSA_KEY_USAGE_SIGN_MESSAGE.
* \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX
* value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg)
* is true), that is compatible with the type of
* \p key.
* \param[in] input The input message to sign.
* \param[in] input_length Size of the \p input buffer in bytes.
* \param[out] signature Buffer where the signature is to be written.
* \param[in] signature_size Size of the \p signature buffer in bytes. This
* must be appropriate for the selected
* algorithm and key:
* - The required signature size is
* #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
* where \c key_type and \c key_bits are the type and
* bit-size respectively of key.
* - #PSA_SIGNATURE_MAX_SIZE evaluates to the
* maximum signature size of any supported
* signature algorithm.
* \param[out] signature_length On success, the number of bytes that make up
* the returned signature value.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
* \retval #PSA_ERROR_NOT_PERMITTED
* The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag,
* or it does not permit the requested algorithm.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
* where \c key_type and \c key_bits are the type and bit-size
* respectively of \p key.
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \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_sign_message(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
/** \brief Verify the signature of a message with a public key, using
* a hash-and-sign verification algorithm.
*
* \note To perform a multi-part hash-and-sign signature verification
* algorithm, first use a multi-part hash operation to hash the message
* and then pass the resulting hash to psa_verify_hash().
* PSA_ALG_GET_HASH(\p alg) can be used to determine the hash algorithm
* to use.
*
* \param[in] key Identifier of the key to use for the operation.
* It must be a public key or an asymmetric key
* pair. The key must allow the usage
* #PSA_KEY_USAGE_VERIFY_MESSAGE.
* \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX
* value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg)
* is true), that is compatible with the type of
* \p key.
* \param[in] input The message whose signature is to be verified.
* \param[in] input_length Size of the \p input buffer in bytes.
* \param[in] signature Buffer containing the signature to verify.
* \param[in] signature_length Size of the \p signature buffer in bytes.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
* \retval #PSA_ERROR_NOT_PERMITTED
* The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag,
* or it does not permit the requested algorithm.
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was performed successfully, but the passed signature
* is not a valid signature.
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DATA_INVALID \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_verify_message(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
const uint8_t *signature,
size_t signature_length);
/**
* \brief Sign a hash or short message with a private key.
*
* Note that to perform a hash-and-sign signature algorithm, you must
* first calculate the hash by calling psa_hash_setup(), psa_hash_update()
* and psa_hash_finish(), or alternatively by calling psa_hash_compute().
* Then pass the resulting hash as the \p hash
* parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg)
* to determine the hash algorithm to use.
*
* \param key Identifier of the key to use for the operation.
* It must be an asymmetric key pair. The key must
* allow the usage #PSA_KEY_USAGE_SIGN_HASH.
* \param alg A signature algorithm (PSA_ALG_XXX
* value such that #PSA_ALG_IS_SIGN_HASH(\p alg)
* is true), that is compatible with
* the type of \p key.
* \param[in] hash The hash or message to sign.
* \param hash_length Size of the \p hash buffer in bytes.
* \param[out] signature Buffer where the signature is to be written.
* \param signature_size Size of the \p signature buffer in bytes.
* \param[out] signature_length On success, the number of bytes
* that make up the returned signature value.
*
* \retval #PSA_SUCCESS \emptydescription
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling
* #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
* where \c key_type and \c key_bits are the type and bit-size
* respectively of \p key.
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \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_sign_hash(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
/**
* \brief Verify the signature of a hash or short message using a public key.
*
* Note that to perform a hash-and-sign signature algorithm, you must
* first calculate the hash by calling psa_hash_setup(), psa_hash_update()
* and psa_hash_finish(), or alternatively by calling psa_hash_compute().
* Then pass the resulting hash as the \p hash
* parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg)
* to determine the hash algorithm to use.
*
* \param key Identifier of the key to use for the operation. It
* must be a public key or an asymmetric key pair. The
* key must allow the usage
* #PSA_KEY_USAGE_VERIFY_HASH.
* \param alg A signature algorithm (PSA_ALG_XXX
* value such that #PSA_ALG_IS_SIGN_HASH(\p alg)
* is true), that is compatible with
* the type of \p key.
* \param[in] hash The hash or message whose signature is to be
* verified.
* \param hash_length Size of the \p hash buffer in bytes.
* \param[in] signature Buffer containing the signature to verify.
* \param signature_length Size of the \p signature buffer in bytes.
*
* \retval #PSA_SUCCESS
* The signature is valid.
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was performed successfully, but the passed
* signature is not a valid signature.
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
* \retval #PSA_ERROR_CORRUPTION_DETECTED \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_verify_hash(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length);