Crypto: psa_aead_verify()/finish() can have NULL pointer outputs
The psa_aead_verify() and psa_aead_finish() APIs can have cases
where the output pointers for plaintext and ciphertext are NULL
or zero-length hence need to be handled accordingly by the
interface as the IPC framework would result in error in these
cases.
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: Ic1885d130c8e7eae1a928623153a93a43b280292
diff --git a/interface/src/tfm_crypto_ipc_api.c b/interface/src/tfm_crypto_ipc_api.c
index 67842ac..29fbf95 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
*
@@ -1068,20 +1068,38 @@
.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 = ciphertext, .len = ciphertext_size},
{.base = tag, .len = tag_size},
+ {.base = ciphertext, .len = ciphertext_size}
};
- status = API_DISPATCH(tfm_crypto_aead_finish,
- TFM_CRYPTO_AEAD_FINISH);
+ 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;
+ }
- *ciphertext_length = out_vec[1].len;
- *tag_length = out_vec[2].len;
+ 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;
}
@@ -1098,6 +1116,11 @@
.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}
@@ -1107,10 +1130,22 @@
{.base = plaintext, .len = plaintext_size},
};
- status = API_DISPATCH(tfm_crypto_aead_verify,
- TFM_CRYPTO_AEAD_VERIFY);
+ 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;
+ }
- *plaintext_length = out_vec[1].len;
+ 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;
}