blob: 2ffe33132ab1648408c842f29e0b0fd3d1110868 [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
Tamas Ban8bd24b72019-02-19 12:13:13 +00008#include "secure_fw/core/tfm_memory_utils.h"
Louis Mayencourt7a36f782018-09-24 14:00:57 +01009#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/**
Antonio de Angelis819c2f32019-02-06 14:32:02 +000019 * \def UNUSED_VAR
20 *
21 * \brief an UNUSED_VAR() macro for better code readability
22 */
23#define UNUSED_VAR(x) (void)x
24
25/**
Jamie Fox82b87ca2018-12-11 16:41:11 +000026 * \def CRYPTO_HMAC_MAX_KEY_LENGTH
27 *
28 * \brief Specifies the maximum key length supported by the
29 * HMAC operations in this implementation
30 */
31#ifndef CRYPTO_HMAC_MAX_KEY_LENGTH
32#define CRYPTO_HMAC_MAX_KEY_LENGTH (32)
33#endif
34
Louis Mayencourt7a36f782018-09-24 14:00:57 +010035static void mac_zeroize(void *data, size_t size)
36{
37 tfm_memset(data, 0, size);
38}
39
40static size_t get_hash_block_size(psa_algorithm_t alg)
41{
42 switch (alg) {
43 case PSA_ALG_MD2:
44 return 16;
45 case PSA_ALG_MD4:
46 return 64;
47 case PSA_ALG_MD5:
48 return 64;
49 case PSA_ALG_RIPEMD160:
50 return 64;
51 case PSA_ALG_SHA_1:
52 return 64;
53 case PSA_ALG_SHA_224:
54 return 64;
55 case PSA_ALG_SHA_256:
56 return 64;
57 case PSA_ALG_SHA_384:
58 return 128;
59 case PSA_ALG_SHA_512:
60 return 128;
61 default:
62 return 0;
63 }
64}
65
Antonio de Angelis819c2f32019-02-06 14:32:02 +000066static enum tfm_crypto_err_t tfm_crypto_mac_release(
67 psa_mac_operation_t *operation,
68 struct tfm_mac_operation_s *ctx)
69{
70 enum tfm_crypto_err_t err;
71
72 /* No release necessary on the ctx related quantites for the time being */
73 UNUSED_VAR(ctx);
74
75 /* Release the operation context */
76 err = tfm_crypto_operation_release(TFM_CRYPTO_MAC_OPERATION, operation);
77 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
78 return err;
79 }
80
81 return TFM_CRYPTO_ERR_PSA_SUCCESS;
82}
83
Louis Mayencourt7a36f782018-09-24 14:00:57 +010084static enum tfm_crypto_err_t tfm_crypto_hmac_setup(
85 struct tfm_mac_operation_s *ctx,
86 psa_key_slot_t key,
87 psa_algorithm_t alg)
88{
89 enum tfm_crypto_err_t err;
90 psa_key_type_t key_type;
91 size_t key_size;
Jamie Fox82b87ca2018-12-11 16:41:11 +000092 uint8_t key_data[CRYPTO_HMAC_MAX_KEY_LENGTH];
Louis Mayencourt7a36f782018-09-24 14:00:57 +010093 uint8_t hashed_key[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
94 size_t block_size;
95 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
96 uint8_t *opad = ctx->ctx.hmac.opad;
97 size_t i;
Jamie Foxefd82732018-11-26 10:34:32 +000098 psa_key_usage_t usage;
Louis Mayencourt7a36f782018-09-24 14:00:57 +010099
100 /* Check provided key */
101 err = tfm_crypto_get_key_information(key, &key_type, &key_size);
102 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
103 return err;
104 }
105
106 if (key_type != PSA_KEY_TYPE_HMAC){
107 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
108 }
109
Jamie Foxefd82732018-11-26 10:34:32 +0000110 /* Set the key usage based on whether this is a sign or verify operation */
111 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
112 usage = PSA_KEY_USAGE_SIGN;
113 } else if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
114 usage = PSA_KEY_USAGE_VERIFY;
115 } else {
116 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
117 }
118
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100119 /* Get the key data to start the HMAC */
Jamie Foxefd82732018-11-26 10:34:32 +0000120 err = tfm_crypto_get_key(key,
121 usage,
122 alg,
123 key_data,
Jamie Fox82b87ca2018-12-11 16:41:11 +0000124 CRYPTO_HMAC_MAX_KEY_LENGTH,
Jamie Foxefd82732018-11-26 10:34:32 +0000125 &key_size);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100126 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
127 return err;
128 }
129
130 /* Bind the digest size to the MAC operation */
131 ctx->mac_size = PSA_HASH_SIZE(PSA_ALG_HMAC_HASH(alg));
132
133 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(alg));
134
135 /* The HMAC algorithm is the standard procedure as described in
136 * RFC-2104 (https://tools.ietf.org/html/rfc2104)
137 */
138 if (key_size > block_size) {
139 /* Hash the key to reduce it to block size */
140 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
141 PSA_ALG_HMAC_HASH(alg));
142 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
143 return err;
144 }
145
146 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
147 &key_data[0],
148 key_size);
149 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100150 return err;
151 }
152
153 /* Replace the key with the hashed key */
154 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
155 hashed_key, sizeof(hashed_key),
156 &key_size);
157 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100158 return err;
159 }
160 } else {
161 /* Copy the key inside the hashed_key buffer */
162 for (i=0; i<key_size; i++) {
163 hashed_key[i] = key_data[i];
164 }
165 }
166
167 /* Create ipad = hashed_key XOR 0x36 and opad = hashed_key XOR 0x5C */
168 for (i=0; i<key_size; i++) {
169 ipad[i] = hashed_key[i] ^ 0x36;
170 opad[i] = hashed_key[i] ^ 0x5C;
171 }
172 /* Fill ipad and opad to match block size */
173 for (i=key_size; i<block_size; i++) {
174 ipad[i] = 0x36;
175 opad[i] = 0x5C;
176 }
177
178 /* Start hash1 = H(i_key_pad || message) */
179 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
180 PSA_ALG_HMAC_HASH(alg));
181 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
182 /* Clear key information on stack */
183 for (i=0; i<key_size; i++) {
184 hashed_key[i] = 0;
185 ipad[i] = 0;
186 }
187 return err;
188 }
189
190 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
191 ipad,
192 block_size);
193 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100194 return err;
195 }
196
197 return TFM_CRYPTO_ERR_PSA_SUCCESS;
198}
199
200static enum tfm_crypto_err_t tfm_crypto_mac_setup(psa_mac_operation_t *operation,
201 psa_key_slot_t key,
202 psa_algorithm_t alg,
203 uint8_t sign_operation)
204{
205 enum tfm_crypto_err_t err;
206
207 struct tfm_mac_operation_s *ctx = NULL;
208
209 if (!PSA_ALG_IS_MAC(alg)) {
210 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
211 }
212
213 /* Validate pointers */
214 err = tfm_crypto_memory_check(operation,
215 sizeof(psa_mac_operation_t),
216 TFM_MEMORY_ACCESS_RW);
217 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
218 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
219 }
220
221 /* Allocate the operation context in the secure world */
222 err = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000223 operation,
224 (void **)&ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100225 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
226 return err;
227 }
228
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100229 /* Bind the algorithm to the mac operation */
230 ctx->alg = alg;
231
232 /* Specify if this will be used for a sign or verify operation */
233 if (sign_operation) {
234 ctx->key_usage_verify = 0;
235 ctx->key_usage_sign = 1;
236 } else {
237 ctx->key_usage_verify = 1;
238 ctx->key_usage_sign = 0;
239 }
240
241 if (PSA_ALG_IS_HMAC(alg)) {
242 err = tfm_crypto_hmac_setup(ctx, key, alg);
243 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
244 /* Release the operation context */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000245 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100246 return err;
247 }
248
249 ctx->key_set = 1;
250 } else {
251 /* Other MAC types constructions are not supported */
252 /* Release the operation context */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000253 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100254 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
255 }
256
257 return TFM_CRYPTO_ERR_PSA_SUCCESS;
258}
259
260static enum tfm_crypto_err_t tfm_crypto_mac_finish(
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000261 psa_mac_operation_t *operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100262 struct tfm_mac_operation_s *ctx,
263 uint8_t *mac,
264 size_t mac_size,
265 size_t *mac_length)
266{
267 enum tfm_crypto_err_t err;
268 uint8_t hash1[PSA_HASH_MAX_SIZE];
269 size_t hash_size;
270 uint8_t *opad;
271 size_t block_size;
272
273 /* Sanity checks */
274 if (mac_size < ctx->mac_size) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000275 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100276 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
277 }
278
279 if (!(ctx->has_input)) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000280 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100281 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
282 }
283
284 if (PSA_ALG_IS_HMAC(ctx->alg)) {
285 opad = ctx->ctx.hmac.opad;
286 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(ctx->alg));
287
288 /* finish the hash1 = H(ipad || message) */
289 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
290 hash1,
291 sizeof(hash1),
292 &hash_size);
293 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000294 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100295 return err;
296 }
297
298 /* compute the final mac value = H(opad || hash1) */
299 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
300 PSA_ALG_HMAC_HASH(ctx->alg));
301 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
302 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000303 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100304 return err;
305 }
306
307 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
308 opad,
309 block_size);
310 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
311 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000312 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100313 return err;
314 }
315
316 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
317 hash1,
318 hash_size);
319 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
320 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000321 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100322 return err;
323 }
324
325 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
326 mac,
327 mac_size,
328 mac_length);
329 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
330 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000331 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100332 return err;
333 }
334
335 /* Clear intermediate hash value */
336 mac_zeroize(hash1, sizeof(hash1));
337
338 } else {
339 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
340 }
341
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000342 return tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100343}
344
345/*!
346 * \defgroup public_psa Public functions, PSA
347 *
348 */
349
350/*!@{*/
351enum tfm_crypto_err_t tfm_crypto_mac_sign_setup(psa_mac_operation_t *operation,
352 psa_key_slot_t key,
353 psa_algorithm_t alg)
354{
355 return tfm_crypto_mac_setup(operation, key, alg, 1);
356}
357
358enum tfm_crypto_err_t tfm_crypto_mac_verify_setup(
359 psa_mac_operation_t *operation,
360 psa_key_slot_t key,
361 psa_algorithm_t alg)
362{
363 return tfm_crypto_mac_setup(operation, key, alg, 0);
364}
365
366enum tfm_crypto_err_t tfm_crypto_mac_update(psa_mac_operation_t *operation,
367 const uint8_t *input,
368 size_t input_length)
369{
370 enum tfm_crypto_err_t err;
371
372 struct tfm_mac_operation_s *ctx = NULL;
373
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100374 /* Validate pointers */
375 err = tfm_crypto_memory_check(operation,
376 sizeof(psa_mac_operation_t),
377 TFM_MEMORY_ACCESS_RW);
378 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
379 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
380 }
381
382 err = tfm_crypto_memory_check((void *)input,
383 input_length,
384 TFM_MEMORY_ACCESS_RO);
385 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
386 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
387 }
388
389 /* Look up the corresponding operation context */
390 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000391 operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100392 (void **)&ctx);
393 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
394 return err;
395 }
396
397 /* Sanity check */
398 if (!(ctx->key_set)) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000399 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100400 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
401 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000402 if (input_length == 0) {
403 (void)tfm_crypto_mac_release(operation, ctx);
404 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
405 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100406
407 /* Process the input chunk */
408 if (PSA_ALG_IS_HMAC(ctx->alg)) {
409 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
410 input,
411 input_length);
412 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000413 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100414 return err;
415 }
416
417 /* Set this flag to avoid HMAC without data */
418 ctx->has_input = 1;
419 } else {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000420 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100421 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
422 }
423
424 return TFM_CRYPTO_ERR_PSA_SUCCESS;
425}
426
427enum tfm_crypto_err_t tfm_crypto_mac_sign_finish(psa_mac_operation_t *operation,
428 uint8_t *mac,
429 size_t mac_size,
430 size_t *mac_length)
431{
432 enum tfm_crypto_err_t err;
433 struct tfm_mac_operation_s *ctx = NULL;
434
435 if (mac_size == 0) {
436 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
437 }
438
439 /* Validate pointers */
440 err = tfm_crypto_memory_check(operation,
441 sizeof(psa_mac_operation_t),
442 TFM_MEMORY_ACCESS_RW);
443 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
444 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
445 }
446
447 err = tfm_crypto_memory_check((void *)mac,
448 mac_size,
449 TFM_MEMORY_ACCESS_RW);
450 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
451 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
452 }
453
454 err = tfm_crypto_memory_check(mac_length,
455 sizeof(size_t),
456 TFM_MEMORY_ACCESS_RW);
457 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
458 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
459 }
460
461 /* Look up the corresponding operation context */
462 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000463 operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100464 (void **)&ctx);
465 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
466 return err;
467 }
468
469 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
470 /* Finalise the mac operation */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000471 err = tfm_crypto_mac_finish(operation, ctx, mac, mac_size, mac_length);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100472 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
473 return err;
474 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000475 /* A call to tfm_crypto_mac_finish() always releases the operation */
476
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100477 } else {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000478 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100479 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
480 }
481
482 return TFM_CRYPTO_ERR_PSA_SUCCESS;
483}
484
485enum tfm_crypto_err_t tfm_crypto_mac_verify_finish(
486 psa_mac_operation_t *operation,
487 const uint8_t *mac,
488 size_t mac_length)
489{
490 enum tfm_crypto_err_t err;
491 struct tfm_mac_operation_s *ctx = NULL;
492 uint8_t computed_mac[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
493 size_t computed_mac_length;
494 size_t i;
495 uint32_t comp_mismatch = 0;
496
497 if (mac_length == 0) {
498 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
499 }
500
501 /* Validate pointers */
502 err = tfm_crypto_memory_check(operation,
503 sizeof(psa_mac_operation_t),
504 TFM_MEMORY_ACCESS_RW);
505 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
506 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
507 }
508
509 err = tfm_crypto_memory_check((void *)mac,
510 mac_length,
511 TFM_MEMORY_ACCESS_RO);
512 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
513 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
514 }
515
516 /* Look up the corresponding operation context */
517 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000518 operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100519 (void **)&ctx);
520 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
521 return err;
522 }
523
524 if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
525 /* Finalise the mac operation */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000526 err = tfm_crypto_mac_finish(operation,
527 ctx,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100528 computed_mac,
529 sizeof(computed_mac),
530 &computed_mac_length);
531 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
532 return err;
533 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000534 /* A call to tfm_crypto_mac_finish() always releases the operation */
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100535
536 /* Check that the computed mac match the expected one */
537 if (computed_mac_length != mac_length) {
538 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
539 }
540
541 for (i=0; i<computed_mac_length ; i++) {
542 if (computed_mac[i] != mac[i]) {
543 comp_mismatch = 1;
544 }
545 }
546
547 if (comp_mismatch == 1) {
548 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
549 }
550 } else {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000551 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100552 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
553 }
554
555 return TFM_CRYPTO_ERR_PSA_SUCCESS;
556}
557
558enum tfm_crypto_err_t tfm_crypto_mac_abort(psa_mac_operation_t *operation)
559{
560 enum tfm_crypto_err_t err;
561 struct tfm_mac_operation_s *ctx = NULL;
562
563 /* Validate pointers */
564 err = tfm_crypto_memory_check(operation,
565 sizeof(psa_mac_operation_t),
566 TFM_MEMORY_ACCESS_RW);
567 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
568 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
569 }
570
571 /* Look up the corresponding operation context */
572 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000573 operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100574 (void **)&ctx);
575 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
576 return err;
577 }
578
579 if (PSA_ALG_IS_HMAC(ctx->alg)){
580 /* Check if the HMAC internal context needs to be deallocated */
581 if (ctx->ctx.hmac.hash_operation.handle != TFM_CRYPTO_INVALID_HANDLE) {
582 /* Clear hash context */
583 err = tfm_crypto_hash_abort(&(ctx->ctx.hmac.hash_operation));
584 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
585 return err;
586 }
587 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100588 } else {
589 /* MACs other than HMACs not currently supported */
590 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
591 }
592
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000593 return tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100594}
595/*!@}*/