Crypto: Fix difference between IPC and Library mode
This patch fixes the difference in empty buffer handling between
IPC mode and Library mode. In the IPC mode implementation for Crypto
partition, the function tfm_crypto_call_sfn() reduces the empty
buffers in IOVEC[] from `in_len` and `out_len`. In Library mode,
these empty buffers are still accounted for in `in_len` and
`out_len`. This meant that the generic sanity check within
each Crypto Service API was failing for IPC mode when empty
buffers were passed in by the client.
This patch introduces a macro which validates `in_len` and `out_len`
differently for IPC mode and Library mode. For IPC mode, the lengths
are compared against an expected range of values. For Library mode,
the lengths are validated against a fixed value as expected by the
API.
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Change-Id: I55e79a31fcf7d16329aa8166fc704455ca01ac20
diff --git a/secure_fw/partitions/crypto/crypto_aead.c b/secure_fw/partitions/crypto/crypto_aead.c
index f663ae6..ebb522f 100644
--- a/secure_fw/partitions/crypto/crypto_aead.c
+++ b/secure_fw/partitions/crypto/crypto_aead.c
@@ -17,6 +17,7 @@
#include "tfm_crypto_api.h"
#include "tfm_crypto_defs.h"
+#include "tfm_crypto_private.h"
/*!
* \defgroup public_psa Public functions, PSA
@@ -34,13 +35,12 @@
#else
psa_status_t status = PSA_SUCCESS;
- if ( !((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 3, out_len, 0, 1);
if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_ERROR_CONNECTION_REFUSED;
}
+
const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
const struct tfm_crypto_aead_pack_input *aead_pack_input = &iov->aead_in;
psa_key_handle_t key_handle = iov->key_handle;
@@ -51,16 +51,10 @@
size_t plaintext_length = in_vec[1].len;
uint8_t *ciphertext = out_vec[0].base;
size_t ciphertext_size = out_vec[0].len;
- const uint8_t *additional_data = NULL;
- size_t additional_data_length = 0;
+ const uint8_t *additional_data = in_vec[2].base;
+ size_t additional_data_length = in_vec[2].len;
- /* Check if additional data has been passed and initialise it */
- if (in_len == 3) {
- additional_data = in_vec[2].base;
- additional_data_length = in_vec[2].len;
- }
-
- /* Initialise ciphertext_length to zero */
+ /* Initialise ciphertext_length to zero. */
out_vec[0].len = 0;
status = tfm_crypto_check_handle_owner(key_handle, NULL);
@@ -86,13 +80,12 @@
#else
psa_status_t status = PSA_SUCCESS;
- if ( !((in_len == 2) || (in_len == 3)) || (out_len > 1)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 3, out_len, 0, 1);
if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
return PSA_ERROR_CONNECTION_REFUSED;
}
+
const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
const struct tfm_crypto_aead_pack_input *aead_pack_input = &iov->aead_in;
psa_key_handle_t key_handle = iov->key_handle;
@@ -103,16 +96,10 @@
size_t ciphertext_length = in_vec[1].len;
uint8_t *plaintext = out_vec[0].base;
size_t plaintext_size = out_vec[0].len;
- const uint8_t *additional_data = NULL;
- size_t additional_data_length = 0;
+ const uint8_t *additional_data = in_vec[2].base;
+ size_t additional_data_length = in_vec[2].len;
- /* Check if additional data has been passed and initialise it */
- if (in_len == 3) {
- additional_data = in_vec[2].base;
- additional_data_length = in_vec[2].len;
- }
-
- /* Initialise plaintext_length to zero */
+ /* Initialise plaintext_length to zero. */
out_vec[0].len = 0;
status = tfm_crypto_check_handle_owner(key_handle, NULL);