mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-04-15 23:42:41 +00:00
psasim: add support for psa_key_derivation_xxx() and psa_raw_key_agreement() to the simulator
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
This commit is contained in:
parent
623fcb37d6
commit
c3236b85da
@ -45,6 +45,17 @@ enum {
|
||||
PSA_HASH_UPDATE,
|
||||
PSA_HASH_VERIFY,
|
||||
PSA_IMPORT_KEY,
|
||||
PSA_KEY_DERIVATION_ABORT,
|
||||
PSA_KEY_DERIVATION_GET_CAPACITY,
|
||||
PSA_KEY_DERIVATION_INPUT_BYTES,
|
||||
PSA_KEY_DERIVATION_INPUT_INTEGER,
|
||||
PSA_KEY_DERIVATION_INPUT_KEY,
|
||||
PSA_KEY_DERIVATION_KEY_AGREEMENT,
|
||||
PSA_KEY_DERIVATION_OUTPUT_BYTES,
|
||||
PSA_KEY_DERIVATION_OUTPUT_KEY,
|
||||
PSA_KEY_DERIVATION_OUTPUT_KEY_EXT,
|
||||
PSA_KEY_DERIVATION_SET_CAPACITY,
|
||||
PSA_KEY_DERIVATION_SETUP,
|
||||
PSA_MAC_ABORT,
|
||||
PSA_MAC_COMPUTE,
|
||||
PSA_MAC_SIGN_FINISH,
|
||||
@ -53,6 +64,7 @@ enum {
|
||||
PSA_MAC_VERIFY,
|
||||
PSA_MAC_VERIFY_FINISH,
|
||||
PSA_MAC_VERIFY_SETUP,
|
||||
PSA_RAW_KEY_AGREEMENT,
|
||||
};
|
||||
|
||||
#endif /* _PSA_FUNCTIONS_CODES_H_ */
|
||||
|
@ -2705,6 +2705,822 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_abort(
|
||||
psa_key_derivation_operation_t *operation
|
||||
)
|
||||
{
|
||||
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_derivation_operation_t_needs(*operation);
|
||||
|
||||
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_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_ABORT,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_ABORT 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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_get_capacity(
|
||||
const psa_key_derivation_operation_t *operation,
|
||||
size_t *capacity
|
||||
)
|
||||
{
|
||||
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_derivation_operation_t_needs(*operation) +
|
||||
psasim_serialise_size_t_needs(*capacity);
|
||||
|
||||
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_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_size_t(&pos, &remaining, *capacity);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_GET_CAPACITY,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_GET_CAPACITY 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_size_t(&rpos, &rremain, capacity);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_input_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
const uint8_t *data, size_t data_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_psa_key_derivation_operation_t_needs(*operation) +
|
||||
psasim_serialise_psa_key_derivation_step_t_needs(step) +
|
||||
psasim_serialise_buffer_needs(data, data_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_psa_key_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_buffer(&pos, &remaining, data, data_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_INPUT_BYTES,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_INPUT_BYTES 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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_input_integer(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
uint64_t value
|
||||
)
|
||||
{
|
||||
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_derivation_operation_t_needs(*operation) +
|
||||
psasim_serialise_psa_key_derivation_step_t_needs(step) +
|
||||
psasim_serialise_uint64_t_needs(value);
|
||||
|
||||
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_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_uint64_t(&pos, &remaining, value);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_INPUT_INTEGER,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_INPUT_INTEGER 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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_input_key(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
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_derivation_operation_t_needs(*operation) +
|
||||
psasim_serialise_psa_key_derivation_step_t_needs(step) +
|
||||
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_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_INPUT_KEY,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_INPUT_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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_key_agreement(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
mbedtls_svc_key_id_t private_key,
|
||||
const uint8_t *peer_key, size_t peer_key_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_psa_key_derivation_operation_t_needs(*operation) +
|
||||
psasim_serialise_psa_key_derivation_step_t_needs(step) +
|
||||
psasim_serialise_mbedtls_svc_key_id_t_needs(private_key) +
|
||||
psasim_serialise_buffer_needs(peer_key, peer_key_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_psa_key_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, private_key);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_buffer(&pos, &remaining, peer_key, peer_key_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_KEY_AGREEMENT,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_KEY_AGREEMENT 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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_output_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
uint8_t *output, size_t output_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_psa_key_derivation_operation_t_needs(*operation) +
|
||||
psasim_serialise_buffer_needs(output, output_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_psa_key_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_buffer(&pos, &remaining, output, output_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_OUTPUT_BYTES,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_OUTPUT_BYTES 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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_output_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_derivation_operation_t *operation,
|
||||
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_derivation_operation_t_needs(*operation) +
|
||||
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_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_OUTPUT_KEY,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_OUTPUT_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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
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_key_derivation_output_key_ext(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_derivation_operation_t *operation,
|
||||
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_derivation_operation_t_needs(*operation) +
|
||||
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_derivation_operation_t(&pos, &remaining, *operation);
|
||||
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_KEY_DERIVATION_OUTPUT_KEY_EXT,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_OUTPUT_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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
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_key_derivation_set_capacity(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
size_t capacity
|
||||
)
|
||||
{
|
||||
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_derivation_operation_t_needs(*operation) +
|
||||
psasim_serialise_size_t_needs(capacity);
|
||||
|
||||
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_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_size_t(&pos, &remaining, capacity);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_SET_CAPACITY,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_SET_CAPACITY 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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_key_derivation_setup(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_algorithm_t alg
|
||||
)
|
||||
{
|
||||
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_derivation_operation_t_needs(*operation) +
|
||||
psasim_serialise_psa_algorithm_t_needs(alg);
|
||||
|
||||
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_derivation_operation_t(&pos, &remaining, *operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_KEY_DERIVATION_SETUP,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_KEY_DERIVATION_SETUP 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_psa_key_derivation_operation_t(&rpos, &rremain, operation);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_mac_abort(
|
||||
psa_mac_operation_t *operation
|
||||
)
|
||||
@ -3307,3 +4123,95 @@ fail:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_raw_key_agreement(
|
||||
psa_algorithm_t alg,
|
||||
mbedtls_svc_key_id_t private_key,
|
||||
const uint8_t *peer_key, size_t peer_key_length,
|
||||
uint8_t *output, size_t output_size,
|
||||
size_t *output_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_psa_algorithm_t_needs(alg) +
|
||||
psasim_serialise_mbedtls_svc_key_id_t_needs(private_key) +
|
||||
psasim_serialise_buffer_needs(peer_key, peer_key_length) +
|
||||
psasim_serialise_buffer_needs(output, output_size) +
|
||||
psasim_serialise_size_t_needs(*output_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_psa_algorithm_t(&pos, &remaining, alg);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, private_key);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_buffer(&pos, &remaining, peer_key, peer_key_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_buffer(&pos, &remaining, output, output_size);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_size_t(&pos, &remaining, *output_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_RAW_KEY_AGREEMENT,
|
||||
ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
|
||||
if (!ok) {
|
||||
printf("PSA_RAW_KEY_AGREEMENT 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, output, output_size);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_size_t(&rpos, &rremain, output_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ser_params);
|
||||
free(ser_result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3321,3 +3321,880 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
|
||||
* results in this error code.
|
||||
*/
|
||||
psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation);
|
||||
|
||||
/** \defgroup key_derivation Key derivation and pseudorandom generation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The type of the state data structure for key derivation operations.
|
||||
*
|
||||
* Before calling any function on a key derivation operation object, the
|
||||
* application must initialize it by any of the following means:
|
||||
* - Set the structure to all-bits-zero, for example:
|
||||
* \code
|
||||
* psa_key_derivation_operation_t operation;
|
||||
* memset(&operation, 0, sizeof(operation));
|
||||
* \endcode
|
||||
* - Initialize the structure to logical zero values, for example:
|
||||
* \code
|
||||
* psa_key_derivation_operation_t operation = {0};
|
||||
* \endcode
|
||||
* - Initialize the structure to the initializer #PSA_KEY_DERIVATION_OPERATION_INIT,
|
||||
* for example:
|
||||
* \code
|
||||
* psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
* \endcode
|
||||
* - Assign the result of the function psa_key_derivation_operation_init()
|
||||
* to the structure, for example:
|
||||
* \code
|
||||
* psa_key_derivation_operation_t operation;
|
||||
* operation = psa_key_derivation_operation_init();
|
||||
* \endcode
|
||||
*
|
||||
* This is an implementation-defined \c struct. Applications should not
|
||||
* make any assumptions about the content of this structure.
|
||||
* Implementation details can change in future versions without notice.
|
||||
*/
|
||||
typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
|
||||
|
||||
/** \def PSA_KEY_DERIVATION_OPERATION_INIT
|
||||
*
|
||||
* This macro returns a suitable initializer for a key derivation operation
|
||||
* object of type #psa_key_derivation_operation_t.
|
||||
*/
|
||||
|
||||
/** Return an initial value for a key derivation operation object.
|
||||
*/
|
||||
static psa_key_derivation_operation_t psa_key_derivation_operation_init(void);
|
||||
|
||||
/** Set up a key derivation operation.
|
||||
*
|
||||
* A key derivation algorithm takes some inputs and uses them to generate
|
||||
* a byte stream in a deterministic way.
|
||||
* This byte stream can be used to produce keys and other
|
||||
* cryptographic material.
|
||||
*
|
||||
* To derive a key:
|
||||
* -# Start with an initialized object of type #psa_key_derivation_operation_t.
|
||||
* -# Call psa_key_derivation_setup() to select the algorithm.
|
||||
* -# Provide the inputs for the key derivation by calling
|
||||
* psa_key_derivation_input_bytes() or psa_key_derivation_input_key()
|
||||
* as appropriate. Which inputs are needed, in what order, and whether
|
||||
* they may be keys and if so of what type depends on the algorithm.
|
||||
* -# Optionally set the operation's maximum capacity with
|
||||
* psa_key_derivation_set_capacity(). You may do this before, in the middle
|
||||
* of or after providing inputs. For some algorithms, this step is mandatory
|
||||
* because the output depends on the maximum capacity.
|
||||
* -# To derive a key, call psa_key_derivation_output_key() or
|
||||
* psa_key_derivation_output_key_ext().
|
||||
* To derive a byte string for a different purpose, call
|
||||
* psa_key_derivation_output_bytes().
|
||||
* Successive calls to these functions use successive output bytes
|
||||
* calculated by the key derivation algorithm.
|
||||
* -# Clean up the key derivation operation object with
|
||||
* psa_key_derivation_abort().
|
||||
*
|
||||
* If this function returns an error, the key derivation operation object is
|
||||
* not changed.
|
||||
*
|
||||
* If an error occurs at any step after a call to psa_key_derivation_setup(),
|
||||
* the operation will need to be reset by a call to psa_key_derivation_abort().
|
||||
*
|
||||
* Implementations must reject an attempt to derive a key of size 0.
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object
|
||||
* to set up. It must
|
||||
* have been initialized but not set up yet.
|
||||
* \param alg The key derivation algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \c alg is not a key derivation algorithm.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \c alg is not supported or is not a key derivation algorithm.
|
||||
* \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 operation state is not valid (it must be inactive), or
|
||||
* 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_key_derivation_setup(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/** Retrieve the current capacity of a key derivation operation.
|
||||
*
|
||||
* The capacity of a key derivation is the maximum number of bytes that it can
|
||||
* return. When you get *N* bytes of output from a key derivation operation,
|
||||
* this reduces its capacity by *N*.
|
||||
*
|
||||
* \param[in] operation The operation to query.
|
||||
* \param[out] capacity On success, the capacity of the operation.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be active), or
|
||||
* 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_key_derivation_get_capacity(
|
||||
const psa_key_derivation_operation_t *operation,
|
||||
size_t *capacity);
|
||||
|
||||
/** Set the maximum capacity of a key derivation operation.
|
||||
*
|
||||
* The capacity of a key derivation operation is the maximum number of bytes
|
||||
* that the key derivation operation can return from this point onwards.
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to modify.
|
||||
* \param capacity The new capacity of the operation.
|
||||
* It must be less or equal to the operation's
|
||||
* current capacity.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p capacity is larger than the operation's current capacity.
|
||||
* In this case, the operation object remains valid and its capacity
|
||||
* remains unchanged.
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be active), or 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_key_derivation_set_capacity(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
size_t capacity);
|
||||
|
||||
/** Use the maximum possible capacity for a key derivation operation.
|
||||
*
|
||||
* Use this value as the capacity argument when setting up a key derivation
|
||||
* to indicate that the operation should have the maximum possible capacity.
|
||||
* The value of the maximum possible capacity depends on the key derivation
|
||||
* algorithm.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY ((size_t) (-1))
|
||||
|
||||
/** Provide an input for key derivation or key agreement.
|
||||
*
|
||||
* Which inputs are required and in what order depends on the algorithm.
|
||||
* Refer to the documentation of each key derivation or key agreement
|
||||
* algorithm for information.
|
||||
*
|
||||
* This function passes direct inputs, which is usually correct for
|
||||
* non-secret inputs. To pass a secret input, which should be in a key
|
||||
* object, call psa_key_derivation_input_key() instead of this function.
|
||||
* Refer to the documentation of individual step types
|
||||
* (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t)
|
||||
* for more information.
|
||||
*
|
||||
* If this function returns an error status, the operation enters an error
|
||||
* state and must be aborted by calling psa_key_derivation_abort().
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to use.
|
||||
* It must have been set up with
|
||||
* psa_key_derivation_setup() and must not
|
||||
* have produced any output yet.
|
||||
* \param step Which step the input data is for.
|
||||
* \param[in] data Input data to use.
|
||||
* \param data_length Size of the \p data buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \c step is not compatible with the operation's algorithm, or
|
||||
* \c step does not allow direct inputs.
|
||||
* \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 operation state is not valid for this input \p step, or
|
||||
* 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_key_derivation_input_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
|
||||
/** Provide a numeric input for key derivation or key agreement.
|
||||
*
|
||||
* Which inputs are required and in what order depends on the algorithm.
|
||||
* However, when an algorithm requires a particular order, numeric inputs
|
||||
* usually come first as they tend to be configuration parameters.
|
||||
* Refer to the documentation of each key derivation or key agreement
|
||||
* algorithm for information.
|
||||
*
|
||||
* This function is used for inputs which are fixed-size non-negative
|
||||
* integers.
|
||||
*
|
||||
* If this function returns an error status, the operation enters an error
|
||||
* state and must be aborted by calling psa_key_derivation_abort().
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to use.
|
||||
* It must have been set up with
|
||||
* psa_key_derivation_setup() and must not
|
||||
* have produced any output yet.
|
||||
* \param step Which step the input data is for.
|
||||
* \param[in] value The value of the numeric input.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \c step is not compatible with the operation's algorithm, or
|
||||
* \c step does not allow numeric inputs.
|
||||
* \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 operation state is not valid for this input \p step, or
|
||||
* 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_key_derivation_input_integer(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
uint64_t value);
|
||||
|
||||
/** Provide an input for key derivation in the form of a key.
|
||||
*
|
||||
* Which inputs are required and in what order depends on the algorithm.
|
||||
* Refer to the documentation of each key derivation or key agreement
|
||||
* algorithm for information.
|
||||
*
|
||||
* This function obtains input from a key object, which is usually correct for
|
||||
* secret inputs or for non-secret personalization strings kept in the key
|
||||
* store. To pass a non-secret parameter which is not in the key store,
|
||||
* call psa_key_derivation_input_bytes() instead of this function.
|
||||
* Refer to the documentation of individual step types
|
||||
* (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t)
|
||||
* for more information.
|
||||
*
|
||||
* If this function returns an error status, the operation enters an error
|
||||
* state and must be aborted by calling psa_key_derivation_abort().
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to use.
|
||||
* It must have been set up with
|
||||
* psa_key_derivation_setup() and must not
|
||||
* have produced any output yet.
|
||||
* \param step Which step the input data is for.
|
||||
* \param key Identifier of the key. It must have an
|
||||
* appropriate type for step and must allow the
|
||||
* usage #PSA_KEY_USAGE_DERIVE or
|
||||
* #PSA_KEY_USAGE_VERIFY_DERIVATION (see note)
|
||||
* and the algorithm used by the operation.
|
||||
*
|
||||
* \note Once all inputs steps are completed, the operations will allow:
|
||||
* - psa_key_derivation_output_bytes() if each input was either a direct input
|
||||
* or a key with #PSA_KEY_USAGE_DERIVE set;
|
||||
* - psa_key_derivation_output_key() or psa_key_derivation_output_key_ext()
|
||||
* if the input for step
|
||||
* #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD
|
||||
* was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was
|
||||
* either a direct input or a key with #PSA_KEY_USAGE_DERIVE set;
|
||||
* - psa_key_derivation_verify_bytes() if each input was either a direct input
|
||||
* or a key with #PSA_KEY_USAGE_VERIFY_DERIVATION set;
|
||||
* - psa_key_derivation_verify_key() under the same conditions as
|
||||
* psa_key_derivation_verify_bytes().
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The key allows neither #PSA_KEY_USAGE_DERIVE nor
|
||||
* #PSA_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this
|
||||
* algorithm.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \c step is not compatible with the operation's algorithm, or
|
||||
* \c step does not allow key inputs of the given type
|
||||
* or does not allow key inputs at all.
|
||||
* \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 operation state is not valid for this input \p step, or
|
||||
* 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_key_derivation_input_key(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
mbedtls_svc_key_id_t key);
|
||||
|
||||
/** Perform a key agreement and use the shared secret as input to a key
|
||||
* derivation.
|
||||
*
|
||||
* A key agreement algorithm takes two inputs: a private key \p private_key
|
||||
* a public key \p peer_key.
|
||||
* The result of this function is passed as input to a key derivation.
|
||||
* The output of this key derivation can be extracted by reading from the
|
||||
* resulting operation to produce keys and other cryptographic material.
|
||||
*
|
||||
* If this function returns an error status, the operation enters an error
|
||||
* state and must be aborted by calling psa_key_derivation_abort().
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to use.
|
||||
* It must have been set up with
|
||||
* psa_key_derivation_setup() with a
|
||||
* key agreement and derivation algorithm
|
||||
* \c alg (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_KEY_AGREEMENT(\c alg) is true
|
||||
* and #PSA_ALG_IS_RAW_KEY_AGREEMENT(\c alg)
|
||||
* is false).
|
||||
* The operation must be ready for an
|
||||
* input of the type given by \p step.
|
||||
* \param step Which step the input data is for.
|
||||
* \param private_key Identifier of the private key to use. It must
|
||||
* allow the usage #PSA_KEY_USAGE_DERIVE.
|
||||
* \param[in] peer_key Public key of the peer. The peer key must be in the
|
||||
* same format that psa_import_key() accepts for the
|
||||
* public key type corresponding to the type of
|
||||
* private_key. That is, this function performs the
|
||||
* equivalent of
|
||||
* #psa_import_key(...,
|
||||
* `peer_key`, `peer_key_length`) where
|
||||
* with key attributes indicating the public key
|
||||
* type corresponding to the type of `private_key`.
|
||||
* For example, for EC keys, this means that peer_key
|
||||
* is interpreted as a point on the curve that the
|
||||
* private key is on. The standard formats for public
|
||||
* keys are documented in the documentation of
|
||||
* psa_export_public_key().
|
||||
* \param peer_key_length Size of \p peer_key in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \c private_key is not compatible with \c alg,
|
||||
* or \p peer_key is not valid for \c alg or not compatible with
|
||||
* \c private_key, or \c step does not allow an input resulting
|
||||
* from a key agreement.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \c alg is not supported or is not a key derivation algorithm.
|
||||
* \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 operation state is not valid for this key agreement \p step,
|
||||
* or 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_key_derivation_key_agreement(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
mbedtls_svc_key_id_t private_key,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length);
|
||||
|
||||
/** Read some data from a key derivation operation.
|
||||
*
|
||||
* This function calculates output bytes from a key derivation algorithm and
|
||||
* return those bytes.
|
||||
* If you view the key derivation's output as a stream of bytes, this
|
||||
* function destructively reads the requested number of bytes from the
|
||||
* stream.
|
||||
* The operation's capacity decreases by the number of bytes read.
|
||||
*
|
||||
* If this function returns an error status other than
|
||||
* #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error
|
||||
* state and must be aborted by calling psa_key_derivation_abort().
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \param[out] output Buffer where the output will be written.
|
||||
* \param output_length Number of bytes to output.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* One of the inputs was a key whose policy didn't allow
|
||||
* #PSA_KEY_USAGE_DERIVE.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_DATA
|
||||
* The operation's capacity was less than
|
||||
* \p output_length bytes. Note that in this case,
|
||||
* no output is written to the output buffer.
|
||||
* The operation's capacity is set to 0, thus
|
||||
* subsequent calls to this function will not
|
||||
* succeed, even with a smaller output buffer.
|
||||
* \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 operation state is not valid (it must be active and completed
|
||||
* all required input steps), or 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_key_derivation_output_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
uint8_t *output,
|
||||
size_t output_length);
|
||||
|
||||
/** Derive a key from an ongoing key derivation operation.
|
||||
*
|
||||
* This function calculates output bytes from a key derivation algorithm
|
||||
* and uses those bytes to generate a key deterministically.
|
||||
* The key's location, usage policy, type and size are taken from
|
||||
* \p attributes.
|
||||
*
|
||||
* If you view the key derivation's output as a stream of bytes, this
|
||||
* function destructively reads as many bytes as required from the
|
||||
* stream.
|
||||
* The operation's capacity decreases by the number of bytes read.
|
||||
*
|
||||
* If this function returns an error status other than
|
||||
* #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error
|
||||
* state and must be aborted by calling psa_key_derivation_abort().
|
||||
*
|
||||
* How much output is produced and consumed from the operation, and how
|
||||
* the key is derived, depends on the key type and on the key size
|
||||
* (denoted \c bits below):
|
||||
*
|
||||
* - For key types for which the key is an arbitrary sequence of bytes
|
||||
* of a given size, this function is functionally equivalent to
|
||||
* calling #psa_key_derivation_output_bytes
|
||||
* and passing the resulting output to #psa_import_key.
|
||||
* However, this function has a security benefit:
|
||||
* if the implementation provides an isolation boundary then
|
||||
* the key material is not exposed outside the isolation boundary.
|
||||
* As a consequence, for these key types, this function always consumes
|
||||
* exactly (\c bits / 8) bytes from the operation.
|
||||
* The following key types defined in this specification follow this scheme:
|
||||
*
|
||||
* - #PSA_KEY_TYPE_AES;
|
||||
* - #PSA_KEY_TYPE_ARIA;
|
||||
* - #PSA_KEY_TYPE_CAMELLIA;
|
||||
* - #PSA_KEY_TYPE_DERIVE;
|
||||
* - #PSA_KEY_TYPE_HMAC;
|
||||
* - #PSA_KEY_TYPE_PASSWORD_HASH.
|
||||
*
|
||||
* - For ECC keys on a Montgomery elliptic curve
|
||||
* (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a
|
||||
* Montgomery curve), this function always draws a byte string whose
|
||||
* length is determined by the curve, and sets the mandatory bits
|
||||
* accordingly. That is:
|
||||
*
|
||||
* - Curve25519 (#PSA_ECC_FAMILY_MONTGOMERY, 255 bits): draw a 32-byte
|
||||
* string and process it as specified in RFC 7748 §5.
|
||||
* - Curve448 (#PSA_ECC_FAMILY_MONTGOMERY, 448 bits): draw a 56-byte
|
||||
* string and process it as specified in RFC 7748 §5.
|
||||
*
|
||||
* - For key types for which the key is represented by a single sequence of
|
||||
* \c bits bits with constraints as to which bit sequences are acceptable,
|
||||
* this function draws a byte string of length (\c bits / 8) bytes rounded
|
||||
* up to the nearest whole number of bytes. If the resulting byte string
|
||||
* is acceptable, it becomes the key, otherwise the drawn bytes are discarded.
|
||||
* This process is repeated until an acceptable byte string is drawn.
|
||||
* The byte string drawn from the operation is interpreted as specified
|
||||
* for the output produced by psa_export_key().
|
||||
* The following key types defined in this specification follow this scheme:
|
||||
*
|
||||
* - #PSA_KEY_TYPE_DES.
|
||||
* Force-set the parity bits, but discard forbidden weak keys.
|
||||
* For 2-key and 3-key triple-DES, the three keys are generated
|
||||
* successively (for example, for 3-key triple-DES,
|
||||
* if the first 8 bytes specify a weak key and the next 8 bytes do not,
|
||||
* discard the first 8 bytes, use the next 8 bytes as the first key,
|
||||
* and continue reading output from the operation to derive the other
|
||||
* two keys).
|
||||
* - Finite-field Diffie-Hellman keys (#PSA_KEY_TYPE_DH_KEY_PAIR(\c group)
|
||||
* where \c group designates any Diffie-Hellman group) and
|
||||
* ECC keys on a Weierstrass elliptic curve
|
||||
* (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a
|
||||
* Weierstrass curve).
|
||||
* For these key types, interpret the byte string as integer
|
||||
* in big-endian order. Discard it if it is not in the range
|
||||
* [0, *N* - 2] where *N* is the boundary of the private key domain
|
||||
* (the prime *p* for Diffie-Hellman, the subprime *q* for DSA,
|
||||
* or the order of the curve's base point for ECC).
|
||||
* Add 1 to the resulting integer and use this as the private key *x*.
|
||||
* This method allows compliance to NIST standards, specifically
|
||||
* the methods titled "key-pair generation by testing candidates"
|
||||
* in NIST SP 800-56A §5.6.1.1.4 for Diffie-Hellman,
|
||||
* in FIPS 186-4 §B.1.2 for DSA, and
|
||||
* in NIST SP 800-56A §5.6.1.2.2 or
|
||||
* FIPS 186-4 §B.4.2 for elliptic curve keys.
|
||||
*
|
||||
* - For other key types, including #PSA_KEY_TYPE_RSA_KEY_PAIR,
|
||||
* the way in which the operation output is consumed is
|
||||
* implementation-defined.
|
||||
*
|
||||
* In all cases, the data that is read is discarded from the operation.
|
||||
* The operation's capacity is decreased by the number of bytes read.
|
||||
*
|
||||
* For algorithms that take an input step #PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||
* the input to that step must be provided with psa_key_derivation_input_key().
|
||||
* Future versions of this specification may include additional restrictions
|
||||
* on the derived key based on the attributes and strength of the secret key.
|
||||
*
|
||||
* \note This function is equivalent to calling
|
||||
* psa_key_derivation_output_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.
|
||||
* If the key type to be created is
|
||||
* #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
|
||||
* the policy must be the same as in the current
|
||||
* operation.
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \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_INSUFFICIENT_DATA
|
||||
* There was not enough data to create the desired key.
|
||||
* Note that in this case, no output is written to the output buffer.
|
||||
* The operation's capacity is set to 0, thus subsequent calls to
|
||||
* this function will not succeed, even with a smaller output buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The key type or key size is not supported, either by the
|
||||
* implementation in general or in this particular location.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The provided key attributes are not valid for the operation.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The #PSA_KEY_DERIVATION_INPUT_SECRET or
|
||||
* #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a
|
||||
* key; or one of the inputs was a key whose policy didn't allow
|
||||
* #PSA_KEY_USAGE_DERIVE.
|
||||
* \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_CORRUPTION_DETECTED \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 operation state is not valid (it must be active and completed
|
||||
* all required input steps), or 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_key_derivation_output_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_derivation_operation_t *operation,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
|
||||
/** Derive a key from an ongoing key derivation operation with custom
|
||||
* production parameters.
|
||||
*
|
||||
* See the description of psa_key_derivation_out_key() for the operation of
|
||||
* this function with the default production parameters.
|
||||
* Mbed TLS currently does not currently support any non-default production
|
||||
* parameters.
|
||||
*
|
||||
* \note This function is experimental and may change in future minor
|
||||
* versions of Mbed TLS.
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* If the key type to be created is
|
||||
* #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
|
||||
* the policy must be the same as in the current
|
||||
* operation.
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \param[in] params Customization parameters for the key derivation.
|
||||
* When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* with \p params_data_length = 0,
|
||||
* this function is equivalent to
|
||||
* psa_key_derivation_output_key().
|
||||
* Mbed TLS currently only supports the default
|
||||
* production parameters, i.e.
|
||||
* #PSA_KEY_PRODUCTION_PARAMETERS_INIT,
|
||||
* for all key types.
|
||||
* \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_INSUFFICIENT_DATA
|
||||
* There was not enough data to create the desired key.
|
||||
* Note that in this case, no output is written to the output buffer.
|
||||
* The operation's capacity is set to 0, thus subsequent calls to
|
||||
* this function will not succeed, even with a smaller output buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The key type or key size is not supported, either by the
|
||||
* implementation in general or in this particular location.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The provided key attributes are not valid for the operation.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The #PSA_KEY_DERIVATION_INPUT_SECRET or
|
||||
* #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a
|
||||
* key; or one of the inputs was a key whose policy didn't allow
|
||||
* #PSA_KEY_USAGE_DERIVE.
|
||||
* \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_CORRUPTION_DETECTED \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 operation state is not valid (it must be active and completed
|
||||
* all required input steps), or 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_key_derivation_output_key_ext(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_derivation_operation_t *operation,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
|
||||
/** Compare output data from a key derivation operation to an expected value.
|
||||
*
|
||||
* This function calculates output bytes from a key derivation algorithm and
|
||||
* compares those bytes to an expected value in constant time.
|
||||
* If you view the key derivation's output as a stream of bytes, this
|
||||
* function destructively reads the expected number of bytes from the
|
||||
* stream before comparing them.
|
||||
* The operation's capacity decreases by the number of bytes read.
|
||||
*
|
||||
* This is functionally equivalent to the following code:
|
||||
* \code
|
||||
* psa_key_derivation_output_bytes(operation, tmp, output_length);
|
||||
* if (memcmp(output, tmp, output_length) != 0)
|
||||
* return PSA_ERROR_INVALID_SIGNATURE;
|
||||
* \endcode
|
||||
* except (1) it works even if the key's policy does not allow outputting the
|
||||
* bytes, and (2) the comparison will be done in constant time.
|
||||
*
|
||||
* If this function returns an error status other than
|
||||
* #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE,
|
||||
* the operation enters an error state and must be aborted by calling
|
||||
* psa_key_derivation_abort().
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \param[in] expected_output Buffer containing the expected derivation output.
|
||||
* \param output_length Length of the expected output; this is also the
|
||||
* number of bytes that will be read.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The output was read successfully, but it differs from the expected
|
||||
* output.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* One of the inputs was a key whose policy didn't allow
|
||||
* #PSA_KEY_USAGE_VERIFY_DERIVATION.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_DATA
|
||||
* The operation's capacity was less than
|
||||
* \p output_length bytes. Note that in this case,
|
||||
* the operation's capacity is set to 0, thus
|
||||
* subsequent calls to this function will not
|
||||
* succeed, even with a smaller expected output.
|
||||
* \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 operation state is not valid (it must be active and completed
|
||||
* all required input steps), or 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_key_derivation_verify_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
const uint8_t *expected_output,
|
||||
size_t output_length);
|
||||
|
||||
/** Compare output data from a key derivation operation to an expected value
|
||||
* stored in a key object.
|
||||
*
|
||||
* This function calculates output bytes from a key derivation algorithm and
|
||||
* compares those bytes to an expected value, provided as key of type
|
||||
* #PSA_KEY_TYPE_PASSWORD_HASH.
|
||||
* If you view the key derivation's output as a stream of bytes, this
|
||||
* function destructively reads the number of bytes corresponding to the
|
||||
* length of the expected value from the stream before comparing them.
|
||||
* The operation's capacity decreases by the number of bytes read.
|
||||
*
|
||||
* This is functionally equivalent to exporting the key and calling
|
||||
* psa_key_derivation_verify_bytes() on the result, except that it
|
||||
* works even if the key cannot be exported.
|
||||
*
|
||||
* If this function returns an error status other than
|
||||
* #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE,
|
||||
* the operation enters an error state and must be aborted by calling
|
||||
* psa_key_derivation_abort().
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \param[in] expected A key of type #PSA_KEY_TYPE_PASSWORD_HASH
|
||||
* containing the expected output. Its policy must
|
||||
* include the #PSA_KEY_USAGE_VERIFY_DERIVATION flag
|
||||
* and the permitted algorithm must match the
|
||||
* operation. The value of this key was likely
|
||||
* computed by a previous call to
|
||||
* psa_key_derivation_output_key() or
|
||||
* psa_key_derivation_output_key_ext().
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The output was read successfully, but if differs from the expected
|
||||
* output.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE
|
||||
* The key passed as the expected value does not exist.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The key passed as the expected value has an invalid type.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The key passed as the expected value does not allow this usage or
|
||||
* this algorithm; or one of the inputs was a key whose policy didn't
|
||||
* allow #PSA_KEY_USAGE_VERIFY_DERIVATION.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_DATA
|
||||
* The operation's capacity was less than
|
||||
* the length of the expected value. In this case,
|
||||
* the operation's capacity is set to 0, thus
|
||||
* subsequent calls to this function will not
|
||||
* succeed, even with a smaller expected output.
|
||||
* \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 operation state is not valid (it must be active and completed
|
||||
* all required input steps), or 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_key_derivation_verify_key(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
psa_key_id_t expected);
|
||||
|
||||
/** Abort a key derivation operation.
|
||||
*
|
||||
* Aborting an operation frees all associated resources except for the \c
|
||||
* operation structure itself. Once aborted, the operation object can be reused
|
||||
* for another operation by calling psa_key_derivation_setup() again.
|
||||
*
|
||||
* This function may be called at any time after the operation
|
||||
* object has been initialized as described in #psa_key_derivation_operation_t.
|
||||
*
|
||||
* In particular, it is valid to call psa_key_derivation_abort() twice, or to
|
||||
* call psa_key_derivation_abort() on an operation that has not been set up.
|
||||
*
|
||||
* \param[in,out] operation The operation to abort.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_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_key_derivation_abort(
|
||||
psa_key_derivation_operation_t *operation);
|
||||
|
||||
/** Perform a key agreement and return the raw shared secret.
|
||||
*
|
||||
* \warning The raw result of a key agreement algorithm such as finite-field
|
||||
* Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should
|
||||
* not be used directly as key material. It should instead be passed as
|
||||
* input to a key derivation algorithm. To chain a key agreement with
|
||||
* a key derivation, use psa_key_derivation_key_agreement() and other
|
||||
* functions from the key derivation interface.
|
||||
*
|
||||
* \param alg The key agreement algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_RAW_KEY_AGREEMENT(\p alg)
|
||||
* is true).
|
||||
* \param private_key Identifier of the private key to use. It must
|
||||
* allow the usage #PSA_KEY_USAGE_DERIVE.
|
||||
* \param[in] peer_key Public key of the peer. It must be
|
||||
* in the same format that psa_import_key()
|
||||
* accepts. The standard formats for public
|
||||
* keys are documented in the documentation
|
||||
* of psa_export_public_key().
|
||||
* \param peer_key_length Size of \p peer_key in bytes.
|
||||
* \param[out] output Buffer where the decrypted message is to
|
||||
* be written.
|
||||
* \param output_size Size of the \c output buffer in bytes.
|
||||
* \param[out] output_length On success, the number of bytes
|
||||
* that make up the returned output.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p alg is not a key agreement algorithm, or
|
||||
* \p private_key is not compatible with \p alg,
|
||||
* or \p peer_key is not valid for \p alg or not compatible with
|
||||
* \p private_key.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p output_size is too small
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \p alg is not a supported key agreement algorithm.
|
||||
* \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_raw_key_agreement(psa_algorithm_t alg,
|
||||
mbedtls_svc_key_id_t private_key,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
@ -215,6 +215,44 @@ static ssize_t find_cipher_slot_by_handle(psasim_client_handle_t handle)
|
||||
return -1; /* not found */
|
||||
}
|
||||
|
||||
static psa_key_derivation_operation_t key_derivation_operations[MAX_LIVE_HANDLES_PER_CLASS];
|
||||
static psasim_client_handle_t key_derivation_operation_handles[MAX_LIVE_HANDLES_PER_CLASS];
|
||||
static psasim_client_handle_t next_key_derivation_operation_handle = 1;
|
||||
|
||||
/* Get a free slot */
|
||||
static ssize_t allocate_key_derivation_operation_slot(void)
|
||||
{
|
||||
psasim_client_handle_t handle = next_key_derivation_operation_handle++;
|
||||
if (next_key_derivation_operation_handle == 0) { /* wrapped around */
|
||||
FATAL("Key_derivation operation handle wrapped");
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) {
|
||||
if (key_derivation_operation_handles[i] == 0) {
|
||||
key_derivation_operation_handles[i] = handle;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR("All slots are currently used. Unable to allocate a new one.");
|
||||
|
||||
return -1; /* all in use */
|
||||
}
|
||||
|
||||
/* Find the slot given the handle */
|
||||
static ssize_t find_key_derivation_slot_by_handle(psasim_client_handle_t handle)
|
||||
{
|
||||
for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) {
|
||||
if (key_derivation_operation_handles[i] == handle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR("Unable to find slot by handle %u", handle);
|
||||
|
||||
return -1; /* not found */
|
||||
}
|
||||
|
||||
size_t psasim_serialise_begin_needs(void)
|
||||
{
|
||||
/* The serialisation buffer will
|
||||
@ -394,6 +432,76 @@ int psasim_deserialise_size_t(uint8_t **pos,
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_uint16_t_needs(uint16_t value)
|
||||
{
|
||||
return sizeof(value);
|
||||
}
|
||||
|
||||
int psasim_serialise_uint16_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
uint16_t value)
|
||||
{
|
||||
if (*remaining < sizeof(value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(*pos, &value, sizeof(value));
|
||||
*pos += sizeof(value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_deserialise_uint16_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
uint16_t *value)
|
||||
{
|
||||
if (*remaining < sizeof(*value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(value, *pos, sizeof(*value));
|
||||
|
||||
*pos += sizeof(*value);
|
||||
*remaining -= sizeof(*value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_uint64_t_needs(uint64_t value)
|
||||
{
|
||||
return sizeof(value);
|
||||
}
|
||||
|
||||
int psasim_serialise_uint64_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
uint64_t value)
|
||||
{
|
||||
if (*remaining < sizeof(value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(*pos, &value, sizeof(value));
|
||||
*pos += sizeof(value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_deserialise_uint64_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
uint64_t *value)
|
||||
{
|
||||
if (*remaining < sizeof(*value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(value, *pos, sizeof(*value));
|
||||
|
||||
*pos += sizeof(*value);
|
||||
*remaining -= sizeof(*value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_buffer_needs(const uint8_t *buffer, size_t buffer_size)
|
||||
{
|
||||
(void) buffer;
|
||||
@ -496,6 +604,100 @@ int psasim_deserialise_return_buffer(uint8_t **pos,
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SER_TAG_SIZE 4
|
||||
|
||||
size_t psasim_serialise_psa_key_production_parameters_t_needs(
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t data_length)
|
||||
{
|
||||
/* We will serialise with 4-byte tag = "PKPP" + 4-byte overall length at the beginning,
|
||||
* followed by size_t data_length, then the actual data from the structure.
|
||||
*/
|
||||
return SER_TAG_SIZE + sizeof(uint32_t) + sizeof(data_length) + sizeof(*params) + data_length;
|
||||
}
|
||||
|
||||
int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t data_length)
|
||||
{
|
||||
if (data_length > UINT32_MAX / 2) { /* arbitrary limit */
|
||||
return 0; /* too big to serialise */
|
||||
}
|
||||
|
||||
/* We use 32-bit lengths, which should be enough for any reasonable usage :) */
|
||||
/* (the UINT32_MAX / 2 above is an even more conservative check to avoid overflow here) */
|
||||
uint32_t len = (uint32_t) (sizeof(data_length) + sizeof(*params) + data_length);
|
||||
if (*remaining < SER_TAG_SIZE + sizeof(uint32_t) + len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char tag[SER_TAG_SIZE] = "PKPP";
|
||||
|
||||
memcpy(*pos, tag, sizeof(tag));
|
||||
memcpy(*pos + sizeof(tag), &len, sizeof(len));
|
||||
*pos += sizeof(tag) + sizeof(len);
|
||||
*remaining -= sizeof(tag) + sizeof(len);
|
||||
|
||||
memcpy(*pos, &data_length, sizeof(data_length));
|
||||
memcpy(*pos + sizeof(data_length), params, sizeof(*params) + data_length);
|
||||
*pos += sizeof(data_length) + sizeof(*params) + data_length;
|
||||
*remaining -= sizeof(data_length) + sizeof(*params) + data_length;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_production_parameters_t **params,
|
||||
size_t *data_length)
|
||||
{
|
||||
if (*remaining < SER_TAG_SIZE + sizeof(uint32_t)) {
|
||||
return 0; /* can't even be an empty serialisation */
|
||||
}
|
||||
|
||||
char tag[SER_TAG_SIZE] = "PKPP"; /* expected */
|
||||
uint32_t len;
|
||||
|
||||
memcpy(&len, *pos + sizeof(tag), sizeof(len));
|
||||
|
||||
if (memcmp(*pos, tag, sizeof(tag)) != 0) {
|
||||
return 0; /* wrong tag */
|
||||
}
|
||||
|
||||
*pos += sizeof(tag) + sizeof(len);
|
||||
*remaining -= sizeof(tag) + sizeof(len);
|
||||
|
||||
if (*remaining < sizeof(*data_length)) {
|
||||
return 0; /* missing data_length */
|
||||
}
|
||||
memcpy(data_length, *pos, sizeof(*data_length));
|
||||
|
||||
if ((size_t)len != (sizeof(data_length) + sizeof(**params) + *data_length)) {
|
||||
return 0; /* wrong length */
|
||||
}
|
||||
|
||||
if (*remaining < sizeof(*data_length) + sizeof(**params) + *data_length) {
|
||||
return 0; /* not enough data provided */
|
||||
}
|
||||
|
||||
*pos += sizeof(data_length);
|
||||
*remaining -= sizeof(data_length);
|
||||
|
||||
psa_key_production_parameters_t *out = malloc(sizeof(**params) + *data_length);
|
||||
if (out == NULL) {
|
||||
return 0; /* allocation failure */
|
||||
}
|
||||
|
||||
memcpy(out, *pos, sizeof(*out) + *data_length);
|
||||
*pos += sizeof(*out) + *data_length;
|
||||
*remaining -= sizeof(*out) + *data_length;
|
||||
|
||||
*params = out;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_psa_status_t_needs(psa_status_t value)
|
||||
{
|
||||
return psasim_serialise_int_needs(value);
|
||||
@ -534,6 +736,25 @@ int psasim_deserialise_psa_algorithm_t(uint8_t **pos,
|
||||
return psasim_deserialise_unsigned_int(pos, remaining, value);
|
||||
}
|
||||
|
||||
size_t psasim_serialise_psa_key_derivation_step_t_needs(psa_key_derivation_step_t value)
|
||||
{
|
||||
return psasim_serialise_uint16_t_needs(value);
|
||||
}
|
||||
|
||||
int psasim_serialise_psa_key_derivation_step_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_step_t value)
|
||||
{
|
||||
return psasim_serialise_uint16_t(pos, remaining, value);
|
||||
}
|
||||
|
||||
int psasim_deserialise_psa_key_derivation_step_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_step_t *value)
|
||||
{
|
||||
return psasim_deserialise_uint16_t(pos, remaining, value);
|
||||
}
|
||||
|
||||
size_t psasim_serialise_psa_hash_operation_t_needs(psa_hash_operation_t value)
|
||||
{
|
||||
return sizeof(value);
|
||||
@ -941,6 +1162,99 @@ int psasim_server_deserialise_psa_cipher_operation_t(uint8_t **pos,
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t value)
|
||||
{
|
||||
return sizeof(value);
|
||||
}
|
||||
|
||||
int psasim_serialise_psa_key_derivation_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_operation_t value)
|
||||
{
|
||||
if (*remaining < sizeof(value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(*pos, &value, sizeof(value));
|
||||
*pos += sizeof(value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_deserialise_psa_key_derivation_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_operation_t *value)
|
||||
{
|
||||
if (*remaining < sizeof(*value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(value, *pos, sizeof(*value));
|
||||
|
||||
*pos += sizeof(*value);
|
||||
*remaining -= sizeof(*value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_server_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t *operation)
|
||||
{
|
||||
(void) operation;
|
||||
|
||||
/* We will actually return a handle */
|
||||
return sizeof(psasim_operation_t);
|
||||
}
|
||||
|
||||
int psasim_server_serialise_psa_key_derivation_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_operation_t *operation)
|
||||
{
|
||||
psasim_operation_t client_operation;
|
||||
|
||||
if (*remaining < sizeof(client_operation)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t slot = operation - key_derivation_operations;
|
||||
|
||||
client_operation.handle = key_derivation_operation_handles[slot];
|
||||
|
||||
memcpy(*pos, &client_operation, sizeof(client_operation));
|
||||
*pos += sizeof(client_operation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_server_deserialise_psa_key_derivation_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_operation_t **operation)
|
||||
{
|
||||
psasim_operation_t client_operation;
|
||||
|
||||
if (*remaining < sizeof(psasim_operation_t)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&client_operation, *pos, sizeof(psasim_operation_t));
|
||||
*pos += sizeof(psasim_operation_t);
|
||||
*remaining -= sizeof(psasim_operation_t);
|
||||
|
||||
ssize_t slot;
|
||||
if (client_operation.handle == 0) { /* We need a new handle */
|
||||
slot = allocate_key_derivation_operation_slot();
|
||||
} else {
|
||||
slot = find_key_derivation_slot_by_handle(client_operation.handle);
|
||||
}
|
||||
|
||||
if (slot < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*operation = &key_derivation_operations[slot];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value)
|
||||
{
|
||||
return sizeof(value);
|
||||
@ -986,4 +1300,6 @@ void psa_sim_serialize_reset(void)
|
||||
memset(mac_operations, 0, sizeof(mac_operations));
|
||||
memset(cipher_operation_handles, 0, sizeof(cipher_operation_handles));
|
||||
memset(cipher_operations, 0, sizeof(cipher_operations));
|
||||
memset(key_derivation_operation_handles, 0, sizeof(key_derivation_operation_handles));
|
||||
memset(key_derivation_operations, 0, sizeof(key_derivation_operations));
|
||||
}
|
||||
|
@ -222,6 +222,90 @@ int psasim_deserialise_size_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
size_t *value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_uint16_t()
|
||||
* to serialise an `uint16_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_uint16_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_serialise_uint16_t_needs(uint16_t value);
|
||||
|
||||
/** Serialise an `uint16_t` into a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_uint16_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
uint16_t value);
|
||||
|
||||
/** Deserialise an `uint16_t` from a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to an `uint16_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_uint16_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
uint16_t *value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_uint64_t()
|
||||
* to serialise an `uint64_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_uint64_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_serialise_uint64_t_needs(uint64_t value);
|
||||
|
||||
/** Serialise an `uint64_t` into a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_uint64_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
uint64_t value);
|
||||
|
||||
/** Deserialise an `uint64_t` from a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to an `uint64_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_uint64_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
uint64_t *value);
|
||||
|
||||
/** Return how much space is needed by \c psasim_serialise_buffer()
|
||||
* to serialise a buffer: a (`uint8_t *`, `size_t`) pair.
|
||||
*
|
||||
@ -289,6 +373,56 @@ int psasim_deserialise_buffer(uint8_t **pos, size_t *remaining,
|
||||
int psasim_deserialise_return_buffer(uint8_t **pos, size_t *remaining,
|
||||
uint8_t *buffer, size_t buffer_length);
|
||||
|
||||
/** Return how much space is needed by \c psasim_serialise_psa_key_production_parameters_t()
|
||||
* to serialise a psa_key_production_parameters_t (a structure with a flexible array member).
|
||||
*
|
||||
* \param params Pointer to the struct to be serialised
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
* \param data_length Number of bytes in the data[] of the struct to be serialised.
|
||||
*
|
||||
* \return The number of bytes needed in the serialisation buffer by
|
||||
* \c psasim_serialise_psa_key_production_parameters_t() to serialise
|
||||
* the specified structure.
|
||||
*/
|
||||
size_t psasim_serialise_psa_key_production_parameters_t_needs(
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t buffer_size);
|
||||
|
||||
/** Serialise a psa_key_production_parameters_t.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param params Pointer to the structure to be serialised.
|
||||
* \param data_length Number of bytes in the data[] of the struct to be serialised.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t data_length);
|
||||
|
||||
/** Deserialise a psa_key_production_parameters_t.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the serialisation buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the serialisation buffer.
|
||||
* \param params Pointer to a `psa_key_production_parameters_t *` to
|
||||
* receive the address of a newly-allocated structure,
|
||||
* which the caller must `free()`.
|
||||
* \param data_length Pointer to a `size_t` to receive the number of
|
||||
* bytes in the data[] member of the structure deserialised.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, size_t *remaining,
|
||||
psa_key_production_parameters_t **params,
|
||||
size_t *buffer_length);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_psa_status_t()
|
||||
* to serialise a `psa_status_t`.
|
||||
*
|
||||
@ -373,6 +507,48 @@ int psasim_deserialise_psa_algorithm_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_algorithm_t *value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_psa_key_derivation_step_t()
|
||||
* to serialise a `psa_key_derivation_step_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_psa_key_derivation_step_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_serialise_psa_key_derivation_step_t_needs(psa_key_derivation_step_t value);
|
||||
|
||||
/** Serialise a `psa_key_derivation_step_t` into a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_psa_key_derivation_step_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_step_t value);
|
||||
|
||||
/** Deserialise a `psa_key_derivation_step_t` from a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to a `psa_key_derivation_step_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_psa_key_derivation_step_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_step_t *value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_psa_hash_operation_t()
|
||||
* to serialise a `psa_hash_operation_t`.
|
||||
*
|
||||
@ -751,6 +927,90 @@ int psasim_server_deserialise_psa_cipher_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_cipher_operation_t **value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_psa_key_derivation_operation_t()
|
||||
* to serialise a `psa_key_derivation_operation_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_psa_key_derivation_operation_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t value);
|
||||
|
||||
/** Serialise a `psa_key_derivation_operation_t` into a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_psa_key_derivation_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_operation_t value);
|
||||
|
||||
/** Deserialise a `psa_key_derivation_operation_t` from a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to a `psa_key_derivation_operation_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_psa_key_derivation_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_operation_t *value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_server_serialise_psa_key_derivation_operation_t()
|
||||
* to serialise a `psa_key_derivation_operation_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_psa_key_derivation_operation_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_server_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t *value);
|
||||
|
||||
/** Serialise a `psa_key_derivation_operation_t` into a buffer on the server side.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_server_serialise_psa_key_derivation_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_operation_t *value);
|
||||
|
||||
/** Deserialise a `psa_key_derivation_operation_t` from a buffer on the server side.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to a `psa_key_derivation_operation_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_server_deserialise_psa_key_derivation_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_derivation_operation_t **value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_mbedtls_svc_key_id_t()
|
||||
* to serialise a `mbedtls_svc_key_id_t`.
|
||||
*
|
||||
|
@ -36,13 +36,16 @@ die($usage) unless $which eq "c" || $which eq "h";
|
||||
# are).
|
||||
#
|
||||
my @types = qw(unsigned-int int size_t
|
||||
uint16_t uint64_t
|
||||
buffer
|
||||
psa_status_t psa_algorithm_t
|
||||
psa_key_production_parameters_t
|
||||
psa_status_t psa_algorithm_t psa_key_derivation_step_t
|
||||
psa_hash_operation_t
|
||||
psa_aead_operation_t
|
||||
psa_key_attributes_t
|
||||
psa_mac_operation_t
|
||||
psa_cipher_operation_t
|
||||
psa_key_derivation_operation_t
|
||||
mbedtls_svc_key_id_t);
|
||||
|
||||
grep(s/-/ /g, @types);
|
||||
@ -51,6 +54,7 @@ grep(s/-/ /g, @types);
|
||||
my %isa = (
|
||||
"psa_status_t" => "int",
|
||||
"psa_algorithm_t" => "unsigned int",
|
||||
"psa_key_derivation_step_t" => "uint16_t",
|
||||
);
|
||||
|
||||
if ($which eq "h") {
|
||||
|
Loading…
x
Reference in New Issue
Block a user