blob: ae6a00be9444a21f538847952d3194f165f73b26 [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 Angelis4743e672019-04-11 11:38:48 +010013/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
14 * integrity checks but this will have to be revised
15 * when the full set of error codes mandated by PSA FF
16 * is available.
17 */
18
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000019static psa_status_t _psa_get_key_information(psa_key_slot_t key,
20 psa_key_type_t *type,
21 size_t *bits)
22{
Antonio de Angelis4743e672019-04-11 11:38:48 +010023 psa_status_t status;
24 struct tfm_crypto_pack_iovec iov = {
25 .sfn_id = TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
26 .key = key,
27 };
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000028 psa_invec in_vec[] = {
Antonio de Angelis4743e672019-04-11 11:38:48 +010029 {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000030 };
31 psa_outvec out_vec[] = {
32 {.base = type, .len = sizeof(psa_key_type_t)},
33 {.base = bits, .len = sizeof(size_t)}
34 };
35
Antonio de Angelis4743e672019-04-11 11:38:48 +010036 status = tfm_crypto_get_key_information(
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000037 in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
38 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
Antonio de Angelis4743e672019-04-11 11:38:48 +010039
40 return status;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000041}
42
Antonio de Angelis4743e672019-04-11 11:38:48 +010043static psa_status_t _psa_hash_setup(uint32_t *handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000044 psa_algorithm_t alg)
45{
Antonio de Angelis4743e672019-04-11 11:38:48 +010046 psa_status_t status;
47 struct tfm_crypto_pack_iovec iov = {
48 .sfn_id = TFM_CRYPTO_HASH_SETUP_SFID,
49 .alg = alg,
50 .handle = *handle,
51 };
52
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000053 psa_invec in_vec[] = {
Antonio de Angelis4743e672019-04-11 11:38:48 +010054 {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000055 };
56 psa_outvec out_vec[] = {
Antonio de Angelis4743e672019-04-11 11:38:48 +010057 {.base = handle, .len = sizeof(uint32_t)},
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000058 };
59
Antonio de Angelis4743e672019-04-11 11:38:48 +010060 status = tfm_crypto_hash_setup(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000061 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
Antonio de Angelis4743e672019-04-11 11:38:48 +010062
63 return status;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000064}
65
Antonio de Angelis4743e672019-04-11 11:38:48 +010066static psa_status_t _psa_hash_update(uint32_t *handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000067 const uint8_t *input,
68 size_t input_length)
69{
Antonio de Angelis4743e672019-04-11 11:38:48 +010070 psa_status_t status;
71 struct tfm_crypto_pack_iovec iov = {
72 .sfn_id = TFM_CRYPTO_HASH_UPDATE_SFID,
73 .handle = *handle,
74 };
75
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000076 psa_invec in_vec[] = {
Antonio de Angelis4743e672019-04-11 11:38:48 +010077 {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000078 {.base = input, .len = input_length},
79 };
80 psa_outvec out_vec[] = {
Antonio de Angelis4743e672019-04-11 11:38:48 +010081 {.base = handle, .len = sizeof(uint32_t)},
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000082 };
83
Antonio de Angelis4743e672019-04-11 11:38:48 +010084 status = tfm_crypto_hash_update(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000085 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
Antonio de Angelis4743e672019-04-11 11:38:48 +010086
87 return status;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000088}
89
Antonio de Angelis4743e672019-04-11 11:38:48 +010090static psa_status_t _psa_hash_finish(uint32_t *handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000091 uint8_t *hash,
92 size_t hash_size,
93 size_t *hash_length)
94{
95 psa_status_t status;
Antonio de Angelis4743e672019-04-11 11:38:48 +010096 struct tfm_crypto_pack_iovec iov = {
97 .sfn_id = TFM_CRYPTO_HASH_FINISH_SFID,
98 .handle = *handle,
99 };
100
101 psa_invec in_vec[] = {
102 {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
103 };
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000104 psa_outvec out_vec[] = {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100105 {.base = handle, .len = sizeof(uint32_t)},
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000106 {.base = hash, .len = hash_size},
107 };
108
Antonio de Angelis4743e672019-04-11 11:38:48 +0100109 status = tfm_crypto_hash_finish(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000110 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
111 *hash_length = out_vec[1].len;
112
113 return status;
114}
115
Antonio de Angelis4743e672019-04-11 11:38:48 +0100116static psa_status_t _psa_hash_abort(uint32_t *handle)
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000117{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100118 psa_status_t status;
119 struct tfm_crypto_pack_iovec iov = {
120 .sfn_id = TFM_CRYPTO_HASH_ABORT_SFID,
121 .handle = *handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000122 };
123
Antonio de Angelis4743e672019-04-11 11:38:48 +0100124 psa_invec in_vec[] = {
125 {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
126 };
127 psa_outvec out_vec[] = {
128 {.base = handle, .len = sizeof(uint32_t)},
129 };
130
131 status = tfm_crypto_hash_abort(in_vec, sizeof(in_vec)/sizeof(in_vec[0]),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000132 out_vec, sizeof(out_vec)/sizeof(out_vec[0]));
Antonio de Angelis4743e672019-04-11 11:38:48 +0100133
134 return status;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000135}
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100136
Jamie Fox82b87ca2018-12-11 16:41:11 +0000137/**
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000138 * \def UNUSED_VAR
139 *
140 * \brief an UNUSED_VAR() macro for better code readability
141 */
142#define UNUSED_VAR(x) (void)x
143
144/**
Jamie Fox82b87ca2018-12-11 16:41:11 +0000145 * \def CRYPTO_HMAC_MAX_KEY_LENGTH
146 *
147 * \brief Specifies the maximum key length supported by the
148 * HMAC operations in this implementation
149 */
150#ifndef CRYPTO_HMAC_MAX_KEY_LENGTH
151#define CRYPTO_HMAC_MAX_KEY_LENGTH (32)
152#endif
153
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100154static void mac_zeroize(void *data, size_t size)
155{
Hugues de Valon8b442442019-02-19 14:30:52 +0000156 (void)tfm_memset(data, 0, size);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100157}
158
159static size_t get_hash_block_size(psa_algorithm_t alg)
160{
161 switch (alg) {
162 case PSA_ALG_MD2:
163 return 16;
164 case PSA_ALG_MD4:
165 return 64;
166 case PSA_ALG_MD5:
167 return 64;
168 case PSA_ALG_RIPEMD160:
169 return 64;
170 case PSA_ALG_SHA_1:
171 return 64;
172 case PSA_ALG_SHA_224:
173 return 64;
174 case PSA_ALG_SHA_256:
175 return 64;
176 case PSA_ALG_SHA_384:
177 return 128;
178 case PSA_ALG_SHA_512:
179 return 128;
180 default:
181 return 0;
182 }
183}
184
Antonio de Angelis4743e672019-04-11 11:38:48 +0100185static psa_status_t tfm_crypto_mac_release(uint32_t *handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000186 struct tfm_mac_operation_s *ctx)
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000187{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000188 /* No release necessary on the ctx related items for the time being */
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000189 UNUSED_VAR(ctx);
190
191 /* Release the operation context */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100192 return tfm_crypto_operation_release(handle);
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000193}
194
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000195static psa_status_t tfm_crypto_hmac_setup(struct tfm_mac_operation_s *ctx,
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100196 psa_key_slot_t key,
197 psa_algorithm_t alg)
198{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000199 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100200 psa_key_type_t key_type;
201 size_t key_size;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000202 uint8_t key_data[CRYPTO_HMAC_MAX_KEY_LENGTH];
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100203 uint8_t hashed_key[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
204 size_t block_size;
205 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
206 uint8_t *opad = ctx->ctx.hmac.opad;
207 size_t i;
Jamie Foxefd82732018-11-26 10:34:32 +0000208 psa_key_usage_t usage;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100209
210 /* Check provided key */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000211 status = _psa_get_key_information(key, &key_type, &key_size);
212 if (status != PSA_SUCCESS) {
213 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100214 }
215
216 if (key_type != PSA_KEY_TYPE_HMAC){
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000217 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100218 }
219
Jamie Foxefd82732018-11-26 10:34:32 +0000220 /* Set the key usage based on whether this is a sign or verify operation */
221 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
222 usage = PSA_KEY_USAGE_SIGN;
223 } else if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
224 usage = PSA_KEY_USAGE_VERIFY;
225 } else {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000226 return PSA_ERROR_BAD_STATE;
Jamie Foxefd82732018-11-26 10:34:32 +0000227 }
228
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100229 /* Get the key data to start the HMAC */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000230 status = tfm_crypto_get_key(key,
231 usage,
232 alg,
233 key_data,
234 CRYPTO_HMAC_MAX_KEY_LENGTH,
235 &key_size);
236 if (status != PSA_SUCCESS) {
237 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100238 }
239
240 /* Bind the digest size to the MAC operation */
241 ctx->mac_size = PSA_HASH_SIZE(PSA_ALG_HMAC_HASH(alg));
242
243 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(alg));
244
245 /* The HMAC algorithm is the standard procedure as described in
246 * RFC-2104 (https://tools.ietf.org/html/rfc2104)
247 */
248 if (key_size > block_size) {
249 /* Hash the key to reduce it to block size */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100250 status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000251 PSA_ALG_HMAC_HASH(alg));
252 if (status != PSA_SUCCESS) {
253 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100254 }
255
Antonio de Angelis4743e672019-04-11 11:38:48 +0100256 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000257 &key_data[0],
258 key_size);
259 if (status != PSA_SUCCESS) {
260 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100261 }
262
263 /* Replace the key with the hashed key */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100264 status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000265 hashed_key,
266 sizeof(hashed_key),
267 &key_size);
268 if (status != PSA_SUCCESS) {
269 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100270 }
271 } else {
272 /* Copy the key inside the hashed_key buffer */
273 for (i=0; i<key_size; i++) {
274 hashed_key[i] = key_data[i];
275 }
276 }
277
278 /* Create ipad = hashed_key XOR 0x36 and opad = hashed_key XOR 0x5C */
279 for (i=0; i<key_size; i++) {
280 ipad[i] = hashed_key[i] ^ 0x36;
281 opad[i] = hashed_key[i] ^ 0x5C;
282 }
283 /* Fill ipad and opad to match block size */
284 for (i=key_size; i<block_size; i++) {
285 ipad[i] = 0x36;
286 opad[i] = 0x5C;
287 }
288
289 /* Start hash1 = H(i_key_pad || message) */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100290 status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000291 PSA_ALG_HMAC_HASH(alg));
292 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100293 /* Clear key information on stack */
294 for (i=0; i<key_size; i++) {
295 hashed_key[i] = 0;
296 ipad[i] = 0;
297 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000298 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100299 }
300
Antonio de Angelis4743e672019-04-11 11:38:48 +0100301 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000302 ipad,
303 block_size);
Antonio de Angelis4743e672019-04-11 11:38:48 +0100304 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100305}
306
Antonio de Angelis4743e672019-04-11 11:38:48 +0100307static psa_status_t tfm_crypto_mac_setup(uint32_t *handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000308 psa_key_slot_t key,
309 psa_algorithm_t alg,
310 uint8_t sign_operation)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100311{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000312 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100313 struct tfm_mac_operation_s *ctx = NULL;
314
315 if (!PSA_ALG_IS_MAC(alg)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000316 return PSA_ERROR_NOT_SUPPORTED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100317 }
318
319 /* Allocate the operation context in the secure world */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000320 status = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100321 handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000322 (void **)&ctx);
323 if (status != PSA_SUCCESS) {
324 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100325 }
326
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100327 /* Bind the algorithm to the mac operation */
328 ctx->alg = alg;
329
330 /* Specify if this will be used for a sign or verify operation */
331 if (sign_operation) {
332 ctx->key_usage_verify = 0;
333 ctx->key_usage_sign = 1;
334 } else {
335 ctx->key_usage_verify = 1;
336 ctx->key_usage_sign = 0;
337 }
338
339 if (PSA_ALG_IS_HMAC(alg)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000340 status = tfm_crypto_hmac_setup(ctx, key, alg);
341 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100342 /* Release the operation context */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100343 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000344 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100345 }
346
347 ctx->key_set = 1;
348 } else {
349 /* Other MAC types constructions are not supported */
350 /* Release the operation context */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100351 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000352 return PSA_ERROR_NOT_SUPPORTED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100353 }
354
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000355 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100356}
357
Antonio de Angelis4743e672019-04-11 11:38:48 +0100358static psa_status_t tfm_crypto_mac_finish(uint32_t *handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000359 struct tfm_mac_operation_s *ctx,
360 uint8_t *mac,
361 size_t mac_size,
362 size_t *mac_length)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100363{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000364 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100365 uint8_t hash1[PSA_HASH_MAX_SIZE];
366 size_t hash_size;
367 uint8_t *opad;
368 size_t block_size;
369
370 /* Sanity checks */
371 if (mac_size < ctx->mac_size) {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100372 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000373 return PSA_ERROR_BUFFER_TOO_SMALL;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100374 }
375
376 if (!(ctx->has_input)) {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100377 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000378 return PSA_ERROR_BAD_STATE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100379 }
380
381 if (PSA_ALG_IS_HMAC(ctx->alg)) {
382 opad = ctx->ctx.hmac.opad;
383 block_size = get_hash_block_size(PSA_ALG_HMAC_HASH(ctx->alg));
384
385 /* finish the hash1 = H(ipad || message) */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100386 status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000387 hash1,
388 sizeof(hash1),
389 &hash_size);
390 if (status != PSA_SUCCESS) {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100391 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000392 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100393 }
394
395 /* compute the final mac value = H(opad || hash1) */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100396 status = _psa_hash_setup(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000397 PSA_ALG_HMAC_HASH(ctx->alg));
398 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100399 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis4743e672019-04-11 11:38:48 +0100400 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000401 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100402 }
403
Antonio de Angelis4743e672019-04-11 11:38:48 +0100404 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000405 opad,
406 block_size);
407 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100408 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis4743e672019-04-11 11:38:48 +0100409 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000410 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100411 }
412
Antonio de Angelis4743e672019-04-11 11:38:48 +0100413 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000414 hash1,
415 hash_size);
416 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100417 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis4743e672019-04-11 11:38:48 +0100418 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000419 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100420 }
421
Antonio de Angelis4743e672019-04-11 11:38:48 +0100422 status = _psa_hash_finish(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000423 mac,
424 mac_size,
425 mac_length);
426 if (status != PSA_SUCCESS) {
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100427 mac_zeroize(hash1, sizeof(hash1));
Antonio de Angelis4743e672019-04-11 11:38:48 +0100428 (void)tfm_crypto_mac_release(handle, ctx);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000429 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100430 }
431
432 /* Clear intermediate hash value */
433 mac_zeroize(hash1, sizeof(hash1));
434
435 } else {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000436 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100437 }
438
Antonio de Angelis4743e672019-04-11 11:38:48 +0100439 return tfm_crypto_mac_release(handle, ctx);
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100440}
441
442/*!
443 * \defgroup public_psa Public functions, PSA
444 *
445 */
446
447/*!@{*/
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000448psa_status_t tfm_crypto_mac_sign_setup(psa_invec in_vec[],
449 size_t in_len,
450 psa_outvec out_vec[],
451 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100452{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100453 psa_status_t status = PSA_SUCCESS;
454 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000455 return PSA_CONNECTION_REFUSED;
456 }
457
Antonio de Angelis4743e672019-04-11 11:38:48 +0100458 if ((out_vec[0].len != sizeof(uint32_t)) ||
459 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000460 return PSA_CONNECTION_REFUSED;
461 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100462 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
463 uint32_t handle = iov->handle;
464 uint32_t *handle_out = out_vec[0].base;
465 psa_key_slot_t key = iov->key;
466 psa_algorithm_t alg = iov->alg;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000467
Antonio de Angelis4743e672019-04-11 11:38:48 +0100468 status = tfm_crypto_mac_setup(&handle, key, alg, 1);
469 if (status == PSA_SUCCESS) {
470 *handle_out = handle;
471 } else {
472 *handle_out = iov->handle;
473 }
474 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100475}
476
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000477psa_status_t tfm_crypto_mac_verify_setup(psa_invec in_vec[],
478 size_t in_len,
479 psa_outvec out_vec[],
480 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100481{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100482 psa_status_t status = PSA_SUCCESS;
483 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000484 return PSA_CONNECTION_REFUSED;
485 }
486
Antonio de Angelis4743e672019-04-11 11:38:48 +0100487 if ((out_vec[0].len != sizeof(uint32_t)) ||
488 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000489 return PSA_CONNECTION_REFUSED;
490 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100491 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
492 uint32_t handle = iov->handle;
493 uint32_t *handle_out = out_vec[0].base;
494 psa_key_slot_t key = iov->key;
495 psa_algorithm_t alg = iov->alg;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000496
Antonio de Angelis4743e672019-04-11 11:38:48 +0100497 status = tfm_crypto_mac_setup(&handle, key, alg, 0);
498 if (status == PSA_SUCCESS) {
499 *handle_out = handle;
500 } else {
501 *handle_out = iov->handle;
502 }
503 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100504}
505
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000506psa_status_t tfm_crypto_mac_update(psa_invec in_vec[],
507 size_t in_len,
508 psa_outvec out_vec[],
509 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100510{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000511 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100512 struct tfm_mac_operation_s *ctx = NULL;
513
Antonio de Angelis4743e672019-04-11 11:38:48 +0100514 if ((in_len != 2) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000515 return PSA_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100516 }
517
Antonio de Angelis4743e672019-04-11 11:38:48 +0100518 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
519 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000520 return PSA_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100521 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100522 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
523 uint32_t handle = iov->handle;
524 uint32_t *handle_out = out_vec[0].base;
525 const uint8_t *input = in_vec[1].base;
526 size_t input_length = in_vec[1].len;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100527
Antonio de Angelis4743e672019-04-11 11:38:48 +0100528 /* Init the handle in the operation with the one passed from the iov */
529 *handle_out = iov->handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000530
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100531 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000532 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100533 handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000534 (void **)&ctx);
535 if (status != PSA_SUCCESS) {
536 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100537 }
538
539 /* Sanity check */
540 if (!(ctx->key_set)) {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100541 if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
542 *handle_out = handle;
543 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000544 return PSA_ERROR_BAD_STATE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100545 }
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000546 if (input_length == 0) {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100547 if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
548 *handle_out = handle;
549 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000550 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000551 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100552
553 /* Process the input chunk */
554 if (PSA_ALG_IS_HMAC(ctx->alg)) {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100555 status = _psa_hash_update(&(ctx->ctx.hmac.hash_operation.handle),
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000556 input,
557 input_length);
558 if (status != PSA_SUCCESS) {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100559 if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
560 *handle_out = handle;
561 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000562 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100563 }
564
565 /* Set this flag to avoid HMAC without data */
566 ctx->has_input = 1;
567 } else {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100568 if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
569 *handle_out = handle;
570 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000571 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100572 }
573
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000574 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100575}
576
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000577psa_status_t tfm_crypto_mac_sign_finish(psa_invec in_vec[],
578 size_t in_len,
579 psa_outvec out_vec[],
580 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100581{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000582 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100583 struct tfm_mac_operation_s *ctx = NULL;
584
Antonio de Angelis4743e672019-04-11 11:38:48 +0100585 if ((in_len != 1) || (out_len != 2)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000586 return PSA_CONNECTION_REFUSED;
587 }
588
Antonio de Angelis4743e672019-04-11 11:38:48 +0100589 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
590 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000591 return PSA_CONNECTION_REFUSED;
592 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100593 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
594 uint32_t handle = iov->handle;
595 uint32_t *handle_out = out_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000596 uint8_t *mac = out_vec[1].base;
597 size_t mac_size = out_vec[1].len;
598
Antonio de Angelis4743e672019-04-11 11:38:48 +0100599 /* Init the handle in the operation with the one passed from the iov */
600 *handle_out = iov->handle;
601
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000602 /* Initialise mac_length to zero */
603 out_vec[1].len = 0;
604
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100605 if (mac_size == 0) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000606 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100607 }
608
609 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000610 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100611 handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000612 (void **)&ctx);
613 if (status != PSA_SUCCESS) {
614 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100615 }
616
617 if ((ctx->key_usage_sign == 1) && (ctx->key_usage_verify == 0)) {
618 /* Finalise the mac operation */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100619 status = tfm_crypto_mac_finish(&handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000620 ctx, mac, mac_size, &(out_vec[1].len));
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100621 } else {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100622 if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
623 *handle_out = handle;
624 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000625 return PSA_ERROR_BAD_STATE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100626 }
627
Antonio de Angelis4743e672019-04-11 11:38:48 +0100628 *handle_out = handle;
629 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100630}
631
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000632psa_status_t tfm_crypto_mac_verify_finish(psa_invec in_vec[],
633 size_t in_len,
634 psa_outvec out_vec[],
635 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100636{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000637 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100638 struct tfm_mac_operation_s *ctx = NULL;
639 uint8_t computed_mac[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
640 size_t computed_mac_length;
641 size_t i;
642 uint32_t comp_mismatch = 0;
643
Antonio de Angelis4743e672019-04-11 11:38:48 +0100644 if ((in_len != 2) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000645 return PSA_CONNECTION_REFUSED;
646 }
647
Antonio de Angelis4743e672019-04-11 11:38:48 +0100648 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
649 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000650 return PSA_CONNECTION_REFUSED;
651 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100652 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
653 uint32_t handle = iov->handle;
654 uint32_t *handle_out = out_vec[0].base;
655 const uint8_t *mac = in_vec[1].base;
656 size_t mac_length = in_vec[1].len;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000657
Antonio de Angelis4743e672019-04-11 11:38:48 +0100658 /* Init the handle in the operation with the one passed from the iov */
659 *handle_out = iov->handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000660
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100661 if (mac_length == 0) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000662 return PSA_ERROR_INVALID_ARGUMENT;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100663 }
664
665 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000666 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100667 handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000668 (void **)&ctx);
669 if (status != PSA_SUCCESS) {
670 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100671 }
672
673 if ((ctx->key_usage_sign == 0) && (ctx->key_usage_verify == 1)) {
674 /* Finalise the mac operation */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100675 status = tfm_crypto_mac_finish(&handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000676 ctx,
677 computed_mac,
678 sizeof(computed_mac),
679 &computed_mac_length);
Antonio de Angelis4743e672019-04-11 11:38:48 +0100680 *handle_out = handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000681 if (status != PSA_SUCCESS) {
682 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100683 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100684
685 /* Check that the computed mac match the expected one */
686 if (computed_mac_length != mac_length) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000687 return PSA_ERROR_INVALID_SIGNATURE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100688 }
689
690 for (i=0; i<computed_mac_length ; i++) {
691 if (computed_mac[i] != mac[i]) {
692 comp_mismatch = 1;
693 }
694 }
695
696 if (comp_mismatch == 1) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000697 return PSA_ERROR_INVALID_SIGNATURE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100698 }
699 } else {
Antonio de Angelis4743e672019-04-11 11:38:48 +0100700 if (tfm_crypto_mac_release(&handle, ctx) == PSA_SUCCESS) {
701 *handle_out = handle;
702 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000703 return PSA_ERROR_BAD_STATE;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100704 }
705
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000706 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100707}
708
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000709psa_status_t tfm_crypto_mac_abort(psa_invec in_vec[],
710 size_t in_len,
711 psa_outvec out_vec[],
712 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100713{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000714 psa_status_t status = PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100715 struct tfm_mac_operation_s *ctx = NULL;
716
Antonio de Angelis4743e672019-04-11 11:38:48 +0100717 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000718 return PSA_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100719 }
720
Antonio de Angelis4743e672019-04-11 11:38:48 +0100721 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
722 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000723 return PSA_CONNECTION_REFUSED;
724 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100725 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
726 uint32_t handle = iov->handle;
727 uint32_t *handle_out = out_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000728
Antonio de Angelis4743e672019-04-11 11:38:48 +0100729 /* Init the handle in the operation with the one passed from the iov */
730 *handle_out = iov->handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000731
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100732 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000733 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100734 handle,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000735 (void **)&ctx);
736 if (status != PSA_SUCCESS) {
737 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100738 }
739
740 if (PSA_ALG_IS_HMAC(ctx->alg)){
741 /* Check if the HMAC internal context needs to be deallocated */
742 if (ctx->ctx.hmac.hash_operation.handle != TFM_CRYPTO_INVALID_HANDLE) {
743 /* Clear hash context */
Antonio de Angelis4743e672019-04-11 11:38:48 +0100744 status = _psa_hash_abort(&(ctx->ctx.hmac.hash_operation.handle));
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000745 if (status != PSA_SUCCESS) {
746 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100747 }
748 }
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100749 } else {
750 /* MACs other than HMACs not currently supported */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000751 return PSA_ERROR_NOT_SUPPORTED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100752 }
753
Antonio de Angelis4743e672019-04-11 11:38:48 +0100754 status = tfm_crypto_mac_release(&handle, ctx);
755 if (status == PSA_SUCCESS) {
756 *handle_out = handle;
757 }
758 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100759}
760/*!@}*/