1 /*
2 * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11
12 #include "config_crypto.h"
13 #include "tfm_mbedcrypto_include.h"
14
15 #include "tfm_crypto_api.h"
16 #include "tfm_crypto_defs.h"
17
18
19 struct tfm_crypto_operation_s {
20 uint32_t in_use; /*!< Indicates if the operation is in use */
21 int32_t owner; /*!< Indicates an ID of the owner of
22 * the context
23 */
24 enum tfm_crypto_operation_type type; /*!< Type of the operation */
25 union {
26 psa_cipher_operation_t cipher; /*!< Cipher operation context */
27 psa_mac_operation_t mac; /*!< MAC operation context */
28 psa_hash_operation_t hash; /*!< Hash operation context */
29 psa_key_derivation_operation_t key_deriv; /*!< Key derivation operation context */
30 psa_aead_operation_t aead; /*!< AEAD operation context */
31 } operation;
32 };
33
34 static struct tfm_crypto_operation_s operations[CRYPTO_CONC_OPER_NUM] = {{0}};
35
36 /*
37 * \brief Function used to clear the memory associated to a backend context
38 *
39 * \param[in] index Numerical index in the database of the backend contexts
40 *
41 * \return None
42 *
43 */
memset_operation_context(uint32_t index)44 static void memset_operation_context(uint32_t index)
45 {
46 /* Clear the contents of the backend context */
47 (void)memset((uint8_t *)&(operations[index].operation), 0,
48 sizeof(operations[index].operation));
49 }
50
51 /*!
52 * \defgroup alloc Function that implement allocation and deallocation of
53 * contexts to be stored in the secure world for multipart
54 * operations
55 */
56
57 /*!@{*/
tfm_crypto_init_alloc(void)58 psa_status_t tfm_crypto_init_alloc(void)
59 {
60 /* Clear the contents of the local contexts */
61 (void)memset(operations, 0, sizeof(operations));
62 return PSA_SUCCESS;
63 }
64
tfm_crypto_operation_alloc(enum tfm_crypto_operation_type type,uint32_t * handle,void ** ctx)65 psa_status_t tfm_crypto_operation_alloc(enum tfm_crypto_operation_type type,
66 uint32_t *handle,
67 void **ctx)
68 {
69 uint32_t i = 0;
70 int32_t partition_id = 0;
71 psa_status_t status;
72
73 /* Handle must be initialised before calling a setup function */
74 if (*handle != TFM_CRYPTO_INVALID_HANDLE) {
75 return PSA_ERROR_BAD_STATE;
76 }
77
78 /* Init to invalid values */
79 if (ctx == NULL) {
80 return PSA_ERROR_INVALID_ARGUMENT;
81 }
82 *ctx = NULL;
83
84 status = tfm_crypto_get_caller_id(&partition_id);
85 if (status != PSA_SUCCESS) {
86 return status;
87 }
88
89 for (i = 0; i < CRYPTO_CONC_OPER_NUM; i++) {
90 if (operations[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
91 operations[i].in_use = TFM_CRYPTO_IN_USE;
92 operations[i].owner = partition_id;
93 operations[i].type = type;
94 *handle = i + 1;
95 *ctx = (void *) &(operations[i].operation);
96 return PSA_SUCCESS;
97 }
98 }
99
100 return PSA_ERROR_NOT_PERMITTED;
101 }
102
tfm_crypto_operation_release(uint32_t * handle)103 psa_status_t tfm_crypto_operation_release(uint32_t *handle)
104 {
105 uint32_t h_val = *handle;
106 int32_t partition_id = 0;
107 psa_status_t status;
108
109 /* Handle shall be cleaned up always at first */
110 *handle = TFM_CRYPTO_INVALID_HANDLE;
111
112 if ((h_val == TFM_CRYPTO_INVALID_HANDLE) ||
113 (h_val > CRYPTO_CONC_OPER_NUM)) {
114 return PSA_ERROR_INVALID_ARGUMENT;
115 }
116
117 status = tfm_crypto_get_caller_id(&partition_id);
118 if (status != PSA_SUCCESS) {
119 return status;
120 }
121
122 if ((operations[h_val - 1].in_use == TFM_CRYPTO_IN_USE) &&
123 (operations[h_val - 1].owner == partition_id)) {
124
125 memset_operation_context(h_val - 1);
126 operations[h_val - 1].in_use = TFM_CRYPTO_NOT_IN_USE;
127 operations[h_val - 1].type = TFM_CRYPTO_OPERATION_NONE;
128 operations[h_val - 1].owner = 0;
129
130 return PSA_SUCCESS;
131 }
132
133 return PSA_ERROR_INVALID_ARGUMENT;
134 }
135
tfm_crypto_operation_lookup(enum tfm_crypto_operation_type type,uint32_t handle,void ** ctx)136 psa_status_t tfm_crypto_operation_lookup(enum tfm_crypto_operation_type type,
137 uint32_t handle,
138 void **ctx)
139 {
140 int32_t partition_id = 0;
141 psa_status_t status;
142
143 if ((handle == TFM_CRYPTO_INVALID_HANDLE) ||
144 (handle > CRYPTO_CONC_OPER_NUM)) {
145 return PSA_ERROR_BAD_STATE;
146 }
147
148 if (ctx == NULL) {
149 return PSA_ERROR_INVALID_ARGUMENT;
150 }
151
152 status = tfm_crypto_get_caller_id(&partition_id);
153 if (status != PSA_SUCCESS) {
154 return status;
155 }
156
157 if ((operations[handle - 1].in_use == TFM_CRYPTO_IN_USE) &&
158 (operations[handle - 1].type == type) &&
159 (operations[handle - 1].owner == partition_id)) {
160 *ctx = (void *) &(operations[handle - 1].operation);
161 return PSA_SUCCESS;
162 }
163
164 return PSA_ERROR_BAD_STATE;
165 }
166 /*!@}*/
167