blob: 7e3afe04e2af52f467cc7e8be30a1611edc37732 [file] [log] [blame]
Antonio de Angelis8908f472018-08-31 15:44:25 +01001/*
Antonio de Angelisdab11b42022-01-10 14:21:04 +00002 * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
Antonio de Angelis8908f472018-08-31 15:44:25 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
Jamie Fox0e54ebc2019-04-09 14:21:04 +01008#include <stddef.h>
9#include <stdint.h>
Ken Liub671d682022-05-12 20:39:29 +080010#include <string.h>
Antonio de Angelis8908f472018-08-31 15:44:25 +010011
Jamie Fox0e54ebc2019-04-09 14:21:04 +010012#include "tfm_mbedcrypto_include.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010013
Antonio de Angelis8908f472018-08-31 15:44:25 +010014#include "tfm_crypto_api.h"
Jamie Fox0e54ebc2019-04-09 14:21:04 +010015#include "tfm_crypto_defs.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010016
17/**
Antonio de Angelis819c2f32019-02-06 14:32:02 +000018 * \def TFM_CRYPTO_CONC_OPER_NUM
19 *
Jamie Fox0e54ebc2019-04-09 14:21:04 +010020 * \brief This is the default value for the maximum number of concurrent
21 * operations that can be active (allocated) at any time, supported
22 * by the implementation
Antonio de Angelis8908f472018-08-31 15:44:25 +010023 */
Jamie Fox0e54ebc2019-04-09 14:21:04 +010024#ifndef TFM_CRYPTO_CONC_OPER_NUM
Antonio de Angelis8908f472018-08-31 15:44:25 +010025#define TFM_CRYPTO_CONC_OPER_NUM (8)
Jamie Fox0e54ebc2019-04-09 14:21:04 +010026#endif
Antonio de Angelis8908f472018-08-31 15:44:25 +010027
Antonio de Angelis8908f472018-08-31 15:44:25 +010028struct tfm_crypto_operation_s {
29 uint32_t in_use; /*!< Indicates if the operation is in use */
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010030 int32_t owner; /*!< Indicates an ID of the owner of
31 * the context
32 */
Antonio de Angelis8908f472018-08-31 15:44:25 +010033 enum tfm_crypto_operation_type type; /*!< Type of the operation */
34 union {
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010035 psa_cipher_operation_t cipher; /*!< Cipher operation context */
36 psa_mac_operation_t mac; /*!< MAC operation context */
37 psa_hash_operation_t hash; /*!< Hash operation context */
Antonio de Angelis04debbd2019-10-14 12:12:52 +010038 psa_key_derivation_operation_t key_deriv; /*!< Key derivation operation context */
Antonio de Angelisc26af632021-10-07 15:04:12 +010039 psa_aead_operation_t aead; /*!< AEAD operation context */
Antonio de Angelis8908f472018-08-31 15:44:25 +010040 } operation;
41};
42
43static struct tfm_crypto_operation_s operation[TFM_CRYPTO_CONC_OPER_NUM] ={{0}};
44
Antonio de Angelis819c2f32019-02-06 14:32:02 +000045/*
46 * \brief Function used to clear the memory associated to a backend context
47 *
48 * \param[in] index Numerical index in the database of the backend contexts
49 *
50 * \return None
51 *
52 */
Antonio de Angelis8908f472018-08-31 15:44:25 +010053static void memset_operation_context(uint32_t index)
54{
Antonio de Angelis819c2f32019-02-06 14:32:02 +000055 uint32_t mem_size;
Antonio de Angelis8908f472018-08-31 15:44:25 +010056
Antonio de Angelis819c2f32019-02-06 14:32:02 +000057 uint8_t *mem_ptr = (uint8_t *) &(operation[index].operation);
Antonio de Angelis8908f472018-08-31 15:44:25 +010058
59 switch(operation[index].type) {
60 case TFM_CRYPTO_CIPHER_OPERATION:
Jamie Fox0e54ebc2019-04-09 14:21:04 +010061 mem_size = sizeof(psa_cipher_operation_t);
Antonio de Angelis8908f472018-08-31 15:44:25 +010062 break;
63 case TFM_CRYPTO_MAC_OPERATION:
Jamie Fox0e54ebc2019-04-09 14:21:04 +010064 mem_size = sizeof(psa_mac_operation_t);
Antonio de Angelis8908f472018-08-31 15:44:25 +010065 break;
66 case TFM_CRYPTO_HASH_OPERATION:
Jamie Fox0e54ebc2019-04-09 14:21:04 +010067 mem_size = sizeof(psa_hash_operation_t);
Antonio de Angelis8908f472018-08-31 15:44:25 +010068 break;
Antonio de Angelis04debbd2019-10-14 12:12:52 +010069 case TFM_CRYPTO_KEY_DERIVATION_OPERATION:
70 mem_size = sizeof(psa_key_derivation_operation_t);
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +010071 break;
Antonio de Angelisc26af632021-10-07 15:04:12 +010072 case TFM_CRYPTO_AEAD_OPERATION:
73 mem_size = sizeof(psa_aead_operation_t);
74 break;
Antonio de Angelis8908f472018-08-31 15:44:25 +010075 case TFM_CRYPTO_OPERATION_NONE:
76 default:
77 mem_size = 0;
78 break;
79 }
80
Antonio de Angelis819c2f32019-02-06 14:32:02 +000081 /* Clear the contents of the backend context */
Ken Liub671d682022-05-12 20:39:29 +080082 (void)memset(mem_ptr, 0, mem_size);
Antonio de Angelis819c2f32019-02-06 14:32:02 +000083}
84
Antonio de Angelis8908f472018-08-31 15:44:25 +010085/*!
Antonio de Angelis202425a2022-04-06 11:13:15 +010086 * \defgroup alloc Function that implement allocation and deallocation of
87 * contexts to be stored in the secure world for multipart
88 * operations
Antonio de Angelis8908f472018-08-31 15:44:25 +010089 */
90
91/*!@{*/
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000092psa_status_t tfm_crypto_init_alloc(void)
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010093{
94 /* Clear the contents of the local contexts */
Ken Liub671d682022-05-12 20:39:29 +080095 (void)memset(operation, 0, sizeof(operation));
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000096 return PSA_SUCCESS;
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010097}
98
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000099psa_status_t tfm_crypto_operation_alloc(enum tfm_crypto_operation_type type,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100100 uint32_t *handle,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000101 void **ctx)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100102{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100103 uint32_t i = 0;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100104 int32_t partition_id = 0;
105 psa_status_t status;
106
107 status = tfm_crypto_get_caller_id(&partition_id);
108 if (status != PSA_SUCCESS) {
109 return status;
110 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000111
Jamie Fox707caf72019-05-29 15:14:18 +0100112 /* Handle must be initialised before calling a setup function */
113 if (*handle != TFM_CRYPTO_INVALID_HANDLE) {
Antonio de Angelis5cbaf322022-01-12 11:55:54 +0000114 if ((*handle <= TFM_CRYPTO_CONC_OPER_NUM) &&
115 (operation[*handle - 1].in_use == TFM_CRYPTO_IN_USE) &&
116 (operation[*handle - 1].owner == partition_id)) {
117 /* The handle is a valid one for already in progress operation */
118 return PSA_ERROR_BAD_STATE;
119 }
120
Antonio de Angelisdab11b42022-01-10 14:21:04 +0000121 return PSA_ERROR_INVALID_HANDLE;
Jamie Fox707caf72019-05-29 15:14:18 +0100122 }
123
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000124 /* Init to invalid values */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000125 if (ctx == NULL) {
126 return PSA_ERROR_INVALID_ARGUMENT;
127 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000128 *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100129
130 for (i=0; i<TFM_CRYPTO_CONC_OPER_NUM; i++) {
131 if (operation[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
132 operation[i].in_use = TFM_CRYPTO_IN_USE;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100133 operation[i].owner = partition_id;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100134 operation[i].type = type;
Jamie Fox707caf72019-05-29 15:14:18 +0100135 *handle = i + 1;
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000136 *ctx = (void *) &(operation[i].operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000137 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100138 }
139 }
Antonio de Angelis8908f472018-08-31 15:44:25 +0100140
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000141 return PSA_ERROR_NOT_PERMITTED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100142}
143
Antonio de Angelis4743e672019-04-11 11:38:48 +0100144psa_status_t tfm_crypto_operation_release(uint32_t *handle)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100145{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100146 uint32_t h_val = *handle;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100147 int32_t partition_id = 0;
148 psa_status_t status;
149
150 status = tfm_crypto_get_caller_id(&partition_id);
151 if (status != PSA_SUCCESS) {
152 return status;
153 }
Antonio de Angelis8908f472018-08-31 15:44:25 +0100154
Antonio de Angelis4743e672019-04-11 11:38:48 +0100155 if ( (h_val != TFM_CRYPTO_INVALID_HANDLE) &&
Jamie Fox707caf72019-05-29 15:14:18 +0100156 (h_val <= TFM_CRYPTO_CONC_OPER_NUM) &&
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100157 (operation[h_val - 1].in_use == TFM_CRYPTO_IN_USE) &&
158 (operation[h_val - 1].owner == partition_id)) {
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100159
Jamie Fox707caf72019-05-29 15:14:18 +0100160 memset_operation_context(h_val - 1);
161 operation[h_val - 1].in_use = TFM_CRYPTO_NOT_IN_USE;
162 operation[h_val - 1].type = TFM_CRYPTO_OPERATION_NONE;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100163 operation[h_val - 1].owner = 0;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100164 *handle = TFM_CRYPTO_INVALID_HANDLE;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000165 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100166 }
167
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000168 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100169}
170
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000171psa_status_t tfm_crypto_operation_lookup(enum tfm_crypto_operation_type type,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100172 uint32_t handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000173 void **ctx)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100174{
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100175 int32_t partition_id = 0;
176 psa_status_t status;
177
178 status = tfm_crypto_get_caller_id(&partition_id);
179 if (status != PSA_SUCCESS) {
180 return status;
181 }
182
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000183 if ( (handle != TFM_CRYPTO_INVALID_HANDLE) &&
Jamie Fox707caf72019-05-29 15:14:18 +0100184 (handle <= TFM_CRYPTO_CONC_OPER_NUM) &&
185 (operation[handle - 1].in_use == TFM_CRYPTO_IN_USE) &&
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100186 (operation[handle - 1].type == type) &&
187 (operation[handle - 1].owner == partition_id)) {
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100188
Jamie Fox707caf72019-05-29 15:14:18 +0100189 *ctx = (void *) &(operation[handle - 1].operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000190 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100191 }
192
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000193 return PSA_ERROR_BAD_STATE;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100194}
Antonio de Angelis202425a2022-04-06 11:13:15 +0100195
196psa_status_t tfm_crypto_operation_handling(enum tfm_crypto_operation_type type,
197 enum tfm_crypto_function_type function_type,
198 uint32_t *handle,
199 void **ctx)
200{
201 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
202
203 /* Multipart context retrieving and handling if required */
204 switch (function_type) {
205 case TFM_CRYPTO_FUNCTION_TYPE_SETUP:
206 /* Allocate the operation context in the secure world */
207 status = tfm_crypto_operation_alloc(type,
208 handle,
209 ctx);
210 break;
211 case TFM_CRYPTO_FUNCTION_TYPE_LOOKUP:
212 /* Look up the corresponding operation context */
213 status = tfm_crypto_operation_lookup(type,
214 *handle,
215 ctx);
216 break;
217 /* All the other APIs don't deal with multipart */
218 case TFM_CRYPTO_FUNCTION_TYPE_NON_MULTIPART:
219 status = PSA_ERROR_INVALID_ARGUMENT;
220 default:
221 break;
222 }
223
224 return status;
225}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100226/*!@}*/