blob: c21bc8588defff283d9199411e83e473fb2cd861 [file] [log] [blame]
Antonio de Angelis8908f472018-08-31 15:44:25 +01001/*
Kevin Peng6aa48952022-01-28 15:40:46 +08002 * 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 */
Antonio de Angelis202425a2022-04-06 11:13:15 +01007#include <stdbool.h>
Antonio de Angelis8908f472018-08-31 15:44:25 +01008
Xinyu Zhangd755b822022-10-25 11:18:09 +08009#include "config_crypto.h"
Jamie Fox0e54ebc2019-04-09 14:21:04 +010010#include "tfm_mbedcrypto_include.h"
11
Antonio de Angelis8908f472018-08-31 15:44:25 +010012#include "tfm_crypto_api.h"
Antonio de Angelis7557e682022-11-30 15:37:51 +000013#include "tfm_crypto_key.h"
Jamie Fox0e54ebc2019-04-09 14:21:04 +010014#include "tfm_crypto_defs.h"
Summer Qinc737ece2020-08-28 10:47:26 +080015#include "tfm_sp_log.h"
Summer Qinca6c1522022-06-17 14:25:55 +080016#include "crypto_check_config.h"
Raef Coles79809c72022-03-02 13:48:20 +000017#include "tfm_plat_crypto_keys.h"
Jamie Fox0e54ebc2019-04-09 14:21:04 +010018
19/*
20 * \brief This Mbed TLS include is needed to initialise the memory allocator
Antonio de Angelis202425a2022-04-06 11:13:15 +010021 * of the library used for internal allocations
Jamie Fox0e54ebc2019-04-09 14:21:04 +010022 */
23#include "mbedtls/memory_buffer_alloc.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010024
Sherry Zhange1524982022-06-08 16:57:59 +080025#include "mbedtls/platform.h"
26
Xinyu Zhangd755b822022-10-25 11:18:09 +080027#if CRYPTO_NV_SEED
Raef Coles618fc152021-06-18 09:26:46 +010028#include "tfm_plat_crypto_nv_seed.h"
29#endif /* CRYPTO_NV_SEED */
Summer Qina5448d62020-12-07 14:03:37 +080030
Raef Colesd2485af2019-10-30 10:15:33 +000031#ifdef CRYPTO_HW_ACCELERATOR
32#include "crypto_hw.h"
Michel Jaouenf41c6422021-10-07 14:38:08 +020033#endif /* CRYPTO_HW_ACCELERATOR */
Raef Colesd2485af2019-10-30 10:15:33 +000034
Ken Liub671d682022-05-12 20:39:29 +080035#include <string.h>
Kevin Pengfe730cc2022-04-11 17:48:42 +080036#include "psa/framework_feature.h"
Jamie Foxcc31d402019-01-28 17:13:52 +000037#include "psa/service.h"
Edison Aicc4c6162019-06-21 13:52:49 +080038#include "psa_manifest/tfm_crypto.h"
Antonio de Angelis4743e672019-04-11 11:38:48 +010039
40/**
Antonio de Angelis4743e672019-04-11 11:38:48 +010041 * \brief Aligns a value x up to an alignment a.
42 */
43#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
44
45/**
46 * \brief Maximum alignment required by any iovec parameters to the TF-M Crypto
47 * partition.
48 */
49#define TFM_CRYPTO_IOVEC_ALIGNMENT (4u)
50
Kevin Pengfe730cc2022-04-11 17:48:42 +080051#if PSA_FRAMEWORK_HAS_MM_IOVEC == 1
52static int32_t g_client_id;
53
54static void tfm_crypto_set_caller_id(int32_t id)
55{
56 g_client_id = id;
57}
58
59psa_status_t tfm_crypto_get_caller_id(int32_t *id)
60{
61 *id = g_client_id;
62 return PSA_SUCCESS;
63}
64
65static psa_status_t tfm_crypto_init_iovecs(const psa_msg_t *msg,
66 psa_invec in_vec[],
67 size_t in_len,
68 psa_outvec out_vec[],
69 size_t out_len)
70{
71 uint32_t i;
72
73 /* Map from the second element as the first is read when parsing */
74 for (i = 1; i < in_len; i++) {
75 in_vec[i].len = msg->in_size[i];
76 if (in_vec[i].len != 0) {
77 in_vec[i].base = psa_map_invec(msg->handle, i);
78 } else {
79 in_vec[i].base = NULL;
80 }
81 }
82
83 for (i = 0; i < out_len; i++) {
84 out_vec[i].len = msg->out_size[i];
85 if (out_vec[i].len != 0) {
86 out_vec[i].base = psa_map_outvec(msg->handle, i);
87 } else {
88 out_vec[i].base = NULL;
89 }
90 }
91
92 return PSA_SUCCESS;
93}
94#else /* PSA_FRAMEWORK_HAS_MM_IOVEC == 1 */
Antonio de Angelis4743e672019-04-11 11:38:48 +010095/**
Antonio de Angelis4743e672019-04-11 11:38:48 +010096 * \brief Internal scratch used for IOVec allocations
97 *
98 */
99static struct tfm_crypto_scratch {
100 __attribute__((__aligned__(TFM_CRYPTO_IOVEC_ALIGNMENT)))
Xinyu Zhangd755b822022-10-25 11:18:09 +0800101 uint8_t buf[CRYPTO_IOVEC_BUFFER_SIZE];
Antonio de Angelis4743e672019-04-11 11:38:48 +0100102 uint32_t alloc_index;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100103 int32_t owner;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100104} scratch = {.buf = {0}, .alloc_index = 0};
105
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100106static psa_status_t tfm_crypto_set_scratch_owner(int32_t id)
107{
108 scratch.owner = id;
109 return PSA_SUCCESS;
110}
111
112static psa_status_t tfm_crypto_get_scratch_owner(int32_t *id)
113{
114 *id = scratch.owner;
115 return PSA_SUCCESS;
116}
117
Antonio de Angelis4743e672019-04-11 11:38:48 +0100118static psa_status_t tfm_crypto_alloc_scratch(size_t requested_size, void **buf)
119{
120 /* Ensure alloc_index remains aligned to the required iovec alignment */
121 requested_size = ALIGN(requested_size, TFM_CRYPTO_IOVEC_ALIGNMENT);
122
123 if (requested_size > (sizeof(scratch.buf) - scratch.alloc_index)) {
124 return PSA_ERROR_INSUFFICIENT_MEMORY;
125 }
126
127 /* Compute the pointer to the allocated space */
128 *buf = (void *)&scratch.buf[scratch.alloc_index];
129
130 /* Increase the allocated size */
131 scratch.alloc_index += requested_size;
132
133 return PSA_SUCCESS;
134}
135
Kevin Pengfe730cc2022-04-11 17:48:42 +0800136static void tfm_crypto_clear_scratch(void)
Antonio de Angelis4743e672019-04-11 11:38:48 +0100137{
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100138 scratch.owner = 0;
Ken Liub671d682022-05-12 20:39:29 +0800139 (void)memset(scratch.buf, 0, scratch.alloc_index);
Summer Qin0a9e5372020-11-27 16:04:05 +0800140 scratch.alloc_index = 0;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100141}
142
Kevin Pengfe730cc2022-04-11 17:48:42 +0800143static void tfm_crypto_set_caller_id(int32_t id)
144{
145 /* Set the owner of the data in the scratch */
146 (void)tfm_crypto_set_scratch_owner(id);
147}
148
149psa_status_t tfm_crypto_get_caller_id(int32_t *id)
150{
151 return tfm_crypto_get_scratch_owner(id);
152}
153
154static psa_status_t tfm_crypto_init_iovecs(const psa_msg_t *msg,
155 psa_invec in_vec[],
156 size_t in_len,
157 psa_outvec out_vec[],
158 size_t out_len)
159{
160 uint32_t i;
161 void *alloc_buf_ptr = NULL;
162 psa_status_t status;
163
164 /* Alloc/read from the second element as the first is read when parsing */
165 for (i = 1; i < in_len; i++) {
166 /* Allocate necessary space in the internal scratch */
167 status = tfm_crypto_alloc_scratch(msg->in_size[i], &alloc_buf_ptr);
168 if (status != PSA_SUCCESS) {
169 tfm_crypto_clear_scratch();
170 return status;
171 }
172 /* Read from the IPC framework inputs into the scratch */
173 in_vec[i].len =
174 psa_read(msg->handle, i, alloc_buf_ptr, msg->in_size[i]);
175 /* Populate the fields of the input to the secure function */
176 in_vec[i].base = alloc_buf_ptr;
177 }
178
179 for (i = 0; i < out_len; i++) {
180 /* Allocate necessary space for the output in the internal scratch */
181 status = tfm_crypto_alloc_scratch(msg->out_size[i], &alloc_buf_ptr);
182 if (status != PSA_SUCCESS) {
183 tfm_crypto_clear_scratch();
184 return status;
185 }
186 /* Populate the fields of the output to the secure function */
187 out_vec[i].base = alloc_buf_ptr;
188 out_vec[i].len = msg->out_size[i];
189 }
190
191 return PSA_SUCCESS;
192}
193#endif /* PSA_FRAMEWORK_HAS_MM_IOVEC == 1 */
194
Kevin Peng2d4bc2e2022-01-28 16:19:30 +0800195static psa_status_t tfm_crypto_call_srv(const psa_msg_t *msg)
Antonio de Angelis4743e672019-04-11 11:38:48 +0100196{
197 psa_status_t status = PSA_SUCCESS;
TTornblomfaf74f52020-03-04 17:56:27 +0100198 size_t in_len = PSA_MAX_IOVEC, out_len = PSA_MAX_IOVEC, i;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100199 psa_invec in_vec[PSA_MAX_IOVEC] = { {NULL, 0} };
200 psa_outvec out_vec[PSA_MAX_IOVEC] = { {NULL, 0} };
Kevin Peng2d4bc2e2022-01-28 16:19:30 +0800201 struct tfm_crypto_pack_iovec iov = {0};
Antonio de Angelis4743e672019-04-11 11:38:48 +0100202
203 /* Check the number of in_vec filled */
Jamie Fox9a234e22019-04-30 11:12:05 +0100204 while ((in_len > 0) && (msg->in_size[in_len - 1] == 0)) {
205 in_len--;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100206 }
207
Kevin Pengfe730cc2022-04-11 17:48:42 +0800208 /* Check the number of out_vec filled */
209 while ((out_len > 0) && (msg->out_size[out_len - 1] == 0)) {
210 out_len--;
211 }
212
Antonio de Angelis4743e672019-04-11 11:38:48 +0100213 /* There will always be a tfm_crypto_pack_iovec in the first iovec */
214 if (in_len < 1) {
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100215 return PSA_ERROR_GENERIC_ERROR;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100216 }
Kevin Peng2d4bc2e2022-01-28 16:19:30 +0800217
218 if (psa_read(msg->handle, 0, &iov, sizeof(iov)) != sizeof(iov)) {
219 return PSA_ERROR_GENERIC_ERROR;
220 }
221
Antonio de Angelis4743e672019-04-11 11:38:48 +0100222 /* Initialise the first iovec with the IOV read when parsing */
Kevin Peng2d4bc2e2022-01-28 16:19:30 +0800223 in_vec[0].base = &iov;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100224 in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
225
Kevin Pengfe730cc2022-04-11 17:48:42 +0800226 status = tfm_crypto_init_iovecs(msg, in_vec, in_len, out_vec, out_len);
227 if (status != PSA_SUCCESS) {
228 return status;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100229 }
230
Kevin Pengfe730cc2022-04-11 17:48:42 +0800231 tfm_crypto_set_caller_id(msg->client_id);
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100232
Antonio de Angelis202425a2022-04-06 11:13:15 +0100233 /* Call the dispatcher to the functions that implement the PSA Crypto API */
234 status = tfm_crypto_api_dispatcher(in_vec, in_len, out_vec, out_len);
Antonio de Angelis4743e672019-04-11 11:38:48 +0100235
Kevin Pengfe730cc2022-04-11 17:48:42 +0800236#if PSA_FRAMEWORK_HAS_MM_IOVEC == 1
237 for (i = 0; i < out_len; i++) {
238 if (out_vec[i].base != NULL) {
239 psa_unmap_outvec(msg->handle, i, out_vec[i].len);
240 }
241 }
242#else
Antonio de Angelis4743e672019-04-11 11:38:48 +0100243 /* Write into the IPC framework outputs from the scratch */
244 for (i = 0; i < out_len; i++) {
245 psa_write(msg->handle, i, out_vec[i].base, out_vec[i].len);
246 }
247
248 /* Clear the allocated internal scratch before returning */
Summer Qin0a9e5372020-11-27 16:04:05 +0800249 tfm_crypto_clear_scratch();
Kevin Pengfe730cc2022-04-11 17:48:42 +0800250#endif
Antonio de Angelis4743e672019-04-11 11:38:48 +0100251
252 return status;
253}
Antonio de Angelis4743e672019-04-11 11:38:48 +0100254
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100255/**
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100256 * \brief Static buffer to be used by Mbed Crypto for memory allocations
257 *
258 */
Xinyu Zhangd755b822022-10-25 11:18:09 +0800259static uint8_t mbedtls_mem_buf[CRYPTO_ENGINE_BUF_SIZE] = {0};
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100260
261static psa_status_t tfm_crypto_engine_init(void)
262{
Xinyu Zhangd755b822022-10-25 11:18:09 +0800263#if CRYPTO_NV_SEED
Antonio de Angelis202425a2022-04-06 11:13:15 +0100264 LOG_INFFMT("[INF][Crypto] ");
Antonio de Angelis202425a2022-04-06 11:13:15 +0100265 LOG_INFFMT("Provisioning entropy seed... ");
Raef Coles618fc152021-06-18 09:26:46 +0100266 if (tfm_plat_crypto_provision_entropy_seed() != TFM_CRYPTO_NV_SEED_SUCCESS) {
Summer Qina5448d62020-12-07 14:03:37 +0800267 return PSA_ERROR_GENERIC_ERROR;
268 }
Antonio de Angelis202425a2022-04-06 11:13:15 +0100269 LOG_INFFMT("\033[0;32mcomplete.\033[0m\r\n");
Raef Coles618fc152021-06-18 09:26:46 +0100270#endif /* CRYPTO_NV_SEED */
Summer Qina5448d62020-12-07 14:03:37 +0800271
Antonio de Angelis202425a2022-04-06 11:13:15 +0100272 /* Initialise the Mbed Crypto memory allocator to use static memory
273 * allocation from the provided buffer instead of using the heap
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100274 */
275 mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf,
Xinyu Zhangd755b822022-10-25 11:18:09 +0800276 CRYPTO_ENGINE_BUF_SIZE);
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100277
Sherry Zhange1524982022-06-08 16:57:59 +0800278 /* mbedtls_printf is used to print messages including error information. */
279#if (TFM_PARTITION_LOG_LEVEL >= TFM_PARTITION_LOG_LEVEL_ERROR)
Ken Liu53b2e332022-09-29 10:56:16 +0800280 mbedtls_platform_set_printf(printf);
Sherry Zhange1524982022-06-08 16:57:59 +0800281#endif
282
Antonio de Angelis695d75b2022-08-22 15:06:24 +0100283 /* Initialise the crypto accelerator if one is enabled. If the driver API is
284 * the one defined by the PSA Unified Driver interface, the initialisation is
285 * performed directly through psa_crypto_init() while the PSA subsystem is
286 * initialised
287 */
288#if defined(CRYPTO_HW_ACCELERATOR) && defined(CC312_LEGACY_DRIVER_API_ENABLED)
Antonio de Angelis202425a2022-04-06 11:13:15 +0100289 LOG_INFFMT("[INF][Crypto] Initialising HW accelerator... ");
Raef Colesd2485af2019-10-30 10:15:33 +0000290 if (crypto_hw_accelerator_init() != 0) {
291 return PSA_ERROR_HARDWARE_FAILURE;
292 }
Antonio de Angelis202425a2022-04-06 11:13:15 +0100293 LOG_INFFMT("\033[0;32mcomplete.\033[0m\r\n");
Raef Colesd2485af2019-10-30 10:15:33 +0000294#endif /* CRYPTO_HW_ACCELERATOR */
295
Antonio de Angelis695d75b2022-08-22 15:06:24 +0100296 /* Perform the initialisation of the PSA subsystem in the Mbed Crypto
297 * library. If a driver is built using the PSA Driver interface, the function
298 * below will perform also the same operations as crypto_hw_accelerator_init()
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100299 */
300 return psa_crypto_init();
301}
302
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000303static psa_status_t tfm_crypto_module_init(void)
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100304{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100305 /* Init the Alloc module */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000306 return tfm_crypto_init_alloc();
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100307}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100308
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000309psa_status_t tfm_crypto_init(void)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100310{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100311 psa_status_t status;
Raef Coles79809c72022-03-02 13:48:20 +0000312 enum tfm_plat_err_t plat_err;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100313
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100314 /* Initialise other modules of the service */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000315 status = tfm_crypto_module_init();
316 if (status != PSA_SUCCESS) {
317 return status;
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100318 }
319
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100320 /* Initialise the engine layer */
Raef Coles79809c72022-03-02 13:48:20 +0000321 status = tfm_crypto_engine_init();
322 if (status != PSA_SUCCESS) {
323 return status;
324 }
325
326 plat_err = tfm_plat_load_builtin_keys();
327 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
328 return PSA_ERROR_GENERIC_ERROR;
329 }
330
331 return PSA_SUCCESS;
Kevin Peng2d4bc2e2022-01-28 16:19:30 +0800332}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100333
Kevin Peng2d4bc2e2022-01-28 16:19:30 +0800334psa_status_t tfm_crypto_sfn(const psa_msg_t *msg)
335{
336 /* Process the message type */
337 switch (msg->type) {
338 case PSA_IPC_CALL:
339 return tfm_crypto_call_srv(msg);
340 default:
341 return PSA_ERROR_NOT_SUPPORTED;
342 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100343
Kevin Peng2d4bc2e2022-01-28 16:19:30 +0800344 return PSA_ERROR_GENERIC_ERROR;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100345}
Antonio de Angelis202425a2022-04-06 11:13:15 +0100346
347psa_status_t tfm_crypto_api_dispatcher(psa_invec in_vec[],
348 size_t in_len,
349 psa_outvec out_vec[],
350 size_t out_len)
351{
352 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
353 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
354 int32_t caller_id = 0;
Antonio de Angelis7557e682022-11-30 15:37:51 +0000355 struct tfm_crypto_key_id_s encoded_key = TFM_CRYPTO_KEY_ID_S_INIT;
Antonio de Angelis202425a2022-04-06 11:13:15 +0100356 bool is_key_required = false;
David Huc9679cc2022-06-21 13:09:34 +0800357 enum tfm_crypto_group_id group_id;
Antonio de Angelis202425a2022-04-06 11:13:15 +0100358
359 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
360 return PSA_ERROR_PROGRAMMER_ERROR;
361 }
362
David Huc9679cc2022-06-21 13:09:34 +0800363 group_id = TFM_CRYPTO_GET_GROUP_ID(iov->function_id);
364
365 is_key_required = !((group_id == TFM_CRYPTO_GROUP_ID_HASH) ||
366 (group_id == TFM_CRYPTO_GROUP_ID_RANDOM));
Antonio de Angelis202425a2022-04-06 11:13:15 +0100367
368 if (is_key_required) {
369 status = tfm_crypto_get_caller_id(&caller_id);
370 if (status != PSA_SUCCESS) {
371 return status;
372 }
373 /* The caller_id being set in the owner field is the partition ID
374 * of the calling partition
375 */
Antonio de Angelis7557e682022-11-30 15:37:51 +0000376 encoded_key.key_id = iov->key_id;
377 encoded_key.owner = caller_id;
Antonio de Angelis202425a2022-04-06 11:13:15 +0100378 }
379
380 /* Dispatch to each sub-module based on the Group ID */
David Huc9679cc2022-06-21 13:09:34 +0800381 switch (group_id) {
382 case TFM_CRYPTO_GROUP_ID_KEY_MANAGEMENT:
383 return tfm_crypto_key_management_interface(in_vec, out_vec,
384 &encoded_key);
385 case TFM_CRYPTO_GROUP_ID_HASH:
386 return tfm_crypto_hash_interface(in_vec, out_vec);
387 case TFM_CRYPTO_GROUP_ID_MAC:
388 return tfm_crypto_mac_interface(in_vec, out_vec, &encoded_key);
389 case TFM_CRYPTO_GROUP_ID_CIPHER:
390 return tfm_crypto_cipher_interface(in_vec, out_vec, &encoded_key);
391 case TFM_CRYPTO_GROUP_ID_AEAD:
392 return tfm_crypto_aead_interface(in_vec, out_vec, &encoded_key);
393 case TFM_CRYPTO_GROUP_ID_ASYM_SIGN:
394 return tfm_crypto_asymmetric_sign_interface(in_vec, out_vec,
395 &encoded_key);
396 case TFM_CRYPTO_GROUP_ID_ASYM_ENCRYPT:
397 return tfm_crypto_asymmetric_encrypt_interface(in_vec, out_vec,
398 &encoded_key);
399 case TFM_CRYPTO_GROUP_ID_KEY_DERIVATION:
400 return tfm_crypto_key_derivation_interface(in_vec, out_vec,
401 &encoded_key);
402 case TFM_CRYPTO_GROUP_ID_RANDOM:
403 return tfm_crypto_random_interface(in_vec, out_vec);
404 default:
Antonio de Angelis202425a2022-04-06 11:13:15 +0100405 LOG_ERRFMT("[ERR][Crypto] Unsupported request!\r\n");
David Huc9679cc2022-06-21 13:09:34 +0800406 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis202425a2022-04-06 11:13:15 +0100407 }
408
David Huc9679cc2022-06-21 13:09:34 +0800409 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis202425a2022-04-06 11:13:15 +0100410}