blob: 45a7eaede266cbfa8cccefd43acba38c11a3fa3f [file] [log] [blame]
Louis Mayencourt7a36f782018-09-24 14:00:57 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include "secure_fw/core/secure_utilities.h"
9#include "tfm_crypto_defs.h"
10
11#include "psa_crypto.h"
12
13#include "tfm_crypto_struct.h"
14
15#include "tfm_crypto_api.h"
16#include "crypto_utils.h"
17
Jamie Fox82b87ca2018-12-11 16:41:11 +000018/**
19 * \def CRYPTO_HMAC_MAX_KEY_LENGTH
20 *
21 * \brief Specifies the maximum key length supported by the
22 * HMAC operations in this implementation
23 */
24#ifndef CRYPTO_HMAC_MAX_KEY_LENGTH
25#define CRYPTO_HMAC_MAX_KEY_LENGTH (32)
26#endif
27
Louis Mayencourt7a36f782018-09-24 14:00:57 +010028static void mac_zeroize(void *data, size_t size)
29{
30 tfm_memset(data, 0, size);
31}
32
33static size_t get_hash_block_size(psa_algorithm_t alg)
34{
35 switch (alg) {
36 case PSA_ALG_MD2:
37 return 16;
38 case PSA_ALG_MD4:
39 return 64;
40 case PSA_ALG_MD5:
41 return 64;
42 case PSA_ALG_RIPEMD160:
43 return 64;
44 case PSA_ALG_SHA_1:
45 return 64;
46 case PSA_ALG_SHA_224:
47 return 64;
48 case PSA_ALG_SHA_256:
49 return 64;
50 case PSA_ALG_SHA_384:
51 return 128;
52 case PSA_ALG_SHA_512:
53 return 128;
54 default:
55 return 0;
56 }
57}
58
59static enum tfm_crypto_err_t tfm_crypto_hmac_setup(
60 struct tfm_mac_operation_s *ctx,
61 psa_key_slot_t key,
62 psa_algorithm_t alg)
63{
64 enum tfm_crypto_err_t err;
65 psa_key_type_t key_type;
66 size_t key_size;
Jamie Fox82b87ca2018-12-11 16:41:11 +000067 uint8_t key_data[CRYPTO_HMAC_MAX_KEY_LENGTH];
Louis Mayencourt7a36f782018-09-24 14:00:57 +010068 uint8_t hashed_key[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
69 size_t block_size;
70 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
71 uint8_t *opad = ctx->ctx.hmac.opad;
72 size_t i;
Jamie Foxefd82732018-11-26 10:34:32 +000073 psa_key_usage_t usage;
Louis Mayencourt7a36f782018-09-24 14:00:57 +010074
75 /* Check provided key */
76 err = tfm_crypto_get_key_information(key, &key_type, &key_size);
77 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
78 return err;
79 }
80
81 if (key_type != PSA_KEY_TYPE_HMAC){
82 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
83 }
84
Jamie Foxefd82732018-11-26 10:34:32 +000085 /* Set the key usage based on whether this is a sign or verify operation */
86 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
87 usage = PSA_KEY_USAGE_SIGN;
88 } else if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
89 usage = PSA_KEY_USAGE_VERIFY;
90 } else {
91 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
92 }
93
Louis Mayencourt7a36f782018-09-24 14:00:57 +010094 /* Get the key data to start the HMAC */
Jamie Foxefd82732018-11-26 10:34:32 +000095 err = tfm_crypto_get_key(key,
96 usage,
97 alg,
98 key_data,
Jamie Fox82b87ca2018-12-11 16:41:11 +000099 CRYPTO_HMAC_MAX_KEY_LENGTH,
Jamie Foxefd82732018-11-26 10:34:32 +0000100 &key_size);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100101 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
102 return err;
103 }
104
105 /* Bind the digest size to the MAC operation */
106 ctx->mac_size = PSA_HASH_SIZE(PSA_ALG_HMAC_HASH(alg));
107
108 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(alg));
109
110 /* The HMAC algorithm is the standard procedure as described in
111 * RFC-2104 (https://tools.ietf.org/html/rfc2104)
112 */
113 if (key_size > block_size) {
114 /* Hash the key to reduce it to block size */
115 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
116 PSA_ALG_HMAC_HASH(alg));
117 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
118 return err;
119 }
120
121 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
122 &key_data[0],
123 key_size);
124 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100125 return err;
126 }
127
128 /* Replace the key with the hashed key */
129 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
130 hashed_key, sizeof(hashed_key),
131 &key_size);
132 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100133 return err;
134 }
135 } else {
136 /* Copy the key inside the hashed_key buffer */
137 for (i=0; i<key_size; i++) {
138 hashed_key[i] = key_data[i];
139 }
140 }
141
142 /* Create ipad = hashed_key XOR 0x36 and opad = hashed_key XOR 0x5C */
143 for (i=0; i<key_size; i++) {
144 ipad[i] = hashed_key[i] ^ 0x36;
145 opad[i] = hashed_key[i] ^ 0x5C;
146 }
147 /* Fill ipad and opad to match block size */
148 for (i=key_size; i<block_size; i++) {
149 ipad[i] = 0x36;
150 opad[i] = 0x5C;
151 }
152
153 /* Start hash1 = H(i_key_pad || message) */
154 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
155 PSA_ALG_HMAC_HASH(alg));
156 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
157 /* Clear key information on stack */
158 for (i=0; i<key_size; i++) {
159 hashed_key[i] = 0;
160 ipad[i] = 0;
161 }
162 return err;
163 }
164
165 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
166 ipad,
167 block_size);
168 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100169 return err;
170 }
171
172 return TFM_CRYPTO_ERR_PSA_SUCCESS;
173}
174
175static enum tfm_crypto_err_t tfm_crypto_mac_setup(psa_mac_operation_t *operation,
176 psa_key_slot_t key,
177 psa_algorithm_t alg,
178 uint8_t sign_operation)
179{
180 enum tfm_crypto_err_t err;
181
182 struct tfm_mac_operation_s *ctx = NULL;
183
184 if (!PSA_ALG_IS_MAC(alg)) {
185 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
186 }
187
188 /* Validate pointers */
189 err = tfm_crypto_memory_check(operation,
190 sizeof(psa_mac_operation_t),
191 TFM_MEMORY_ACCESS_RW);
192 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
193 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
194 }
195
196 /* Allocate the operation context in the secure world */
197 err = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
198 &(operation->handle));
199 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
200 return err;
201 }
202
203 /* Look up the corresponding operation context */
204 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
205 operation->handle,
206 (void **)&ctx);
207 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
208 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000209 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100210 return err;
211 }
212
213 /* Bind the algorithm to the mac operation */
214 ctx->alg = alg;
215
216 /* Specify if this will be used for a sign or verify operation */
217 if (sign_operation) {
218 ctx->key_usage_verify = 0;
219 ctx->key_usage_sign = 1;
220 } else {
221 ctx->key_usage_verify = 1;
222 ctx->key_usage_sign = 0;
223 }
224
225 if (PSA_ALG_IS_HMAC(alg)) {
226 err = tfm_crypto_hmac_setup(ctx, key, alg);
227 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
228 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000229 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100230 return err;
231 }
232
233 ctx->key_set = 1;
234 } else {
235 /* Other MAC types constructions are not supported */
236 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000237 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100238 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
239 }
240
241 return TFM_CRYPTO_ERR_PSA_SUCCESS;
242}
243
244static enum tfm_crypto_err_t tfm_crypto_mac_finish(
245 struct tfm_mac_operation_s *ctx,
246 uint8_t *mac,
247 size_t mac_size,
248 size_t *mac_length)
249{
250 enum tfm_crypto_err_t err;
251 uint8_t hash1[PSA_HASH_MAX_SIZE];
252 size_t hash_size;
253 uint8_t *opad;
254 size_t block_size;
255
256 /* Sanity checks */
257 if (mac_size < ctx->mac_size) {
258 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
259 }
260
261 if (!(ctx->has_input)) {
262 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
263 }
264
265 if (PSA_ALG_IS_HMAC(ctx->alg)) {
266 opad = ctx->ctx.hmac.opad;
267 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(ctx->alg));
268
269 /* finish the hash1 = H(ipad || message) */
270 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
271 hash1,
272 sizeof(hash1),
273 &hash_size);
274 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
275 return err;
276 }
277
278 /* compute the final mac value = H(opad || hash1) */
279 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
280 PSA_ALG_HMAC_HASH(ctx->alg));
281 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
282 mac_zeroize(hash1, sizeof(hash1));
283 return err;
284 }
285
286 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
287 opad,
288 block_size);
289 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
290 mac_zeroize(hash1, sizeof(hash1));
291 return err;
292 }
293
294 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
295 hash1,
296 hash_size);
297 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
298 mac_zeroize(hash1, sizeof(hash1));
299 return err;
300 }
301
302 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
303 mac,
304 mac_size,
305 mac_length);
306 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
307 mac_zeroize(hash1, sizeof(hash1));
308 return err;
309 }
310
311 /* Clear intermediate hash value */
312 mac_zeroize(hash1, sizeof(hash1));
313
314 } else {
315 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
316 }
317
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100318 return TFM_CRYPTO_ERR_PSA_SUCCESS;
319}
320
321/*!
322 * \defgroup public_psa Public functions, PSA
323 *
324 */
325
326/*!@{*/
327enum tfm_crypto_err_t tfm_crypto_mac_sign_setup(psa_mac_operation_t *operation,
328 psa_key_slot_t key,
329 psa_algorithm_t alg)
330{
331 return tfm_crypto_mac_setup(operation, key, alg, 1);
332}
333
334enum tfm_crypto_err_t tfm_crypto_mac_verify_setup(
335 psa_mac_operation_t *operation,
336 psa_key_slot_t key,
337 psa_algorithm_t alg)
338{
339 return tfm_crypto_mac_setup(operation, key, alg, 0);
340}
341
342enum tfm_crypto_err_t tfm_crypto_mac_update(psa_mac_operation_t *operation,
343 const uint8_t *input,
344 size_t input_length)
345{
346 enum tfm_crypto_err_t err;
347
348 struct tfm_mac_operation_s *ctx = NULL;
349
350 if (input_length == 0) {
351 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
352 }
353
354 /* Validate pointers */
355 err = tfm_crypto_memory_check(operation,
356 sizeof(psa_mac_operation_t),
357 TFM_MEMORY_ACCESS_RW);
358 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
359 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
360 }
361
362 err = tfm_crypto_memory_check((void *)input,
363 input_length,
364 TFM_MEMORY_ACCESS_RO);
365 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
366 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
367 }
368
369 /* Look up the corresponding operation context */
370 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
371 operation->handle,
372 (void **)&ctx);
373 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
374 return err;
375 }
376
377 /* Sanity check */
378 if (!(ctx->key_set)) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000379 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100380 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
381 }
382
383 /* Process the input chunk */
384 if (PSA_ALG_IS_HMAC(ctx->alg)) {
385 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
386 input,
387 input_length);
388 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000389 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100390 return err;
391 }
392
393 /* Set this flag to avoid HMAC without data */
394 ctx->has_input = 1;
395 } else {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000396 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100397 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
398 }
399
400 return TFM_CRYPTO_ERR_PSA_SUCCESS;
401}
402
403enum tfm_crypto_err_t tfm_crypto_mac_sign_finish(psa_mac_operation_t *operation,
404 uint8_t *mac,
405 size_t mac_size,
406 size_t *mac_length)
407{
408 enum tfm_crypto_err_t err;
409 struct tfm_mac_operation_s *ctx = NULL;
410
411 if (mac_size == 0) {
412 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
413 }
414
415 /* Validate pointers */
416 err = tfm_crypto_memory_check(operation,
417 sizeof(psa_mac_operation_t),
418 TFM_MEMORY_ACCESS_RW);
419 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
420 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
421 }
422
423 err = tfm_crypto_memory_check((void *)mac,
424 mac_size,
425 TFM_MEMORY_ACCESS_RW);
426 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
427 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
428 }
429
430 err = tfm_crypto_memory_check(mac_length,
431 sizeof(size_t),
432 TFM_MEMORY_ACCESS_RW);
433 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
434 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
435 }
436
437 /* Look up the corresponding operation context */
438 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
439 operation->handle,
440 (void **)&ctx);
441 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
442 return err;
443 }
444
445 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
446 /* Finalise the mac operation */
447 err = tfm_crypto_mac_finish(ctx, mac, mac_size, mac_length);
448 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000449 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100450 return err;
451 }
452 /* Release the operation context */
453 err = tfm_crypto_operation_release(&(operation->handle));
454 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
455 return err;
456 }
457 } else {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000458 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100459 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
460 }
461
462 return TFM_CRYPTO_ERR_PSA_SUCCESS;
463}
464
465enum tfm_crypto_err_t tfm_crypto_mac_verify_finish(
466 psa_mac_operation_t *operation,
467 const uint8_t *mac,
468 size_t mac_length)
469{
470 enum tfm_crypto_err_t err;
471 struct tfm_mac_operation_s *ctx = NULL;
472 uint8_t computed_mac[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
473 size_t computed_mac_length;
474 size_t i;
475 uint32_t comp_mismatch = 0;
476
477 if (mac_length == 0) {
478 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
479 }
480
481 /* Validate pointers */
482 err = tfm_crypto_memory_check(operation,
483 sizeof(psa_mac_operation_t),
484 TFM_MEMORY_ACCESS_RW);
485 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
486 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
487 }
488
489 err = tfm_crypto_memory_check((void *)mac,
490 mac_length,
491 TFM_MEMORY_ACCESS_RO);
492 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
493 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
494 }
495
496 /* Look up the corresponding operation context */
497 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
498 operation->handle,
499 (void **)&ctx);
500 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
501 return err;
502 }
503
504 if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
505 /* Finalise the mac operation */
506 err = tfm_crypto_mac_finish(ctx,
507 computed_mac,
508 sizeof(computed_mac),
509 &computed_mac_length);
510 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000511 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100512 return err;
513 }
514 /* Release the operation context */
515 err = tfm_crypto_operation_release(&(operation->handle));
516 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
517 return err;
518 }
519
520 /* Check that the computed mac match the expected one */
521 if (computed_mac_length != mac_length) {
522 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
523 }
524
525 for (i=0; i<computed_mac_length ; i++) {
526 if (computed_mac[i] != mac[i]) {
527 comp_mismatch = 1;
528 }
529 }
530
531 if (comp_mismatch == 1) {
532 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
533 }
534 } else {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000535 (void)tfm_crypto_operation_release(&(operation->handle));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100536 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
537 }
538
539 return TFM_CRYPTO_ERR_PSA_SUCCESS;
540}
541
542enum tfm_crypto_err_t tfm_crypto_mac_abort(psa_mac_operation_t *operation)
543{
544 enum tfm_crypto_err_t err;
545 struct tfm_mac_operation_s *ctx = NULL;
546
547 /* Validate pointers */
548 err = tfm_crypto_memory_check(operation,
549 sizeof(psa_mac_operation_t),
550 TFM_MEMORY_ACCESS_RW);
551 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
552 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
553 }
554
555 /* Look up the corresponding operation context */
556 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
557 operation->handle,
558 (void **)&ctx);
559 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
560 return err;
561 }
562
563 if (PSA_ALG_IS_HMAC(ctx->alg)){
564 /* Check if the HMAC internal context needs to be deallocated */
565 if (ctx->ctx.hmac.hash_operation.handle != TFM_CRYPTO_INVALID_HANDLE) {
566 /* Clear hash context */
567 err = tfm_crypto_hash_abort(&(ctx->ctx.hmac.hash_operation));
568 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
569 return err;
570 }
571 }
572
573 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000574 err = tfm_crypto_operation_release(&(operation->handle));
575 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
576 return err;
577 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100578 } else {
579 /* MACs other than HMACs not currently supported */
580 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
581 }
582
583 return TFM_CRYPTO_ERR_PSA_SUCCESS;
584}
585/*!@}*/