Crypto: Check ownership of context
This patch introduces additional checks in the Crypto service
to make sure that a multipart operation context user is consistent
between calls. The same concept is extended to key handles which
are allocated subsequently and can be easily guessed.
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I16a9469682f203083a07ec623127fea71fd9f1e6
diff --git a/secure_fw/services/crypto/crypto_init.c b/secure_fw/services/crypto/crypto_init.c
index 73574c8..c719d07 100644
--- a/secure_fw/services/crypto/crypto_init.c
+++ b/secure_fw/services/crypto/crypto_init.c
@@ -16,6 +16,10 @@
*/
#include "mbedtls/memory_buffer_alloc.h"
+#ifndef TFM_PSA_API
+#include "tfm_secure_api.h"
+#endif
+
#ifdef TFM_PSA_API
#include "psa_service.h"
#include "tfm_crypto_signal.h"
@@ -58,8 +62,21 @@
__attribute__((__aligned__(TFM_CRYPTO_IOVEC_ALIGNMENT)))
uint8_t buf[TFM_CRYPTO_IOVEC_BUFFER_SIZE];
uint32_t alloc_index;
+ int32_t owner;
} scratch = {.buf = {0}, .alloc_index = 0};
+static psa_status_t tfm_crypto_set_scratch_owner(int32_t id)
+{
+ scratch.owner = id;
+ return PSA_SUCCESS;
+}
+
+static psa_status_t tfm_crypto_get_scratch_owner(int32_t *id)
+{
+ *id = scratch.owner;
+ return PSA_SUCCESS;
+}
+
static psa_status_t tfm_crypto_alloc_scratch(size_t requested_size, void **buf)
{
/* Ensure alloc_index remains aligned to the required iovec alignment */
@@ -81,6 +98,7 @@
static psa_status_t tfm_crypto_clear_scratch(void)
{
scratch.alloc_index = 0;
+ scratch.owner = 0;
(void)tfm_memset(scratch.buf, 0, sizeof(scratch.buf));
return PSA_SUCCESS;
@@ -114,6 +132,7 @@
/* Allocate necessary space in the internal scratch */
status = tfm_crypto_alloc_scratch(msg->in_size[i], &alloc_buf_ptr);
if (status != PSA_SUCCESS) {
+ (void)tfm_crypto_clear_scratch();
return status;
}
/* Read from the IPC framework inputs into the scratch */
@@ -132,6 +151,7 @@
/* Allocate necessary space for the output in the internal scratch */
status = tfm_crypto_alloc_scratch(msg->out_size[i], &alloc_buf_ptr);
if (status != PSA_SUCCESS) {
+ (void)tfm_crypto_clear_scratch();
return status;
}
/* Populate the fields of the output to the secure function */
@@ -139,6 +159,9 @@
out_vec[i].len = msg->out_size[i];
}
+ /* Set the owner of the data in the scratch */
+ (void)tfm_crypto_set_scratch_owner(msg->client_id);
+
/* Call the uniform signature API */
status = sfid_func_table[sfn_id](in_vec, in_len, out_vec, out_len);
@@ -271,6 +294,22 @@
return tfm_crypto_init_alloc();
}
+psa_status_t tfm_crypto_get_caller_id(int32_t *id)
+{
+#ifdef TFM_PSA_API
+ return tfm_crypto_get_scratch_owner(id);
+#else
+ int32_t res;
+
+ res = tfm_core_get_caller_client_id(id);
+ if (res != TFM_SUCCESS) {
+ return PSA_ERROR_NOT_PERMITTED;
+ } else {
+ return PSA_SUCCESS;
+ }
+#endif
+}
+
psa_status_t tfm_crypto_init(void)
{
psa_status_t status;