blob: b09efea596413f0fc281aac637c8a2e3fc08f89f [file] [log] [blame]
Steven Cooremand13a70f2021-03-19 15:24:23 +01001/*
2 * PSA MAC layer on top of Mbed TLS software crypto
3 */
4/*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include "common.h"
22
23#if defined(MBEDTLS_PSA_CRYPTO_C)
24
25#include <psa/crypto.h>
26#include "psa_crypto_core.h"
27#include "psa_crypto_mac.h"
Steven Cooreman82c66b62021-03-19 17:39:17 +010028#include <mbedtls/md.h>
Steven Cooremand13a70f2021-03-19 15:24:23 +010029
30#include <mbedtls/error.h>
31#include <string.h>
32
33/* Use builtin defines specific to this compilation unit, since the test driver
34 * relies on the software driver. */
35#if( defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || \
36 ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) ) )
37#define BUILTIN_ALG_CMAC 1
38#endif
39#if( defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || \
40 ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_HMAC) ) )
41#define BUILTIN_ALG_HMAC 1
42#endif
43
Steven Cooreman82c66b62021-03-19 17:39:17 +010044#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST)
45static size_t psa_get_hash_block_size( psa_algorithm_t alg )
46{
47 switch( alg )
48 {
49 case PSA_ALG_MD2:
50 return( 16 );
51 case PSA_ALG_MD4:
52 return( 64 );
53 case PSA_ALG_MD5:
54 return( 64 );
55 case PSA_ALG_RIPEMD160:
56 return( 64 );
57 case PSA_ALG_SHA_1:
58 return( 64 );
59 case PSA_ALG_SHA_224:
60 return( 64 );
61 case PSA_ALG_SHA_256:
62 return( 64 );
63 case PSA_ALG_SHA_384:
64 return( 128 );
65 case PSA_ALG_SHA_512:
66 return( 128 );
67 default:
68 return( 0 );
69 }
70}
71
72psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
73{
74 mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
75 return( psa_hash_abort( &hmac->hash_ctx ) );
76}
77
78psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
79 const uint8_t *key,
80 size_t key_length,
81 psa_algorithm_t hash_alg )
82{
83 uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
84 size_t i;
85 size_t hash_size = PSA_HASH_LENGTH( hash_alg );
86 size_t block_size = psa_get_hash_block_size( hash_alg );
87 psa_status_t status;
88
89 hmac->alg = hash_alg;
90
91 /* Sanity checks on block_size, to guarantee that there won't be a buffer
92 * overflow below. This should never trigger if the hash algorithm
93 * is implemented correctly. */
94 /* The size checks against the ipad and opad buffers cannot be written
95 * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
96 * because that triggers -Wlogical-op on GCC 7.3. */
97 if( block_size > sizeof( ipad ) )
98 return( PSA_ERROR_NOT_SUPPORTED );
99 if( block_size > sizeof( hmac->opad ) )
100 return( PSA_ERROR_NOT_SUPPORTED );
101 if( block_size < hash_size )
102 return( PSA_ERROR_NOT_SUPPORTED );
103
104 if( key_length > block_size )
105 {
106 status = psa_hash_compute( hash_alg, key, key_length,
107 ipad, sizeof( ipad ), &key_length );
108 if( status != PSA_SUCCESS )
109 goto cleanup;
110 }
111 /* A 0-length key is not commonly used in HMAC when used as a MAC,
112 * but it is permitted. It is common when HMAC is used in HKDF, for
113 * example. Don't call `memcpy` in the 0-length because `key` could be
114 * an invalid pointer which would make the behavior undefined. */
115 else if( key_length != 0 )
116 memcpy( ipad, key, key_length );
117
118 /* ipad contains the key followed by garbage. Xor and fill with 0x36
119 * to create the ipad value. */
120 for( i = 0; i < key_length; i++ )
121 ipad[i] ^= 0x36;
122 memset( ipad + key_length, 0x36, block_size - key_length );
123
124 /* Copy the key material from ipad to opad, flipping the requisite bits,
125 * and filling the rest of opad with the requisite constant. */
126 for( i = 0; i < key_length; i++ )
127 hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
128 memset( hmac->opad + key_length, 0x5C, block_size - key_length );
129
130 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
131 if( status != PSA_SUCCESS )
132 goto cleanup;
133
134 status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );
135
136cleanup:
137 mbedtls_platform_zeroize( ipad, sizeof( ipad ) );
138
139 return( status );
140}
141
142psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
143 uint8_t *mac,
144 size_t mac_size )
145{
146 uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
147 psa_algorithm_t hash_alg = hmac->alg;
148 size_t hash_size = 0;
149 size_t block_size = psa_get_hash_block_size( hash_alg );
150 psa_status_t status;
151
152 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
153 if( status != PSA_SUCCESS )
154 return( status );
155 /* From here on, tmp needs to be wiped. */
156
157 status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
158 if( status != PSA_SUCCESS )
159 goto exit;
160
161 status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
162 if( status != PSA_SUCCESS )
163 goto exit;
164
165 status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
166 if( status != PSA_SUCCESS )
167 goto exit;
168
169 status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
170 if( status != PSA_SUCCESS )
171 goto exit;
172
173 memcpy( mac, tmp, mac_size );
174
175exit:
176 mbedtls_platform_zeroize( tmp, hash_size );
177 return( status );
178}
179#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || PSA_CRYPTO_DRIVER_TEST */
180
Steven Cooremand13a70f2021-03-19 15:24:23 +0100181/* Implement the PSA driver MAC interface on top of mbed TLS if either the
182 * software driver or the test driver requires it. */
183#if defined(MBEDTLS_PSA_BUILTIN_MAC) || defined(PSA_CRYPTO_DRIVER_TEST)
184static psa_status_t mac_compute(
185 const psa_key_attributes_t *attributes,
186 const uint8_t *key_buffer,
187 size_t key_buffer_size,
188 psa_algorithm_t alg,
189 const uint8_t *input,
190 size_t input_length,
191 uint8_t *mac,
192 size_t mac_size,
193 size_t *mac_length )
194{
Steven Cooreman82c66b62021-03-19 17:39:17 +0100195 /* One-shot MAC has not been implemented in this PSA implementation yet. */
Steven Cooremand13a70f2021-03-19 15:24:23 +0100196 (void) attributes;
197 (void) key_buffer;
198 (void) key_buffer_size;
199 (void) alg;
200 (void) input;
201 (void) input_length;
202 (void) mac;
203 (void) mac_size;
204 (void) mac_length;
205 return( PSA_ERROR_NOT_SUPPORTED );
206}
207
208static psa_status_t mac_sign_setup(
209 mbedtls_psa_mac_operation_t *operation,
210 const psa_key_attributes_t *attributes,
211 const uint8_t *key_buffer,
212 size_t key_buffer_size,
213 psa_algorithm_t alg )
214{
215 /* To be fleshed out in a subsequent commit */
216 (void) operation;
217 (void) attributes;
218 (void) key_buffer;
219 (void) key_buffer_size;
220 (void) alg;
221 return( PSA_ERROR_NOT_SUPPORTED );
222}
223
224static psa_status_t mac_verify_setup(
225 mbedtls_psa_mac_operation_t *operation,
226 const psa_key_attributes_t *attributes,
227 const uint8_t *key_buffer,
228 size_t key_buffer_size,
229 psa_algorithm_t alg )
230{
231 /* To be fleshed out in a subsequent commit */
232 (void) operation;
233 (void) attributes;
234 (void) key_buffer;
235 (void) key_buffer_size;
236 (void) alg;
237 return( PSA_ERROR_NOT_SUPPORTED );
238}
239
240static psa_status_t mac_update(
241 mbedtls_psa_mac_operation_t *operation,
242 const uint8_t *input,
243 size_t input_length )
244{
245 /* To be fleshed out in a subsequent commit */
246 (void) operation;
247 (void) input;
248 (void) input_length;
249 return( PSA_ERROR_NOT_SUPPORTED );
250}
251
252static psa_status_t mac_sign_finish(
253 mbedtls_psa_mac_operation_t *operation,
254 uint8_t *mac,
255 size_t mac_size,
256 size_t *mac_length )
257{
258 /* To be fleshed out in a subsequent commit */
259 (void) operation;
260 (void) mac;
261 (void) mac_size;
262 (void) mac_length;
263 return( PSA_ERROR_NOT_SUPPORTED );
264}
265
266static psa_status_t mac_verify_finish(
267 mbedtls_psa_mac_operation_t *operation,
268 const uint8_t *mac,
269 size_t mac_length )
270{
271 /* To be fleshed out in a subsequent commit */
272 (void) operation;
273 (void) mac;
274 (void) mac_length;
275 return( PSA_ERROR_NOT_SUPPORTED );
276}
277
278static psa_status_t mac_abort(
279 mbedtls_psa_mac_operation_t *operation )
280{
281 /* To be fleshed out in a subsequent commit */
282 (void) operation;
283 return( PSA_ERROR_NOT_SUPPORTED );
284}
285#endif /* MBEDTLS_PSA_BUILTIN_MAC || PSA_CRYPTO_DRIVER_TEST */
286
287#if defined(MBEDTLS_PSA_BUILTIN_MAC)
288psa_status_t mbedtls_psa_mac_compute(
289 const psa_key_attributes_t *attributes,
290 const uint8_t *key_buffer,
291 size_t key_buffer_size,
292 psa_algorithm_t alg,
293 const uint8_t *input,
294 size_t input_length,
295 uint8_t *mac,
296 size_t mac_size,
297 size_t *mac_length )
298{
299 return( mac_compute( attributes, key_buffer, key_buffer_size, alg,
300 input, input_length,
301 mac, mac_size, mac_length ) );
302}
303
304psa_status_t mbedtls_psa_mac_sign_setup(
305 mbedtls_psa_mac_operation_t *operation,
306 const psa_key_attributes_t *attributes,
307 const uint8_t *key_buffer,
308 size_t key_buffer_size,
309 psa_algorithm_t alg )
310{
311 return( mac_sign_setup( operation, attributes,
312 key_buffer, key_buffer_size, alg ) );
313}
314
315psa_status_t mbedtls_psa_mac_verify_setup(
316 mbedtls_psa_mac_operation_t *operation,
317 const psa_key_attributes_t *attributes,
318 const uint8_t *key_buffer,
319 size_t key_buffer_size,
320 psa_algorithm_t alg )
321{
322 return( mac_verify_setup( operation, attributes,
323 key_buffer, key_buffer_size, alg ) );
324}
325
326psa_status_t mbedtls_psa_mac_update(
327 mbedtls_psa_mac_operation_t *operation,
328 const uint8_t *input,
329 size_t input_length )
330{
331 return( mac_update( operation, input, input_length ) );
332}
333
334psa_status_t mbedtls_psa_mac_sign_finish(
335 mbedtls_psa_mac_operation_t *operation,
336 uint8_t *mac,
337 size_t mac_size,
338 size_t *mac_length )
339{
340 return( mac_sign_finish( operation, mac, mac_size, mac_length ) );
341}
342
343psa_status_t mbedtls_psa_mac_verify_finish(
344 mbedtls_psa_mac_operation_t *operation,
345 const uint8_t *mac,
346 size_t mac_length )
347{
348 return( mac_verify_finish( operation, mac, mac_length ) );
349}
350
351psa_status_t mbedtls_psa_mac_abort(
352 mbedtls_psa_mac_operation_t *operation )
353{
354 return( mac_abort( operation ) );
355}
356#endif /* MBEDTLS_PSA_BUILTIN_MAC */
357
358 /*
359 * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
360 */
361#if defined(PSA_CRYPTO_DRIVER_TEST)
362
363static int is_mac_accelerated( psa_algorithm_t alg )
364{
365#if defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
366 if( PSA_ALG_IS_HMAC( alg ) )
367 return( 1 );
368#endif
369
370 switch( PSA_ALG_FULL_LENGTH_MAC( alg ) )
371 {
372#if defined(MBEDTLS_PSA_ACCEL_ALG_CMAC)
373 case PSA_ALG_CMAC:
374 return( 1 );
375#endif
376 default:
377 return( 0 );
378 }
379}
380
381psa_status_t mbedtls_transparent_test_driver_mac_compute(
382 const psa_key_attributes_t *attributes,
383 const uint8_t *key_buffer,
384 size_t key_buffer_size,
385 psa_algorithm_t alg,
386 const uint8_t *input,
387 size_t input_length,
388 uint8_t *mac,
389 size_t mac_size,
390 size_t *mac_length )
391{
392 if( is_mac_accelerated( alg ) )
393 return( mac_compute( attributes, key_buffer, key_buffer_size, alg,
394 input, input_length,
395 mac, mac_size, mac_length ) );
396 else
397 return( PSA_ERROR_NOT_SUPPORTED );
398}
399
400psa_status_t mbedtls_transparent_test_driver_mac_sign_setup(
401 mbedtls_transparent_test_driver_mac_operation_t *operation,
402 const psa_key_attributes_t *attributes,
403 const uint8_t *key_buffer,
404 size_t key_buffer_size,
405 psa_algorithm_t alg )
406{
407 if( is_mac_accelerated( alg ) )
408 return( mac_sign_setup( operation, attributes,
409 key_buffer, key_buffer_size, alg ) );
410 else
411 return( PSA_ERROR_NOT_SUPPORTED );
412}
413
414psa_status_t mbedtls_transparent_test_driver_mac_verify_setup(
415 mbedtls_transparent_test_driver_mac_operation_t *operation,
416 const psa_key_attributes_t *attributes,
417 const uint8_t *key_buffer,
418 size_t key_buffer_size,
419 psa_algorithm_t alg )
420{
421 if( is_mac_accelerated( alg ) )
422 return( mac_verify_setup( operation, attributes,
423 key_buffer, key_buffer_size, alg ) );
424 else
425 return( PSA_ERROR_NOT_SUPPORTED );
426}
427
428psa_status_t mbedtls_transparent_test_driver_mac_update(
429 mbedtls_transparent_test_driver_mac_operation_t *operation,
430 const uint8_t *input,
431 size_t input_length )
432{
433 if( is_mac_accelerated( operation->alg ) )
434 return( mac_update( operation, input, input_length ) );
435 else
436 return( PSA_ERROR_BAD_STATE );
437}
438
439psa_status_t mbedtls_transparent_test_driver_mac_sign_finish(
440 mbedtls_transparent_test_driver_mac_operation_t *operation,
441 uint8_t *mac,
442 size_t mac_size,
443 size_t *mac_length )
444{
445 if( is_mac_accelerated( operation->alg ) )
446 return( mac_sign_finish( operation, mac, mac_size, mac_length ) );
447 else
448 return( PSA_ERROR_BAD_STATE );
449}
450
451psa_status_t mbedtls_transparent_test_driver_mac_verify_finish(
452 mbedtls_transparent_test_driver_mac_operation_t *operation,
453 const uint8_t *mac,
454 size_t mac_length )
455{
456 if( is_mac_accelerated( operation->alg ) )
457 return( mac_verify_finish( operation, mac, mac_length ) );
458 else
459 return( PSA_ERROR_BAD_STATE );
460}
461
462psa_status_t mbedtls_transparent_test_driver_mac_abort(
463 mbedtls_transparent_test_driver_mac_operation_t *operation )
464{
465 return( mac_abort( operation ) );
466}
467
468psa_status_t mbedtls_opaque_test_driver_mac_compute(
469 const psa_key_attributes_t *attributes,
470 const uint8_t *key_buffer,
471 size_t key_buffer_size,
472 psa_algorithm_t alg,
473 const uint8_t *input,
474 size_t input_length,
475 uint8_t *mac,
476 size_t mac_size,
477 size_t *mac_length )
478{
479 /* Opaque driver testing is not implemented yet through this mechanism. */
480 (void) attributes;
481 (void) key_buffer;
482 (void) key_buffer_size;
483 (void) alg;
484 (void) input;
485 (void) input_length;
486 (void) mac;
487 (void) mac_size;
488 (void) mac_length;
489 return( PSA_ERROR_NOT_SUPPORTED );
490}
491
492psa_status_t mbedtls_opaque_test_driver_mac_sign_setup(
493 mbedtls_opaque_test_driver_mac_operation_t *operation,
494 const psa_key_attributes_t *attributes,
495 const uint8_t *key_buffer,
496 size_t key_buffer_size,
497 psa_algorithm_t alg )
498{
499 /* Opaque driver testing is not implemented yet through this mechanism. */
500 (void) operation;
501 (void) attributes;
502 (void) key_buffer;
503 (void) key_buffer_size;
504 (void) alg;
505 return( PSA_ERROR_NOT_SUPPORTED );
506}
507
508psa_status_t mbedtls_opaque_test_driver_mac_verify_setup(
509 mbedtls_opaque_test_driver_mac_operation_t *operation,
510 const psa_key_attributes_t *attributes,
511 const uint8_t *key_buffer,
512 size_t key_buffer_size,
513 psa_algorithm_t alg )
514{
515 /* Opaque driver testing is not implemented yet through this mechanism. */
516 (void) operation;
517 (void) attributes;
518 (void) key_buffer;
519 (void) key_buffer_size;
520 (void) alg;
521 return( PSA_ERROR_NOT_SUPPORTED );
522}
523
524psa_status_t mbedtls_opaque_test_driver_mac_update(
525 mbedtls_opaque_test_driver_mac_operation_t *operation,
526 const uint8_t *input,
527 size_t input_length )
528{
529 /* Opaque driver testing is not implemented yet through this mechanism. */
530 (void) operation;
531 (void) input;
532 (void) input_length;
533 return( PSA_ERROR_NOT_SUPPORTED );
534}
535
536psa_status_t mbedtls_opaque_test_driver_mac_sign_finish(
537 mbedtls_opaque_test_driver_mac_operation_t *operation,
538 uint8_t *mac,
539 size_t mac_size,
540 size_t *mac_length )
541{
542 /* Opaque driver testing is not implemented yet through this mechanism. */
543 (void) operation;
544 (void) mac;
545 (void) mac_size;
546 (void) mac_length;
547 return( PSA_ERROR_NOT_SUPPORTED );
548}
549
550psa_status_t mbedtls_opaque_test_driver_mac_verify_finish(
551 mbedtls_opaque_test_driver_mac_operation_t *operation,
552 const uint8_t *mac,
553 size_t mac_length )
554{
555 /* Opaque driver testing is not implemented yet through this mechanism. */
556 (void) operation;
557 (void) mac;
558 (void) mac_length;
559 return( PSA_ERROR_NOT_SUPPORTED );
560}
561
562psa_status_t mbedtls_opaque_test_driver_mac_abort(
563 mbedtls_opaque_test_driver_mac_operation_t *operation )
564{
565 /* Opaque driver testing is not implemented yet through this mechanism. */
566 (void) operation;
567 return( PSA_ERROR_NOT_SUPPORTED );
568}
569
570#endif /* PSA_CRYPTO_DRIVER_TEST */
571
572#endif /* MBEDTLS_PSA_CRYPTO_C */