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/interface/src/tfm_crypto_ipc_api.c b/interface/src/tfm_crypto_ipc_api.c
index c11fba0..0f9191c 100644
--- a/interface/src/tfm_crypto_ipc_api.c
+++ b/interface/src/tfm_crypto_ipc_api.c
@@ -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
*
@@ -125,7 +125,6 @@
status = API_DISPATCH(tfm_crypto_get_key_attributes,
TFM_CRYPTO_GET_KEY_ATTRIBUTES);
-
return status;
}
@@ -143,7 +142,6 @@
(void)API_DISPATCH(tfm_crypto_reset_key_attributes,
TFM_CRYPTO_RESET_KEY_ATTRIBUTES);
-
return;
}
@@ -211,7 +209,6 @@
status = API_DISPATCH_NO_OUTVEC(tfm_crypto_purge_key,
TFM_CRYPTO_PURGE_KEY);
-
return status;
}
@@ -228,7 +225,6 @@
psa_invec in_vec[] = {
{.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
{.base = attributes, .len = sizeof(psa_key_attributes_t)},
-
};
psa_outvec out_vec[] = {
@@ -814,6 +810,7 @@
in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
size_t in_len = IOVEC_LEN(in_vec);
+
if (additional_data == NULL) {
in_len--;
}
@@ -874,6 +871,7 @@
in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
size_t in_len = IOVEC_LEN(in_vec);
+
if (additional_data == NULL) {
in_len--;
}
@@ -885,6 +883,318 @@
return status;
}
+psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ 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;
+}
+
+psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ 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;
+}
+
+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;
+ 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;
+}
+
+psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
+ const uint8_t *nonce,
+ size_t nonce_length)
+{
+ 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;
+}
+
+psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
+ size_t ad_length,
+ size_t plaintext_length)
+{
+ 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;
+}
+
+psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+ 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)}
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+ 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;
+ 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},
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *output_length = out_vec[1].len;
+ 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;
+ 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}
+ };
+
+ size_t out_len = IOVEC_LEN(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, IOVEC_LEN(in_vec),
+ out_vec, out_len);
+
+ *tag_length = out_vec[1].len;
+
+ if (out_len == 3) {
+ *ciphertext_length = out_vec[2].len;
+ } else {
+ *ciphertext_length = 0;
+ }
+ 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;
+ 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},
+ };
+
+ size_t out_len = IOVEC_LEN(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, IOVEC_LEN(in_vec),
+ out_vec, out_len);
+
+ if (out_len == 2) {
+ *plaintext_length = out_vec[1].len;
+ } else {
+ *plaintext_length = 0;
+ }
+ return status;
+}
+
+psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
+{
+ 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;
+}
+
psa_status_t psa_sign_message(psa_key_id_t key,
psa_algorithm_t alg,
const uint8_t *input,
@@ -1034,6 +1344,7 @@
};
size_t in_len = IOVEC_LEN(in_vec);
+
if (salt == NULL) {
in_len--;
}
@@ -1078,6 +1389,7 @@
};
size_t in_len = IOVEC_LEN(in_vec);
+
if (salt == NULL) {
in_len--;
}
@@ -1161,8 +1473,7 @@
return status;
}
-psa_status_t psa_key_derivation_abort(
- psa_key_derivation_operation_t *operation)
+psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation)
{
psa_status_t status;
struct tfm_crypto_pack_iovec iov = {
@@ -1259,55 +1570,6 @@
return status;
}
-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,
psa_algorithm_t alg,
const uint8_t *input,
@@ -1484,7 +1746,6 @@
status = API_DISPATCH(tfm_crypto_key_derivation_setup,
TFM_CRYPTO_KEY_DERIVATION_SETUP);
-
return status;
}
@@ -1505,7 +1766,6 @@
status = API_DISPATCH_NO_OUTVEC(tfm_crypto_key_derivation_set_capacity,
TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY);
-
return status;
}
@@ -1529,7 +1789,6 @@
status = API_DISPATCH_NO_OUTVEC(tfm_crypto_key_derivation_input_bytes,
TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES);
-
return status;
}
@@ -1555,76 +1814,5 @@
status = API_DISPATCH(tfm_crypto_key_derivation_output_key,
TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY);
-
- return status;
-}
-
-psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
- psa_key_id_t key,
- 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,
- 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;
}