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/tfm_crypto_private.h b/secure_fw/partitions/crypto/tfm_crypto_private.h
new file mode 100644
index 0000000..e3ec377
--- /dev/null
+++ b/secure_fw/partitions/crypto/tfm_crypto_private.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CRYPTO_PRIVATE_H__
+#define __TFM_CRYPTO_PRIVATE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef TFM_PSA_API
+/*
+ * Validate the IOVEC[] lengths for IPC model. The tfm_crypto_call_sfn()
+ * reduces the entries in IOVEC[] which are empty from `in_len` and `out_len`.
+ * This means that Crypto service APIs need to ensure that the `in_len`
+ * and `out_len` are within the expected range.
+ *
+ * Also tfm_crypto_call_sfn() ensures that all entries in IOVEC[] are
+ * initialised. Hence all entries in IOVEC[] can be accessed to
+ * initialize internal variables even if they are outside `in_len`
+ * and `out_len`.
+ */
+#define CRYPTO_IN_OUT_LEN_VALIDATE(in_len, in_min, in_max, out_len, out_min, out_max) \
+ if (!(((in_len) >= (in_min)) && ((in_len) <= (in_max))) || \
+ !(((out_len) >= (out_min)) && ((out_len) <= (out_max)))) { \
+ return PSA_ERROR_PROGRAMMER_ERROR; \
+ }
+#else
+/*
+ * Validate the IOVEC[] lengths for Library model. Unlike the IPC model, the
+ * service APIs expects to receive the exact of `in_len` and `out_len`
+ * as expected by the API.
+ */
+#define CRYPTO_IN_OUT_LEN_VALIDATE(in_len, in_min, in_max, out_len, out_min, out_max) \
+ if (((in_len) != (in_max)) || ((out_len) != (out_max))) { \
+ return PSA_ERROR_PROGRAMMER_ERROR; \
+ }
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_CRYPTO_PRIVATE_H__ */