blob: 7000b1852d7153bcfa6c52156102f3e5c805fa5f [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"
Antonio de Angelisab85ccd2019-03-25 15:14:29 +00009#include "tfm_crypto_api.h"
10#include "crypto_engine.h"
Louis Mayencourt7a36f782018-09-24 14:00:57 +010011#include "tfm_crypto_struct.h"
12
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000013static psa_status_t _psa_get_key_information(psa_key_slot_t key,
14 psa_key_type_t *type,
15 size_t *bits)
16{
17 psa_invec in_vec[] = {
18 {.base = &key, .len = sizeof(psa_key_slot_t)},
19 };
20 psa_outvec out_vec[] = {
21 {.base = type, .len = sizeof(psa_key_type_t)},
22 {.base = bits, .len = sizeof(size_t)}
23 };
24
25 return tfm_crypto_get_key_information(
26 in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
27 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
28}
29
30static psa_status_t _psa_hash_setup(psa_hash_operation_t *operation,
31 psa_algorithm_t alg)
32{
33 psa_invec in_vec[] = {
34 {.base = &alg, .len = sizeof(psa_algorithm_t)},
35 };
36 psa_outvec out_vec[] = {
37 {.base = operation, .len = sizeof(psa_hash_operation_t)},
38 };
39
40 return tfm_crypto_hash_setup(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
41 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
42}
43
44static psa_status_t _psa_hash_update(psa_hash_operation_t *operation,
45 const uint8_t *input,
46 size_t input_length)
47{
48 psa_invec in_vec[] = {
49 {.base = input, .len = input_length},
50 };
51 psa_outvec out_vec[] = {
52 {.base = operation, .len = sizeof(psa_hash_operation_t)},
53 };
54
55 return tfm_crypto_hash_update(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
56 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
57}
58
59static psa_status_t _psa_hash_finish(psa_hash_operation_t *operation,
60 uint8_t *hash,
61 size_t hash_size,
62 size_t *hash_length)
63{
64 psa_status_t status;
65 psa_outvec out_vec[] = {
66 {.base = operation, .len = sizeof(psa_hash_operation_t)},
67 {.base = hash, .len = hash_size},
68 };
69
70 status = tfm_crypto_hash_finish(NULL, 0,
71 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
72 *hash_length = out_vec[1].len;
73
74 return status;
75}
76
77static psa_status_t _psa_hash_abort(psa_hash_operation_t *operation)
78{
79 psa_outvec out_vec[] = {
80 {.base = operation, .len = sizeof(psa_hash_operation_t)},
81 };
82
83 return tfm_crypto_hash_abort(NULL, 0,
84 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
85}
Louis Mayencourt7a36f782018-09-24 14:00:57 +010086
Jamie Fox82b87ca2018-12-11 16:41:11 +000087/**
Antonio de Angelis819c2f32019-02-06 14:32:02 +000088 * \def UNUSED_VAR
89 *
90 * \brief an UNUSED_VAR() macro for better code readability
91 */
92#define UNUSED_VAR(x) (void)x
93
94/**
Jamie Fox82b87ca2018-12-11 16:41:11 +000095 * \def CRYPTO_HMAC_MAX_KEY_LENGTH
96 *
97 * \brief Specifies the maximum key length supported by the
98 * HMAC operations in this implementation
99 */
100#ifndef CRYPTO_HMAC_MAX_KEY_LENGTH
101#define CRYPTO_HMAC_MAX_KEY_LENGTH (32)
102#endif
103
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100104static void mac_zeroize(void *data, size_t size)
105{
Hugues de Valon8b442442019-02-19 14:30:52 +0000106 (void)tfm_memset(data, 0, size);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100107}
108
109static size_t get_hash_block_size(psa_algorithm_t alg)
110{
111 switch (alg) {
112 case PSA_ALG_MD2:
113 return 16;
114 case PSA_ALG_MD4:
115 return 64;
116 case PSA_ALG_MD5:
117 return 64;
118 case PSA_ALG_RIPEMD160:
119 return 64;
120 case PSA_ALG_SHA_1:
121 return 64;
122 case PSA_ALG_SHA_224:
123 return 64;
124 case PSA_ALG_SHA_256:
125 return 64;
126 case PSA_ALG_SHA_384:
127 return 128;
128 case PSA_ALG_SHA_512:
129 return 128;
130 default:
131 return 0;
132 }
133}
134
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000135static psa_status_t tfm_crypto_mac_release(psa_mac_operation_t *operation,
136 struct tfm_mac_operation_s *ctx)
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000137{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000138 /* No release necessary on the ctx related items for the time being */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000139 UNUSED_VAR(ctx);
140
141 /* Release the operation context */
Hugues de Valon8b442442019-02-19 14:30:52 +0000142 return tfm_crypto_operation_release(TFM_CRYPTO_MAC_OPERATION, operation);
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000143}
144
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000145static psa_status_t tfm_crypto_hmac_setup(struct tfm_mac_operation_s *ctx,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100146 psa_key_slot_t key,
147 psa_algorithm_t alg)
148{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000149 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100150 psa_key_type_t key_type;
151 size_t key_size;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000152 uint8_t key_data[CRYPTO_HMAC_MAX_KEY_LENGTH];
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100153 uint8_t hashed_key[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
154 size_t block_size;
155 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
156 uint8_t *opad = ctx->ctx.hmac.opad;
157 size_t i;
Jamie Foxefd82732018-11-26 10:34:32 +0000158 psa_key_usage_t usage;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100159
160 /* Check provided key */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000161 status = _psa_get_key_information(key, &key_type, &key_size);
162 if (status != PSA_SUCCESS) {
163 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100164 }
165
166 if (key_type != PSA_KEY_TYPE_HMAC){
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000167 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100168 }
169
Jamie Foxefd82732018-11-26 10:34:32 +0000170 /* Set the key usage based on whether this is a sign or verify operation */
171 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
172 usage = PSA_KEY_USAGE_SIGN;
173 } else if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
174 usage = PSA_KEY_USAGE_VERIFY;
175 } else {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000176 return PSA_ERROR_BAD_STATE;
Jamie Foxefd82732018-11-26 10:34:32 +0000177 }
178
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100179 /* Get the key data to start the HMAC */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000180 status = tfm_crypto_get_key(key,
181 usage,
182 alg,
183 key_data,
184 CRYPTO_HMAC_MAX_KEY_LENGTH,
185 &key_size);
186 if (status != PSA_SUCCESS) {
187 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100188 }
189
190 /* Bind the digest size to the MAC operation */
191 ctx->mac_size = PSA_HASH_SIZE(PSA_ALG_HMAC_HASH(alg));
192
193 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(alg));
194
195 /* The HMAC algorithm is the standard procedure as described in
196 * RFC-2104 (https://tools.ietf.org/html/rfc2104)
197 */
198 if (key_size > block_size) {
199 /* Hash the key to reduce it to block size */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000200 status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation),
201 PSA_ALG_HMAC_HASH(alg));
202 if (status != PSA_SUCCESS) {
203 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100204 }
205
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000206 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
207 &key_data[0],
208 key_size);
209 if (status != PSA_SUCCESS) {
210 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100211 }
212
213 /* Replace the key with the hashed key */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000214 status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation),
215 hashed_key,
216 sizeof(hashed_key),
217 &key_size);
218 if (status != PSA_SUCCESS) {
219 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100220 }
221 } else {
222 /* Copy the key inside the hashed_key buffer */
223 for (i=0; i<key_size; i++) {
224 hashed_key[i] = key_data[i];
225 }
226 }
227
228 /* Create ipad = hashed_key XOR 0x36 and opad = hashed_key XOR 0x5C */
229 for (i=0; i<key_size; i++) {
230 ipad[i] = hashed_key[i] ^ 0x36;
231 opad[i] = hashed_key[i] ^ 0x5C;
232 }
233 /* Fill ipad and opad to match block size */
234 for (i=key_size; i<block_size; i++) {
235 ipad[i] = 0x36;
236 opad[i] = 0x5C;
237 }
238
239 /* Start hash1 = H(i_key_pad || message) */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000240 status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation),
241 PSA_ALG_HMAC_HASH(alg));
242 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100243 /* Clear key information on stack */
244 for (i=0; i<key_size; i++) {
245 hashed_key[i] = 0;
246 ipad[i] = 0;
247 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000248 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100249 }
250
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000251 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
252 ipad,
253 block_size);
254 if (status != PSA_SUCCESS) {
255 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100256 }
257
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000258 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100259}
260
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000261static psa_status_t tfm_crypto_mac_setup(psa_mac_operation_t *operation,
262 psa_key_slot_t key,
263 psa_algorithm_t alg,
264 uint8_t sign_operation)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100265{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000266 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100267 struct tfm_mac_operation_s *ctx = NULL;
268
269 if (!PSA_ALG_IS_MAC(alg)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000270 return PSA_ERROR_NOT_SUPPORTED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100271 }
272
273 /* Allocate the operation context in the secure world */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000274 status = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
275 operation,
276 (void **)&ctx);
277 if (status != PSA_SUCCESS) {
278 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100279 }
280
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100281 /* Bind the algorithm to the mac operation */
282 ctx->alg = alg;
283
284 /* Specify if this will be used for a sign or verify operation */
285 if (sign_operation) {
286 ctx->key_usage_verify = 0;
287 ctx->key_usage_sign = 1;
288 } else {
289 ctx->key_usage_verify = 1;
290 ctx->key_usage_sign = 0;
291 }
292
293 if (PSA_ALG_IS_HMAC(alg)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000294 status = tfm_crypto_hmac_setup(ctx, key, alg);
295 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100296 /* Release the operation context */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000297 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000298 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100299 }
300
301 ctx->key_set = 1;
302 } else {
303 /* Other MAC types constructions are not supported */
304 /* Release the operation context */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000305 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000306 return PSA_ERROR_NOT_SUPPORTED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100307 }
308
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000309 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100310}
311
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000312static psa_status_t tfm_crypto_mac_finish(psa_mac_operation_t *operation,
313 struct tfm_mac_operation_s *ctx,
314 uint8_t *mac,
315 size_t mac_size,
316 size_t *mac_length)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100317{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000318 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100319 uint8_t hash1[PSA_HASH_MAX_SIZE];
320 size_t hash_size;
321 uint8_t *opad;
322 size_t block_size;
323
324 /* Sanity checks */
325 if (mac_size < ctx->mac_size) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000326 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000327 return PSA_ERROR_BUFFER_TOO_SMALL;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100328 }
329
330 if (!(ctx->has_input)) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000331 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000332 return PSA_ERROR_BAD_STATE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100333 }
334
335 if (PSA_ALG_IS_HMAC(ctx->alg)) {
336 opad = ctx->ctx.hmac.opad;
337 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(ctx->alg));
338
339 /* finish the hash1 = H(ipad || message) */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000340 status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation),
341 hash1,
342 sizeof(hash1),
343 &hash_size);
344 if (status != PSA_SUCCESS) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000345 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000346 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100347 }
348
349 /* compute the final mac value = H(opad || hash1) */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000350 status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation),
351 PSA_ALG_HMAC_HASH(ctx->alg));
352 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100353 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000354 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000355 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100356 }
357
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000358 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
359 opad,
360 block_size);
361 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100362 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000363 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000364 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100365 }
366
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000367 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
368 hash1,
369 hash_size);
370 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100371 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000372 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000373 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100374 }
375
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000376 status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation),
377 mac,
378 mac_size,
379 mac_length);
380 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100381 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000382 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000383 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100384 }
385
386 /* Clear intermediate hash value */
387 mac_zeroize(hash1, sizeof(hash1));
388
389 } else {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000390 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100391 }
392
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000393 return tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100394}
395
396/*!
397 * \defgroup public_psa Public functions, PSA
398 *
399 */
400
401/*!@{*/
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000402psa_status_t tfm_crypto_mac_sign_setup(psa_invec in_vec[],
403 size_t in_len,
404 psa_outvec out_vec[],
405 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100406{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000407 if ((in_len != 2) || (out_len != 1)) {
408 return PSA_CONNECTION_REFUSED;
409 }
410
411 if ((out_vec[0].len != sizeof(psa_mac_operation_t)) ||
412 (in_vec[0].len != sizeof(psa_key_slot_t)) ||
413 (in_vec[1].len != sizeof(psa_algorithm_t))) {
414 return PSA_CONNECTION_REFUSED;
415 }
416
417 psa_mac_operation_t *operation = out_vec[0].base;
418 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
419 psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[1].base);
420
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100421 return tfm_crypto_mac_setup(operation, key, alg, 1);
422}
423
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000424psa_status_t tfm_crypto_mac_verify_setup(psa_invec in_vec[],
425 size_t in_len,
426 psa_outvec out_vec[],
427 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100428{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000429 if ((in_len != 2) || (out_len != 1)) {
430 return PSA_CONNECTION_REFUSED;
431 }
432
433 if ((out_vec[0].len != sizeof(psa_mac_operation_t)) ||
434 (in_vec[0].len != sizeof(psa_key_slot_t)) ||
435 (in_vec[1].len != sizeof(psa_algorithm_t))) {
436 return PSA_CONNECTION_REFUSED;
437 }
438
439 psa_mac_operation_t *operation = out_vec[0].base;
440 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
441 psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[1].base);
442
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100443 return tfm_crypto_mac_setup(operation, key, alg, 0);
444}
445
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000446psa_status_t tfm_crypto_mac_update(psa_invec in_vec[],
447 size_t in_len,
448 psa_outvec out_vec[],
449 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100450{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000451 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100452 struct tfm_mac_operation_s *ctx = NULL;
453
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000454 if ((in_len != 1) || (out_len != 1)) {
455 return PSA_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100456 }
457
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000458 if ((out_vec[0].len != sizeof(psa_mac_operation_t))) {
459 return PSA_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100460 }
461
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000462 psa_mac_operation_t *operation = out_vec[0].base;
463 const uint8_t *input = in_vec[0].base;
464 size_t input_length = in_vec[0].len;
465
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100466 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000467 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
468 operation,
469 (void **)&ctx);
470 if (status != PSA_SUCCESS) {
471 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100472 }
473
474 /* Sanity check */
475 if (!(ctx->key_set)) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000476 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000477 return PSA_ERROR_BAD_STATE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100478 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000479 if (input_length == 0) {
480 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000481 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000482 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100483
484 /* Process the input chunk */
485 if (PSA_ALG_IS_HMAC(ctx->alg)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000486 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation),
487 input,
488 input_length);
489 if (status != PSA_SUCCESS) {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000490 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000491 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100492 }
493
494 /* Set this flag to avoid HMAC without data */
495 ctx->has_input = 1;
496 } else {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000497 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000498 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100499 }
500
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000501 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100502}
503
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000504psa_status_t tfm_crypto_mac_sign_finish(psa_invec in_vec[],
505 size_t in_len,
506 psa_outvec out_vec[],
507 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100508{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000509 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100510 struct tfm_mac_operation_s *ctx = NULL;
511
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000512 if ((in_len != 0) || (out_len != 2)) {
513 return PSA_CONNECTION_REFUSED;
514 }
515
516 if ((out_vec[0].len != sizeof(psa_mac_operation_t))) {
517 return PSA_CONNECTION_REFUSED;
518 }
519
520 psa_mac_operation_t *operation = out_vec[0].base;
521 uint8_t *mac = out_vec[1].base;
522 size_t mac_size = out_vec[1].len;
523
524 /* Initialise mac_length to zero */
525 out_vec[1].len = 0;
526
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100527 if (mac_size == 0) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000528 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100529 }
530
531 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000532 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
533 operation,
534 (void **)&ctx);
535 if (status != PSA_SUCCESS) {
536 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100537 }
538
539 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
540 /* Finalise the mac operation */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000541 status = tfm_crypto_mac_finish(operation,
542 ctx, mac, mac_size, &(out_vec[1].len));
543 if (status != PSA_SUCCESS) {
544 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100545 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000546 /* A call to tfm_crypto_mac_finish() always releases the operation */
547
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100548 } else {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000549 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000550 return PSA_ERROR_BAD_STATE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100551 }
552
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000553 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100554}
555
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000556psa_status_t tfm_crypto_mac_verify_finish(psa_invec in_vec[],
557 size_t in_len,
558 psa_outvec out_vec[],
559 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100560{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000561 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100562 struct tfm_mac_operation_s *ctx = NULL;
563 uint8_t computed_mac[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
564 size_t computed_mac_length;
565 size_t i;
566 uint32_t comp_mismatch = 0;
567
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000568 if ((in_len != 1) || (out_len != 1)) {
569 return PSA_CONNECTION_REFUSED;
570 }
571
572 if ((out_vec[0].len != sizeof(psa_mac_operation_t))) {
573 return PSA_CONNECTION_REFUSED;
574 }
575
576 psa_mac_operation_t *operation = out_vec[0].base;
577 const uint8_t *mac = in_vec[0].base;
578 size_t mac_length = in_vec[0].len;
579
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100580 if (mac_length == 0) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000581 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100582 }
583
584 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000585 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
586 operation,
587 (void **)&ctx);
588 if (status != PSA_SUCCESS) {
589 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100590 }
591
592 if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
593 /* Finalise the mac operation */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000594 status = tfm_crypto_mac_finish(operation,
595 ctx,
596 computed_mac,
597 sizeof(computed_mac),
598 &computed_mac_length);
599 if (status != PSA_SUCCESS) {
600 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100601 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000602 /* A call to tfm_crypto_mac_finish() always releases the operation */
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100603
604 /* Check that the computed mac match the expected one */
605 if (computed_mac_length != mac_length) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000606 return PSA_ERROR_INVALID_SIGNATURE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100607 }
608
609 for (i=0; i<computed_mac_length ; i++) {
610 if (computed_mac[i] != mac[i]) {
611 comp_mismatch = 1;
612 }
613 }
614
615 if (comp_mismatch == 1) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000616 return PSA_ERROR_INVALID_SIGNATURE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100617 }
618 } else {
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000619 (void)tfm_crypto_mac_release(operation, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000620 return PSA_ERROR_BAD_STATE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100621 }
622
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000623 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100624}
625
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000626psa_status_t tfm_crypto_mac_abort(psa_invec in_vec[],
627 size_t in_len,
628 psa_outvec out_vec[],
629 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100630{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000631 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100632 struct tfm_mac_operation_s *ctx = NULL;
633
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000634 if ((in_len != 0) || (out_len != 1)) {
635 return PSA_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100636 }
637
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000638 if ((out_vec[0].len != sizeof(psa_mac_operation_t))) {
639 return PSA_CONNECTION_REFUSED;
640 }
641
642 psa_mac_operation_t *operation = out_vec[0].base;
643
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100644 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000645 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
646 operation,
647 (void **)&ctx);
648 if (status != PSA_SUCCESS) {
649 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100650 }
651
652 if (PSA_ALG_IS_HMAC(ctx->alg)){
653 /* Check if the HMAC internal context needs to be deallocated */
654 if (ctx->ctx.hmac.hash_operation.handle != TFM_CRYPTO_INVALID_HANDLE) {
655 /* Clear hash context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000656 status = _psa_hash_abort(&(ctx->ctx.hmac.hash_operation));
657 if (status != PSA_SUCCESS) {
658 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100659 }
660 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100661 } else {
662 /* MACs other than HMACs not currently supported */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000663 return PSA_ERROR_NOT_SUPPORTED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100664 }
665
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000666 return tfm_crypto_mac_release(operation, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100667}
668/*!@}*/