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_cipher.c b/secure_fw/partitions/crypto/crypto_cipher.c
index 85297a8..abaa259 100644
--- a/secure_fw/partitions/crypto/crypto_cipher.c
+++ b/secure_fw/partitions/crypto/crypto_cipher.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
@@ -35,9 +36,7 @@
psa_status_t status = PSA_SUCCESS;
psa_cipher_operation_t *operation = NULL;
- if ((in_len != 1) || (out_len != 2)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 2);
if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
(out_vec[0].len != sizeof(uint32_t))) {
@@ -85,9 +84,7 @@
psa_status_t status = PSA_SUCCESS;
psa_cipher_operation_t *operation = NULL;
- if ((in_len != 2) || (out_len != 1)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ 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))) {
@@ -132,9 +129,7 @@
psa_status_t status = PSA_SUCCESS;
psa_cipher_operation_t *operation = NULL;
- if ((in_len != 1) || (out_len != 1)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
if ((out_vec[0].len != sizeof(uint32_t)) ||
(in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
@@ -183,9 +178,7 @@
psa_status_t status = PSA_SUCCESS;
psa_cipher_operation_t *operation = NULL;
- if ((in_len != 1) || (out_len != 1)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
if ((out_vec[0].len != sizeof(uint32_t)) ||
(in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
@@ -234,14 +227,13 @@
psa_status_t status = PSA_SUCCESS;
psa_cipher_operation_t *operation = NULL;
- if ((in_len != 2) || (out_len != 2)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 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_CONNECTION_REFUSED;
}
+
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;
@@ -287,9 +279,7 @@
psa_status_t status = PSA_SUCCESS;
psa_cipher_operation_t *operation = NULL;
- if ((in_len != 1) || (out_len != 2)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 2);
if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
(out_vec[0].len != sizeof(uint32_t))) {
@@ -339,9 +329,7 @@
psa_status_t status = PSA_SUCCESS;
psa_cipher_operation_t *operation = NULL;
- if ((in_len != 1) || (out_len != 1)) {
- return PSA_ERROR_CONNECTION_REFUSED;
- }
+ 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))) {