Crypto: Add frontend support for multipart AEAD APIs
This patch adds support in the TF-M Crypto service
frontend for AEAD multipart APIs.
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I81b55bc6ae1b0e1c1c015c90577518328a3286fa
diff --git a/secure_fw/partitions/crypto/crypto_aead.c b/secure_fw/partitions/crypto/crypto_aead.c
index 012ffcf..41eb142 100644
--- a/secure_fw/partitions/crypto/crypto_aead.c
+++ b/secure_fw/partitions/crypto/crypto_aead.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -115,8 +115,54 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
+
+ if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_key_id_t key_id = iov->key_id;
+ psa_algorithm_t alg = iov->alg;
+ mbedtls_svc_key_id_t encoded_key;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Allocate the operation context in the secure world */
+ status = tfm_crypto_operation_alloc(TFM_CRYPTO_AEAD_OPERATION,
+ &handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ *handle_out = handle;
+
+ status = tfm_crypto_encode_id_and_owner(key_id, &encoded_key);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ status = psa_aead_encrypt_setup(operation, encoded_key, alg);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ return status;
+
+exit:
+ /* Release the operation context, ignore if the operation fails. */
+ (void)tfm_crypto_operation_release(handle_out);
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_decrypt_setup(psa_invec in_vec[],
@@ -124,8 +170,54 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
+
+ if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ psa_key_id_t key_id = iov->key_id;
+ psa_algorithm_t alg = iov->alg;
+ mbedtls_svc_key_id_t encoded_key;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Allocate the operation context in the secure world */
+ status = tfm_crypto_operation_alloc(TFM_CRYPTO_AEAD_OPERATION,
+ &handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ *handle_out = handle;
+
+ status = tfm_crypto_encode_id_and_owner(key_id, &encoded_key);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ status = psa_aead_decrypt_setup(operation, encoded_key, alg);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ return status;
+
+exit:
+ /* Release the operation context, ignore if the operation fails. */
+ (void)tfm_crypto_operation_release(handle_out);
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_abort(psa_invec in_vec[],
@@ -133,8 +225,44 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ /* Operation does not exist, so abort has no effect */
+ return PSA_SUCCESS;
+ }
+
+ status = psa_aead_abort(operation);
+
+ if (status != PSA_SUCCESS) {
+ /* Release the operation context, ignore if the operation fails. */
+ (void)tfm_crypto_operation_release(handle_out);
+ return status;
+ }
+
+ return tfm_crypto_operation_release(handle_out);
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_finish(psa_invec in_vec[],
@@ -142,8 +270,51 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 2, 3);
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ uint8_t *ciphertext = out_vec[2].base;
+ size_t ciphertext_size = out_vec[2].len;
+ uint8_t *tag = out_vec[1].base;
+ size_t tag_size = out_vec[1].len;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Initialise tag and ciphertext lengths to zero */
+ out_vec[1].len = 0;
+ out_vec[2].len = 0;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ status = psa_aead_finish(operation,
+ ciphertext, ciphertext_size, &out_vec[2].len,
+ tag, tag_size, &out_vec[1].len);
+ if (status == PSA_SUCCESS) {
+ /* Release the operation context, ignore if the operation fails. */
+ (void)tfm_crypto_operation_release(handle_out);
+ }
+
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_generate_nonce(psa_invec in_vec[],
@@ -151,8 +322,44 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 2, 2);
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ uint8_t *nonce = out_vec[1].base;
+ size_t nonce_size = out_vec[1].len;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Initialise nonce length to zero */
+ out_vec[1].len = 0;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ return psa_aead_generate_nonce(operation,
+ nonce,
+ nonce_size,
+ &out_vec[1].len);
+
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_set_nonce(psa_invec in_vec[],
@@ -160,8 +367,38 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 2, 2, out_len, 1, 1);
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *nonce = in_vec[1].base;
+ size_t nonce_size = in_vec[1].len;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ return psa_aead_set_nonce(operation, nonce, nonce_size);
+
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_set_lengths(psa_invec in_vec[],
@@ -169,8 +406,38 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ size_t ad_length = iov->ad_length;
+ size_t plaintext_length = iov->plaintext_length;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ return psa_aead_set_lengths(operation, ad_length, plaintext_length);
+
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_update(psa_invec in_vec[],
@@ -178,8 +445,41 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 2, 2);
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *input = in_vec[1].base;
+ size_t input_length = in_vec[1].len;
+ uint8_t *output = out_vec[1].base;
+ size_t output_size = out_vec[1].len;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ return psa_aead_update(operation, input, input_length,
+ output, output_size, &out_vec[1].len);
+
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_update_ad(psa_invec in_vec[],
@@ -187,8 +487,38 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 1, 1);
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *input = in_vec[1].base;
+ size_t input_length = in_vec[1].len;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ return psa_aead_update_ad(operation, input, input_length);
+
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
psa_status_t tfm_crypto_aead_verify(psa_invec in_vec[],
@@ -196,7 +526,47 @@
psa_outvec out_vec[],
size_t out_len)
{
- /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status = PSA_SUCCESS;
+ psa_aead_operation_t *operation = NULL;
+
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 2, 2, out_len, 1, 2);
+
+ if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+ (out_vec[0].len != sizeof(uint32_t))) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+ const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+ uint32_t handle = iov->op_handle;
+ uint32_t *handle_out = out_vec[0].base;
+ const uint8_t *tag = in_vec[1].base;
+ size_t tag_length = in_vec[1].len;
+ uint8_t *plaintext = out_vec[1].base;
+ size_t plaintext_size = out_vec[1].len;
+
+ /* Init the handle in the operation with the one passed from the iov */
+ *handle_out = iov->op_handle;
+
+ /* Look up the corresponding operation context */
+ status = tfm_crypto_operation_lookup(TFM_CRYPTO_AEAD_OPERATION,
+ handle,
+ (void **)&operation);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ status = psa_aead_verify(operation,
+ plaintext, plaintext_size, &out_vec[1].len,
+ tag, tag_length);
+
+ if (status == PSA_SUCCESS) {
+ /* Release the operation context, ignore if the operation fails. */
+ (void)tfm_crypto_operation_release(handle_out);
+ }
+
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
/*!@}*/
diff --git a/secure_fw/partitions/crypto/crypto_alloc.c b/secure_fw/partitions/crypto/crypto_alloc.c
index 1036a67..be8e83c 100644
--- a/secure_fw/partitions/crypto/crypto_alloc.c
+++ b/secure_fw/partitions/crypto/crypto_alloc.c
@@ -36,6 +36,7 @@
psa_mac_operation_t mac; /*!< MAC operation context */
psa_hash_operation_t hash; /*!< Hash operation context */
psa_key_derivation_operation_t key_deriv; /*!< Key derivation operation context */
+ psa_aead_operation_t aead; /*!< AEAD operation context */
} operation;
};
@@ -68,6 +69,9 @@
case TFM_CRYPTO_KEY_DERIVATION_OPERATION:
mem_size = sizeof(psa_key_derivation_operation_t);
break;
+ case TFM_CRYPTO_AEAD_OPERATION:
+ mem_size = sizeof(psa_aead_operation_t);
+ break;
case TFM_CRYPTO_OPERATION_NONE:
default:
mem_size = 0;
diff --git a/secure_fw/partitions/crypto/tfm_crypto_api.h b/secure_fw/partitions/crypto/tfm_crypto_api.h
index 79bf703..42c643b 100644
--- a/secure_fw/partitions/crypto/tfm_crypto_api.h
+++ b/secure_fw/partitions/crypto/tfm_crypto_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -41,6 +41,7 @@
TFM_CRYPTO_MAC_OPERATION = 2,
TFM_CRYPTO_HASH_OPERATION = 3,
TFM_CRYPTO_KEY_DERIVATION_OPERATION = 4,
+ TFM_CRYPTO_AEAD_OPERATION = 5,
/* Used to force the enum size */
TFM_CRYPTO_OPERATION_TYPE_MAX = INT_MAX
diff --git a/secure_fw/partitions/crypto/tfm_crypto_secure_api.c b/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
index 89b1ea6..8396c06 100644
--- a/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
+++ b/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -959,6 +959,7 @@
#ifdef TFM_PSA_API
size_t in_len = ARRAY_SIZE(in_vec);
+
if (additional_data == NULL) {
in_len--;
}
@@ -1028,6 +1029,7 @@
#ifdef TFM_PSA_API
size_t in_len = ARRAY_SIZE(in_vec);
+
if (additional_data == NULL) {
in_len--;
}
@@ -1044,6 +1046,386 @@
#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
}
+psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+ status = API_DISPATCH(tfm_crypto_aead_encrypt_setup,
+ TFM_CRYPTO_AEAD_ENCRYPT_SETUP);
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+ status = API_DISPATCH(tfm_crypto_aead_decrypt_setup,
+ TFM_CRYPTO_AEAD_DECRYPT_SETUP);
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
+ uint8_t *nonce,
+ size_t nonce_size,
+ size_t *nonce_length)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = nonce, .len = nonce_size}
+ };
+
+ status = API_DISPATCH(tfm_crypto_aead_generate_nonce,
+ TFM_CRYPTO_AEAD_GENERATE_NONCE);
+
+ *nonce_length = out_vec[1].len;
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
+ const uint8_t *nonce,
+ size_t nonce_length)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_SET_NONCE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = nonce, .len = nonce_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+ status = API_DISPATCH(tfm_crypto_aead_set_nonce,
+ TFM_CRYPTO_AEAD_SET_NONCE);
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
+ size_t ad_length,
+ size_t plaintext_length)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
+ .ad_length = ad_length,
+ .plaintext_length = plaintext_length,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+ status = API_DISPATCH(tfm_crypto_aead_set_lengths,
+ TFM_CRYPTO_AEAD_SET_LENGTHS);
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_UPDATE_AD_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional input */
+ if ((input == NULL) && (input_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, ARRAY_SIZE(out_vec));
+#else
+ status = API_DISPATCH(tfm_crypto_aead_update_ad,
+ TFM_CRYPTO_AEAD_UPDATE_AD);
+#endif
+
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_update(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_UPDATE_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional input */
+ if ((input == NULL) && (input_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = output, .len = output_size},
+ };
+
+#ifdef TFM_PSA_API
+ size_t in_len = ARRAY_SIZE(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, ARRAY_SIZE(out_vec));
+#else
+ status = API_DISPATCH(tfm_crypto_aead_update,
+ TFM_CRYPTO_AEAD_UPDATE);
+#endif
+
+ *output_length = out_vec[1].len;
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length,
+ uint8_t *tag,
+ size_t tag_size,
+ size_t *tag_length)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional output */
+ if ((ciphertext == NULL) && (ciphertext_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = tag, .len = tag_size},
+ {.base = ciphertext, .len = ciphertext_size}
+ };
+
+#ifdef TFM_PSA_API
+ size_t out_len = ARRAY_SIZE(out_vec);
+
+ if (ciphertext == NULL || ciphertext_size == 0) {
+ out_len--;
+ }
+ if ((out_len == 3) && (ciphertext_length == NULL)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,
+ in_vec, ARRAY_SIZE(in_vec),
+ out_vec, out_len);
+
+ if (out_len == 3) {
+ *ciphertext_length = out_vec[2].len;
+ } else {
+ *ciphertext_length = 0;
+ }
+
+#else
+ status = API_DISPATCH(tfm_crypto_aead_finish,
+ TFM_CRYPTO_AEAD_FINISH);
+
+ *ciphertext_length = out_vec[2].len;
+#endif
+
+ *tag_length = out_vec[1].len;
+
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length,
+ const uint8_t *tag,
+ size_t tag_length)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_VERIFY_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional output */
+ if ((plaintext == NULL) && (plaintext_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = tag, .len = tag_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = plaintext, .len = plaintext_size}
+ };
+
+#ifdef TFM_PSA_API
+ size_t out_len = ARRAY_SIZE(out_vec);
+
+ if (plaintext == NULL || plaintext_size == 0) {
+ out_len--;
+ }
+ if ((out_len == 2) && (plaintext_length == NULL)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,
+ in_vec, ARRAY_SIZE(in_vec),
+ out_vec, out_len);
+
+ if (out_len == 2) {
+ *plaintext_length = out_vec[1].len;
+ } else {
+ *plaintext_length = 0;
+ }
+
+#else
+ status = API_DISPATCH(tfm_crypto_aead_verify,
+ TFM_CRYPTO_AEAD_VERIFY);
+
+ *plaintext_length = out_vec[1].len;
+#endif
+
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
+psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
+{
+#ifdef TFM_CRYPTO_AEAD_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .sfn_id = TFM_CRYPTO_AEAD_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ status = API_DISPATCH(tfm_crypto_aead_abort,
+ TFM_CRYPTO_AEAD_ABORT);
+ return status;
+#endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
+}
+
psa_status_t psa_sign_message(psa_key_id_t key_id,
psa_algorithm_t alg,
const uint8_t *input,
@@ -1213,6 +1595,7 @@
#ifdef TFM_PSA_API
size_t in_len = ARRAY_SIZE(in_vec);
+
if (salt == NULL) {
in_len--;
}
@@ -1266,6 +1649,7 @@
#ifdef TFM_PSA_API
size_t in_len = ARRAY_SIZE(in_vec);
+
if (salt == NULL) {
in_len--;
}
@@ -1483,55 +1867,6 @@
#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
}
-psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
- const uint8_t *input,
- size_t input_length)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
-psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
- uint8_t *ciphertext,
- size_t ciphertext_size,
- size_t *ciphertext_length,
- uint8_t *tag,
- size_t tag_size,
- size_t *tag_length)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
-psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
- uint8_t *plaintext,
- size_t plaintext_size,
- size_t *plaintext_length,
- const uint8_t *tag,
- size_t tag_length)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
-psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
psa_status_t psa_mac_compute(psa_key_id_t key_id,
psa_algorithm_t alg,
const uint8_t *input,
@@ -1818,73 +2153,3 @@
return status;
#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
}
-
-psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
- psa_key_id_t key_id,
- psa_algorithm_t alg)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
-psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
- psa_key_id_t key_id,
- psa_algorithm_t alg)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
-psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
- uint8_t *nonce,
- size_t nonce_size,
- size_t *nonce_length)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
-psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
- const uint8_t *nonce,
- size_t nonce_length)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
-psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
- size_t ad_length,
- size_t plaintext_length)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}
-
-psa_status_t psa_aead_update(psa_aead_operation_t *operation,
- const uint8_t *input,
- size_t input_length,
- uint8_t *output,
- size_t output_size,
- size_t *output_length)
-{
- psa_status_t status;
-
- status = PSA_ERROR_NOT_SUPPORTED;
-
- return status;
-}