blob: 328ce4d25a6f20a0896c31c3bd4ba2f28798270c [file] [log] [blame]
/*
* Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stddef.h>
#include <stdint.h>
#include "config_tfm.h"
#include "tfm_mbedcrypto_include.h"
#include "tfm_crypto_api.h"
#include "tfm_crypto_key.h"
#include "tfm_crypto_defs.h"
#include "crypto_library.h"
/*!
* \addtogroup tfm_crypto_api_shim_layer
*
*/
/*!@{*/
#if CRYPTO_KEY_MODULE_ENABLED
psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
psa_outvec out_vec[],
struct tfm_crypto_key_id_s *encoded_key)
{
const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
int32_t partition_id = encoded_key->owner;
tfm_crypto_library_key_id_t library_key = tfm_crypto_library_key_id_init(
encoded_key->owner, encoded_key->key_id);
switch (iov->function_id) {
case TFM_CRYPTO_IMPORT_KEY_SID:
{
const struct psa_client_key_attributes_s *client_key_attr =
in_vec[1].base;
const uint8_t *data = in_vec[2].base;
size_t data_length = in_vec[2].len;
psa_key_id_t *key_id = out_vec[0].base;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
status = tfm_crypto_core_library_key_attributes_from_client(
client_key_attr,
partition_id,
&key_attributes);
if (status != PSA_SUCCESS) {
return status;
}
status = psa_import_key(&key_attributes,
data, data_length, &library_key);
/* Update the imported key id */
*key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
}
break;
case TFM_CRYPTO_OPEN_KEY_SID:
{
psa_key_id_t *key_id = out_vec[0].base;
status = psa_open_key(library_key, &library_key);
*key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
}
break;
case TFM_CRYPTO_CLOSE_KEY_SID:
{
status = psa_close_key(library_key);
}
break;
case TFM_CRYPTO_DESTROY_KEY_SID:
{
status = psa_destroy_key(library_key);
}
break;
case TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID:
{
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
struct psa_client_key_attributes_s *client_key_attr = out_vec[0].base;
status = psa_get_key_attributes(library_key, &key_attributes);
if (status == PSA_SUCCESS) {
status = tfm_crypto_core_library_key_attributes_to_client(&key_attributes,
client_key_attr);
}
}
break;
case TFM_CRYPTO_RESET_KEY_ATTRIBUTES_SID:
{
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
struct psa_client_key_attributes_s *client_key_attr = out_vec[0].base;
status = tfm_crypto_core_library_key_attributes_from_client(
client_key_attr,
partition_id,
&key_attributes);
if (status != PSA_SUCCESS) {
return status;
}
psa_reset_key_attributes(&key_attributes);
status = tfm_crypto_core_library_key_attributes_to_client(&key_attributes,
client_key_attr);
}
break;
case TFM_CRYPTO_EXPORT_KEY_SID:
{
uint8_t *data = out_vec[0].base;
size_t data_size = out_vec[0].len;
status = psa_export_key(library_key, data, data_size,
&(out_vec[0].len));
if (status != PSA_SUCCESS) {
out_vec[0].len = 0;
}
}
break;
case TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID:
{
uint8_t *data = out_vec[0].base;
size_t data_size = out_vec[0].len;
status = psa_export_public_key(library_key, data, data_size,
&(out_vec[0].len));
if (status != PSA_SUCCESS) {
out_vec[0].len = 0;
}
}
break;
case TFM_CRYPTO_PURGE_KEY_SID:
{
status = psa_purge_key(library_key);
}
break;
case TFM_CRYPTO_COPY_KEY_SID:
{
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
const struct psa_client_key_attributes_s *client_key_attr =
in_vec[1].base;
psa_key_id_t *target_key_id = out_vec[0].base;
tfm_crypto_library_key_id_t target_key = tfm_crypto_library_key_id_init_default();
status = tfm_crypto_core_library_key_attributes_from_client(
client_key_attr,
partition_id,
&key_attributes);
if (status != PSA_SUCCESS) {
return status;
}
status = psa_copy_key(library_key,
&key_attributes,
&target_key);
if (status != PSA_SUCCESS) {
return status;
}
*target_key_id = CRYPTO_LIBRARY_GET_KEY_ID(target_key);
}
break;
case TFM_CRYPTO_GENERATE_KEY_SID:
{
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
const struct psa_client_key_attributes_s *client_key_attr =
in_vec[1].base;
psa_key_id_t *key_handle = out_vec[0].base;
status = tfm_crypto_core_library_key_attributes_from_client(
client_key_attr,
partition_id,
&key_attributes);
if (status != PSA_SUCCESS) {
return status;
}
status = psa_generate_key(&key_attributes, &library_key);
if (status != PSA_SUCCESS) {
return status;
}
*key_handle = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
}
break;
default:
return PSA_ERROR_NOT_SUPPORTED;
}
return status;
}
#else /* CRYPTO_KEY_MODULE_ENABLED */
psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
psa_outvec out_vec[],
struct tfm_crypto_key_id_s *encoded_key)
{
(void)in_vec;
(void)out_vec;
(void)encoded_key;
return PSA_ERROR_NOT_SUPPORTED;
}
#endif /* CRYPTO_KEY_MODULE_ENABLED */
/*!@}*/