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