blob: 2aeb99e4ca1165a29172a4a3796ca95d9f04021b [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
Hugues de Valon8b442442019-02-19 14:30:52 +00008#include "crypto_utils.h"
Tamas Ban8bd24b72019-02-19 12:13:13 +00009#include "secure_fw/core/tfm_memory_utils.h"
Louis Mayencourt7a36f782018-09-24 14:00:57 +010010#include "tfm_crypto_defs.h"
11
12#include "psa_crypto.h"
13
14#include "tfm_crypto_struct.h"
15
16#include "tfm_crypto_api.h"
Louis Mayencourt7a36f782018-09-24 14:00:57 +010017
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{
Hugues de Valon8b442442019-02-19 14:30:52 +000037 (void)tfm_memset(data, 0, size);
Louis Mayencourt7a36f782018-09-24 14:00:57 +010038}
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{
Antonio de Angelis819c2f32019-02-06 14:32:02 +000070 /* No release necessary on the ctx related quantites for the time being */
71 UNUSED_VAR(ctx);
72
73 /* Release the operation context */
Hugues de Valon8b442442019-02-19 14:30:52 +000074 return tfm_crypto_operation_release(TFM_CRYPTO_MAC_OPERATION, operation);
Antonio de Angelis819c2f32019-02-06 14:32:02 +000075}
76
Louis Mayencourt7a36f782018-09-24 14:00:57 +010077static enum tfm_crypto_err_t tfm_crypto_hmac_setup(
78 struct tfm_mac_operation_s *ctx,
79 psa_key_slot_t key,
80 psa_algorithm_t alg)
81{
82 enum tfm_crypto_err_t err;
83 psa_key_type_t key_type;
84 size_t key_size;
Jamie Fox82b87ca2018-12-11 16:41:11 +000085 uint8_t key_data[CRYPTO_HMAC_MAX_KEY_LENGTH];
Louis Mayencourt7a36f782018-09-24 14:00:57 +010086 uint8_t hashed_key[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
87 size_t block_size;
88 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
89 uint8_t *opad = ctx->ctx.hmac.opad;
90 size_t i;
Jamie Foxefd82732018-11-26 10:34:32 +000091 psa_key_usage_t usage;
Louis Mayencourt7a36f782018-09-24 14:00:57 +010092
93 /* Check provided key */
94 err = tfm_crypto_get_key_information(key, &key_type, &key_size);
95 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
96 return err;
97 }
98
99 if (key_type != PSA_KEY_TYPE_HMAC){
100 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
101 }
102
Jamie Foxefd82732018-11-26 10:34:32 +0000103 /* Set the key usage based on whether this is a sign or verify operation */
104 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
105 usage = PSA_KEY_USAGE_SIGN;
106 } else if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
107 usage = PSA_KEY_USAGE_VERIFY;
108 } else {
109 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
110 }
111
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100112 /* Get the key data to start the HMAC */
Jamie Foxefd82732018-11-26 10:34:32 +0000113 err = tfm_crypto_get_key(key,
114 usage,
115 alg,
116 key_data,
Jamie Fox82b87ca2018-12-11 16:41:11 +0000117 CRYPTO_HMAC_MAX_KEY_LENGTH,
Jamie Foxefd82732018-11-26 10:34:32 +0000118 &key_size);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100119 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
120 return err;
121 }
122
123 /* Bind the digest size to the MAC operation */
124 ctx->mac_size = PSA_HASH_SIZE(PSA_ALG_HMAC_HASH(alg));
125
126 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(alg));
127
128 /* The HMAC algorithm is the standard procedure as described in
129 * RFC-2104 (https://tools.ietf.org/html/rfc2104)
130 */
131 if (key_size > block_size) {
132 /* Hash the key to reduce it to block size */
133 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
134 PSA_ALG_HMAC_HASH(alg));
135 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
136 return err;
137 }
138
139 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
140 &key_data[0],
141 key_size);
142 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100143 return err;
144 }
145
146 /* Replace the key with the hashed key */
147 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
148 hashed_key, sizeof(hashed_key),
149 &key_size);
150 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100151 return err;
152 }
153 } else {
154 /* Copy the key inside the hashed_key buffer */
155 for (i=0; i<key_size; i++) {
156 hashed_key[i] = key_data[i];
157 }
158 }
159
160 /* Create ipad = hashed_key XOR 0x36 and opad = hashed_key XOR 0x5C */
161 for (i=0; i<key_size; i++) {
162 ipad[i] = hashed_key[i] ^ 0x36;
163 opad[i] = hashed_key[i] ^ 0x5C;
164 }
165 /* Fill ipad and opad to match block size */
166 for (i=key_size; i<block_size; i++) {
167 ipad[i] = 0x36;
168 opad[i] = 0x5C;
169 }
170
171 /* Start hash1 = H(i_key_pad || message) */
172 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
173 PSA_ALG_HMAC_HASH(alg));
174 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
175 /* Clear key information on stack */
176 for (i=0; i<key_size; i++) {
177 hashed_key[i] = 0;
178 ipad[i] = 0;
179 }
180 return err;
181 }
182
183 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
184 ipad,
185 block_size);
186 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100187 return err;
188 }
189
190 return TFM_CRYPTO_ERR_PSA_SUCCESS;
191}
192
193static enum tfm_crypto_err_t tfm_crypto_mac_setup(psa_mac_operation_t *operation,
194 psa_key_slot_t key,
195 psa_algorithm_t alg,
196 uint8_t sign_operation)
197{
198 enum tfm_crypto_err_t err;
199
200 struct tfm_mac_operation_s *ctx = NULL;
201
202 if (!PSA_ALG_IS_MAC(alg)) {
203 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
204 }
205
206 /* Validate pointers */
207 err = tfm_crypto_memory_check(operation,
208 sizeof(psa_mac_operation_t),
209 TFM_MEMORY_ACCESS_RW);
210 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
211 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
212 }
213
214 /* Allocate the operation context in the secure world */
215 err = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000216 operation,
217 (void **)&ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100218 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
219 return err;
220 }
221
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100222 /* Bind the algorithm to the mac operation */
223 ctx->alg = alg;
224
225 /* Specify if this will be used for a sign or verify operation */
226 if (sign_operation) {
227 ctx->key_usage_verify = 0;
228 ctx->key_usage_sign = 1;
229 } else {
230 ctx->key_usage_verify = 1;
231 ctx->key_usage_sign = 0;
232 }
233
234 if (PSA_ALG_IS_HMAC(alg)) {
235 err = tfm_crypto_hmac_setup(ctx, key, alg);
236 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
237 /* Release the operation context */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000238 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100239 return err;
240 }
241
242 ctx->key_set = 1;
243 } else {
244 /* Other MAC types constructions are not supported */
245 /* Release the operation context */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000246 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100247 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
248 }
249
250 return TFM_CRYPTO_ERR_PSA_SUCCESS;
251}
252
253static enum tfm_crypto_err_t tfm_crypto_mac_finish(
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000254 psa_mac_operation_t *operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100255 struct tfm_mac_operation_s *ctx,
256 uint8_t *mac,
257 size_t mac_size,
258 size_t *mac_length)
259{
260 enum tfm_crypto_err_t err;
261 uint8_t hash1[PSA_HASH_MAX_SIZE];
262 size_t hash_size;
263 uint8_t *opad;
264 size_t block_size;
265
266 /* Sanity checks */
267 if (mac_size < ctx->mac_size) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000268 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100269 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
270 }
271
272 if (!(ctx->has_input)) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000273 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100274 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
275 }
276
277 if (PSA_ALG_IS_HMAC(ctx->alg)) {
278 opad = ctx->ctx.hmac.opad;
279 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(ctx->alg));
280
281 /* finish the hash1 = H(ipad || message) */
282 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
283 hash1,
284 sizeof(hash1),
285 &hash_size);
286 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000287 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100288 return err;
289 }
290
291 /* compute the final mac value = H(opad || hash1) */
292 err = tfm_crypto_hash_setup(&(ctx->ctx.hmac.hash_operation),
293 PSA_ALG_HMAC_HASH(ctx->alg));
294 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
295 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000296 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100297 return err;
298 }
299
300 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
301 opad,
302 block_size);
303 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
304 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000305 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100306 return err;
307 }
308
309 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
310 hash1,
311 hash_size);
312 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
313 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000314 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100315 return err;
316 }
317
318 err = tfm_crypto_hash_finish(&(ctx->ctx.hmac.hash_operation),
319 mac,
320 mac_size,
321 mac_length);
322 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
323 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000324 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100325 return err;
326 }
327
328 /* Clear intermediate hash value */
329 mac_zeroize(hash1, sizeof(hash1));
330
331 } else {
332 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
333 }
334
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000335 return tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100336}
337
338/*!
339 * \defgroup public_psa Public functions, PSA
340 *
341 */
342
343/*!@{*/
344enum tfm_crypto_err_t tfm_crypto_mac_sign_setup(psa_mac_operation_t *operation,
345 psa_key_slot_t key,
346 psa_algorithm_t alg)
347{
348 return tfm_crypto_mac_setup(operation, key, alg, 1);
349}
350
351enum tfm_crypto_err_t tfm_crypto_mac_verify_setup(
352 psa_mac_operation_t *operation,
353 psa_key_slot_t key,
354 psa_algorithm_t alg)
355{
356 return tfm_crypto_mac_setup(operation, key, alg, 0);
357}
358
359enum tfm_crypto_err_t tfm_crypto_mac_update(psa_mac_operation_t *operation,
360 const uint8_t *input,
361 size_t input_length)
362{
363 enum tfm_crypto_err_t err;
364
365 struct tfm_mac_operation_s *ctx = NULL;
366
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100367 /* Validate pointers */
368 err = tfm_crypto_memory_check(operation,
369 sizeof(psa_mac_operation_t),
370 TFM_MEMORY_ACCESS_RW);
371 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
372 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
373 }
374
375 err = tfm_crypto_memory_check((void *)input,
376 input_length,
377 TFM_MEMORY_ACCESS_RO);
378 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
379 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
380 }
381
382 /* Look up the corresponding operation context */
383 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000384 operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100385 (void **)&ctx);
386 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
387 return err;
388 }
389
390 /* Sanity check */
391 if (!(ctx->key_set)) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000392 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100393 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
394 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000395 if (input_length == 0) {
396 (void)tfm_crypto_mac_release(operation, ctx);
397 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
398 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100399
400 /* Process the input chunk */
401 if (PSA_ALG_IS_HMAC(ctx->alg)) {
402 err = tfm_crypto_hash_update(&(ctx->ctx.hmac.hash_operation),
403 input,
404 input_length);
405 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000406 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100407 return err;
408 }
409
410 /* Set this flag to avoid HMAC without data */
411 ctx->has_input = 1;
412 } else {
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 TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
415 }
416
417 return TFM_CRYPTO_ERR_PSA_SUCCESS;
418}
419
420enum tfm_crypto_err_t tfm_crypto_mac_sign_finish(psa_mac_operation_t *operation,
421 uint8_t *mac,
422 size_t mac_size,
423 size_t *mac_length)
424{
425 enum tfm_crypto_err_t err;
426 struct tfm_mac_operation_s *ctx = NULL;
427
428 if (mac_size == 0) {
429 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
430 }
431
432 /* Validate pointers */
433 err = tfm_crypto_memory_check(operation,
434 sizeof(psa_mac_operation_t),
435 TFM_MEMORY_ACCESS_RW);
436 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
437 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
438 }
439
440 err = tfm_crypto_memory_check((void *)mac,
441 mac_size,
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(mac_length,
448 sizeof(size_t),
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 /* Look up the corresponding operation context */
455 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000456 operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100457 (void **)&ctx);
458 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
459 return err;
460 }
461
462 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
463 /* Finalise the mac operation */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000464 err = tfm_crypto_mac_finish(operation, ctx, mac, mac_size, mac_length);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100465 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
466 return err;
467 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000468 /* A call to tfm_crypto_mac_finish() always releases the operation */
469
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100470 } else {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000471 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100472 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
473 }
474
475 return TFM_CRYPTO_ERR_PSA_SUCCESS;
476}
477
478enum tfm_crypto_err_t tfm_crypto_mac_verify_finish(
479 psa_mac_operation_t *operation,
480 const uint8_t *mac,
481 size_t mac_length)
482{
483 enum tfm_crypto_err_t err;
484 struct tfm_mac_operation_s *ctx = NULL;
485 uint8_t computed_mac[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
486 size_t computed_mac_length;
487 size_t i;
488 uint32_t comp_mismatch = 0;
489
490 if (mac_length == 0) {
491 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
492 }
493
494 /* Validate pointers */
495 err = tfm_crypto_memory_check(operation,
496 sizeof(psa_mac_operation_t),
497 TFM_MEMORY_ACCESS_RW);
498 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
499 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
500 }
501
502 err = tfm_crypto_memory_check((void *)mac,
503 mac_length,
504 TFM_MEMORY_ACCESS_RO);
505 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
506 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
507 }
508
509 /* Look up the corresponding operation context */
510 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000511 operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100512 (void **)&ctx);
513 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
514 return err;
515 }
516
517 if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
518 /* Finalise the mac operation */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000519 err = tfm_crypto_mac_finish(operation,
520 ctx,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100521 computed_mac,
522 sizeof(computed_mac),
523 &computed_mac_length);
524 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
525 return err;
526 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000527 /* A call to tfm_crypto_mac_finish() always releases the operation */
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100528
529 /* Check that the computed mac match the expected one */
530 if (computed_mac_length != mac_length) {
531 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
532 }
533
534 for (i=0; i<computed_mac_length ; i++) {
535 if (computed_mac[i] != mac[i]) {
536 comp_mismatch = 1;
537 }
538 }
539
540 if (comp_mismatch == 1) {
541 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
542 }
543 } else {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000544 (void)tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100545 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
546 }
547
548 return TFM_CRYPTO_ERR_PSA_SUCCESS;
549}
550
551enum tfm_crypto_err_t tfm_crypto_mac_abort(psa_mac_operation_t *operation)
552{
553 enum tfm_crypto_err_t err;
554 struct tfm_mac_operation_s *ctx = NULL;
555
556 /* Validate pointers */
557 err = tfm_crypto_memory_check(operation,
558 sizeof(psa_mac_operation_t),
559 TFM_MEMORY_ACCESS_RW);
560 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
561 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
562 }
563
564 /* Look up the corresponding operation context */
565 err = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000566 operation,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100567 (void **)&ctx);
568 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
569 return err;
570 }
571
572 if (PSA_ALG_IS_HMAC(ctx->alg)){
573 /* Check if the HMAC internal context needs to be deallocated */
574 if (ctx->ctx.hmac.hash_operation.handle != TFM_CRYPTO_INVALID_HANDLE) {
575 /* Clear hash context */
576 err = tfm_crypto_hash_abort(&(ctx->ctx.hmac.hash_operation));
577 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
578 return err;
579 }
580 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100581 } else {
582 /* MACs other than HMACs not currently supported */
583 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
584 }
585
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000586 return tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100587}
588/*!@}*/