ReactOS 0.4.15-dev-8339-g4028de8
cmac.c
Go to the documentation of this file.
1
49/*
50 * References:
51 *
52 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
53 * CMAC Mode for Authentication
54 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
55 *
56 * - RFC 4493 - The AES-CMAC Algorithm
57 * https://tools.ietf.org/html/rfc4493
58 *
59 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
60 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
61 * Algorithm for the Internet Key Exchange Protocol (IKE)
62 * https://tools.ietf.org/html/rfc4615
63 *
64 * Additional test vectors: ISO/IEC 9797-1
65 *
66 */
67
68#if !defined(MBEDTLS_CONFIG_FILE)
69#include "mbedtls/config.h"
70#else
71#include MBEDTLS_CONFIG_FILE
72#endif
73
74#if defined(MBEDTLS_CMAC_C)
75
76#include "mbedtls/cmac.h"
78
79#include <string.h>
80
81
82#if defined(MBEDTLS_PLATFORM_C)
83#include "mbedtls/platform.h"
84#else
85#include <stdlib.h>
86#define mbedtls_calloc calloc
87#define mbedtls_free free
88#if defined(MBEDTLS_SELF_TEST)
89#include <stdio.h>
90#define mbedtls_printf printf
91#endif /* MBEDTLS_SELF_TEST */
92#endif /* MBEDTLS_PLATFORM_C */
93
94#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
95
96/*
97 * Multiplication by u in the Galois field of GF(2^n)
98 *
99 * As explained in NIST SP 800-38B, this can be computed:
100 *
101 * If MSB(p) = 0, then p = (p << 1)
102 * If MSB(p) = 1, then p = (p << 1) ^ R_n
103 * with R_64 = 0x1B and R_128 = 0x87
104 *
105 * Input and output MUST NOT point to the same buffer
106 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
107 */
108static int cmac_multiply_by_u( unsigned char *output,
109 const unsigned char *input,
110 size_t blocksize )
111{
112 const unsigned char R_128 = 0x87;
113 const unsigned char R_64 = 0x1B;
114 unsigned char R_n, mask;
115 unsigned char overflow = 0x00;
116 int i;
117
118 if( blocksize == MBEDTLS_AES_BLOCK_SIZE )
119 {
120 R_n = R_128;
121 }
122 else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE )
123 {
124 R_n = R_64;
125 }
126 else
127 {
129 }
130
131 for( i = (int)blocksize - 1; i >= 0; i-- )
132 {
133 output[i] = input[i] << 1 | overflow;
134 overflow = input[i] >> 7;
135 }
136
137 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
138 * using bit operations to avoid branches */
139
140 /* MSVC has a warning about unary minus on unsigned, but this is
141 * well-defined and precisely what we want to do here */
142#if defined(_MSC_VER)
143#pragma warning( push )
144#pragma warning( disable : 4146 )
145#endif
146 mask = - ( input[0] >> 7 );
147#if defined(_MSC_VER)
148#pragma warning( pop )
149#endif
150
151 output[ blocksize - 1 ] ^= R_n & mask;
152
153 return( 0 );
154}
155
156/*
157 * Generate subkeys
158 *
159 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
160 */
161static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
162 unsigned char* K1, unsigned char* K2 )
163{
164 int ret;
165 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
166 size_t olen, block_size;
167
168 mbedtls_platform_zeroize( L, sizeof( L ) );
169
170 block_size = ctx->cipher_info->block_size;
171
172 /* Calculate Ek(0) */
173 if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 )
174 goto exit;
175
176 /*
177 * Generate K1 and K2
178 */
179 if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 )
180 goto exit;
181
182 if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 )
183 goto exit;
184
185exit:
186 mbedtls_platform_zeroize( L, sizeof( L ) );
187
188 return( ret );
189}
190#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
191
192#if !defined(MBEDTLS_CMAC_ALT)
193static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
194 const unsigned char *input2,
195 const size_t block_size )
196{
197 size_t idx;
198
199 for( idx = 0; idx < block_size; idx++ )
200 output[ idx ] = input1[ idx ] ^ input2[ idx ];
201}
202
203/*
204 * Create padded last block from (partial) last block.
205 *
206 * We can't use the padding option from the cipher layer, as it only works for
207 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
208 */
209static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
210 size_t padded_block_len,
211 const unsigned char *last_block,
212 size_t last_block_len )
213{
214 size_t j;
215
216 for( j = 0; j < padded_block_len; j++ )
217 {
218 if( j < last_block_len )
219 padded_block[j] = last_block[j];
220 else if( j == last_block_len )
221 padded_block[j] = 0x80;
222 else
223 padded_block[j] = 0x00;
224 }
225}
226
228 const unsigned char *key, size_t keybits )
229{
231 mbedtls_cmac_context_t *cmac_ctx;
232 int retval;
233
234 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
236
237 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
238 MBEDTLS_ENCRYPT ) ) != 0 )
239 return( retval );
240
241 type = ctx->cipher_info->type;
242
243 switch( type )
244 {
249 break;
250 default:
252 }
253
254 /* Allocated and initialise in the cipher context memory for the CMAC
255 * context */
256 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
257 if( cmac_ctx == NULL )
259
260 ctx->cmac_ctx = cmac_ctx;
261
262 mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
263
264 return 0;
265}
266
268 const unsigned char *input, size_t ilen )
269{
270 mbedtls_cmac_context_t* cmac_ctx;
271 unsigned char *state;
272 int ret = 0;
273 size_t n, j, olen, block_size;
274
275 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
276 ctx->cmac_ctx == NULL )
278
279 cmac_ctx = ctx->cmac_ctx;
280 block_size = ctx->cipher_info->block_size;
281 state = ctx->cmac_ctx->state;
282
283 /* Is there data still to process from the last call, that's greater in
284 * size than a block? */
285 if( cmac_ctx->unprocessed_len > 0 &&
286 ilen > block_size - cmac_ctx->unprocessed_len )
287 {
288 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
289 input,
290 block_size - cmac_ctx->unprocessed_len );
291
292 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
293
295 &olen ) ) != 0 )
296 {
297 goto exit;
298 }
299
300 input += block_size - cmac_ctx->unprocessed_len;
301 ilen -= block_size - cmac_ctx->unprocessed_len;
302 cmac_ctx->unprocessed_len = 0;
303 }
304
305 /* n is the number of blocks including any final partial block */
306 n = ( ilen + block_size - 1 ) / block_size;
307
308 /* Iterate across the input data in block sized chunks, excluding any
309 * final partial or complete block */
310 for( j = 1; j < n; j++ )
311 {
312 cmac_xor_block( state, input, state, block_size );
313
315 &olen ) ) != 0 )
316 goto exit;
317
318 ilen -= block_size;
319 input += block_size;
320 }
321
322 /* If there is data left over that wasn't aligned to a block */
323 if( ilen > 0 )
324 {
325 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
326 input,
327 ilen );
328 cmac_ctx->unprocessed_len += ilen;
329 }
330
331exit:
332 return( ret );
333}
334
336 unsigned char *output )
337{
338 mbedtls_cmac_context_t* cmac_ctx;
339 unsigned char *state, *last_block;
340 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
341 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
342 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
343 int ret;
344 size_t olen, block_size;
345
346 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
347 output == NULL )
349
350 cmac_ctx = ctx->cmac_ctx;
351 block_size = ctx->cipher_info->block_size;
352 state = cmac_ctx->state;
353
354 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
355 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
356 cmac_generate_subkeys( ctx, K1, K2 );
357
358 last_block = cmac_ctx->unprocessed_block;
359
360 /* Calculate last block */
361 if( cmac_ctx->unprocessed_len < block_size )
362 {
363 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
364 cmac_xor_block( M_last, M_last, K2, block_size );
365 }
366 else
367 {
368 /* Last block is complete block */
369 cmac_xor_block( M_last, last_block, K1, block_size );
370 }
371
372
373 cmac_xor_block( state, M_last, state, block_size );
375 &olen ) ) != 0 )
376 {
377 goto exit;
378 }
379
380 memcpy( output, state, block_size );
381
382exit:
383 /* Wipe the generated keys on the stack, and any other transients to avoid
384 * side channel leakage */
385 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
386 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
387
388 cmac_ctx->unprocessed_len = 0;
390 sizeof( cmac_ctx->unprocessed_block ) );
391
393 return( ret );
394}
395
397{
398 mbedtls_cmac_context_t* cmac_ctx;
399
400 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
402
403 cmac_ctx = ctx->cmac_ctx;
404
405 /* Reset the internal state */
406 cmac_ctx->unprocessed_len = 0;
408 sizeof( cmac_ctx->unprocessed_block ) );
410 sizeof( cmac_ctx->state ) );
411
412 return( 0 );
413}
414
415int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
416 const unsigned char *key, size_t keylen,
417 const unsigned char *input, size_t ilen,
418 unsigned char *output )
419{
421 int ret;
422
423 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
425
427
428 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
429 goto exit;
430
431 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
432 if( ret != 0 )
433 goto exit;
434
436 if( ret != 0 )
437 goto exit;
438
439 ret = mbedtls_cipher_cmac_finish( &ctx, output );
440
441exit:
443
444 return( ret );
445}
446
447#if defined(MBEDTLS_AES_C)
448/*
449 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
450 */
451int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
452 const unsigned char *input, size_t in_len,
453 unsigned char output[16] )
454{
455 int ret;
456 const mbedtls_cipher_info_t *cipher_info;
457 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
458 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
459
460 if( key == NULL || input == NULL || output == NULL )
462
464 if( cipher_info == NULL )
465 {
466 /* Failing at this point must be due to a build issue */
468 goto exit;
469 }
470
472 {
473 /* Use key as is */
474 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
475 }
476 else
477 {
479
480 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
481 key_length, int_key );
482 if( ret != 0 )
483 goto exit;
484 }
485
486 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
487 output );
488
489exit:
490 mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
491
492 return( ret );
493}
494#endif /* MBEDTLS_AES_C */
495
496#endif /* !MBEDTLS_CMAC_ALT */
497
498#if defined(MBEDTLS_SELF_TEST)
499/*
500 * CMAC test data for SP800-38B
501 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
502 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
503 *
504 * AES-CMAC-PRF-128 test data from RFC 4615
505 * https://tools.ietf.org/html/rfc4615#page-4
506 */
507
508#define NB_CMAC_TESTS_PER_KEY 4
509#define NB_PRF_TESTS 3
510
511#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
512/* All CMAC test inputs are truncated from the same 64 byte buffer. */
513static const unsigned char test_message[] = {
514 /* PT */
515 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
516 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
517 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
518 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
519 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
520 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
521 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
522 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
523};
524#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
525
526#if defined(MBEDTLS_AES_C)
527/* Truncation point of message for AES CMAC tests */
528static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
529 /* Mlen */
530 0,
531 16,
532 20,
533 64
534};
535
536/* CMAC-AES128 Test Data */
537static const unsigned char aes_128_key[16] = {
538 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
539 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
540};
541static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
542 {
543 /* K1 */
544 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
545 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
546 },
547 {
548 /* K2 */
549 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
550 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
551 }
552};
553static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
554 {
555 /* Example #1 */
556 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
557 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
558 },
559 {
560 /* Example #2 */
561 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
562 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
563 },
564 {
565 /* Example #3 */
566 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
567 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
568 },
569 {
570 /* Example #4 */
571 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
572 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
573 }
574};
575
576/* CMAC-AES192 Test Data */
577static const unsigned char aes_192_key[24] = {
578 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
579 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
580 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
581};
582static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
583 {
584 /* K1 */
585 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
586 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
587 },
588 {
589 /* K2 */
590 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
591 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
592 }
593};
594static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
595 {
596 /* Example #1 */
597 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
598 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
599 },
600 {
601 /* Example #2 */
602 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
603 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
604 },
605 {
606 /* Example #3 */
607 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
608 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
609 },
610 {
611 /* Example #4 */
612 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
613 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
614 }
615};
616
617/* CMAC-AES256 Test Data */
618static const unsigned char aes_256_key[32] = {
619 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
620 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
621 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
622 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
623};
624static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
625 {
626 /* K1 */
627 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
628 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
629 },
630 {
631 /* K2 */
632 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
633 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
634 }
635};
636static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
637 {
638 /* Example #1 */
639 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
640 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
641 },
642 {
643 /* Example #2 */
644 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
645 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
646 },
647 {
648 /* Example #3 */
649 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
650 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
651 },
652 {
653 /* Example #4 */
654 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
655 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
656 }
657};
658#endif /* MBEDTLS_AES_C */
659
660#if defined(MBEDTLS_DES_C)
661/* Truncation point of message for 3DES CMAC tests */
662static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
663 0,
664 16,
665 20,
666 32
667};
668
669/* CMAC-TDES (Generation) - 2 Key Test Data */
670static const unsigned char des3_2key_key[24] = {
671 /* Key1 */
672 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
673 /* Key2 */
674 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
675 /* Key3 */
676 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
677};
678static const unsigned char des3_2key_subkeys[2][8] = {
679 {
680 /* K1 */
681 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
682 },
683 {
684 /* K2 */
685 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
686 }
687};
688static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
689 {
690 /* Sample #1 */
691 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
692 },
693 {
694 /* Sample #2 */
695 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
696 },
697 {
698 /* Sample #3 */
699 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
700 },
701 {
702 /* Sample #4 */
703 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
704 }
705};
706
707/* CMAC-TDES (Generation) - 3 Key Test Data */
708static const unsigned char des3_3key_key[24] = {
709 /* Key1 */
710 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
711 /* Key2 */
712 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
713 /* Key3 */
714 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
715};
716static const unsigned char des3_3key_subkeys[2][8] = {
717 {
718 /* K1 */
719 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
720 },
721 {
722 /* K2 */
723 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
724 }
725};
726static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
727 {
728 /* Sample #1 */
729 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
730 },
731 {
732 /* Sample #2 */
733 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
734 },
735 {
736 /* Sample #3 */
737 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
738 },
739 {
740 /* Sample #4 */
741 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
742 }
743};
744
745#endif /* MBEDTLS_DES_C */
746
747#if defined(MBEDTLS_AES_C)
748/* AES AES-CMAC-PRF-128 Test Data */
749static const unsigned char PRFK[] = {
750 /* Key */
751 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
752 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
753 0xed, 0xcb
754};
755
756/* Sizes in bytes */
757static const size_t PRFKlen[NB_PRF_TESTS] = {
758 18,
759 16,
760 10
761};
762
763/* Message */
764static const unsigned char PRFM[] = {
765 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
766 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
767 0x10, 0x11, 0x12, 0x13
768};
769
770static const unsigned char PRFT[NB_PRF_TESTS][16] = {
771 {
772 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
773 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
774 },
775 {
776 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
777 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
778 },
779 {
780 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
781 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
782 }
783};
784#endif /* MBEDTLS_AES_C */
785
786static int cmac_test_subkeys( int verbose,
787 const char* testname,
788 const unsigned char* key,
789 int keybits,
790 const unsigned char* subkeys,
791 mbedtls_cipher_type_t cipher_type,
792 int block_size,
793 int num_tests )
794{
795 int i, ret = 0;
797 const mbedtls_cipher_info_t *cipher_info;
798 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
799 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
800
801 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
802 if( cipher_info == NULL )
803 {
804 /* Failing at this point must be due to a build issue */
806 }
807
808 for( i = 0; i < num_tests; i++ )
809 {
810 if( verbose != 0 )
811 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
812
814
815 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
816 {
817 if( verbose != 0 )
818 mbedtls_printf( "test execution failed\n" );
819
820 goto cleanup;
821 }
822
823 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
824 MBEDTLS_ENCRYPT ) ) != 0 )
825 {
826 if( verbose != 0 )
827 mbedtls_printf( "test execution failed\n" );
828
829 goto cleanup;
830 }
831
832 ret = cmac_generate_subkeys( &ctx, K1, K2 );
833 if( ret != 0 )
834 {
835 if( verbose != 0 )
836 mbedtls_printf( "failed\n" );
837
838 goto cleanup;
839 }
840
841 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
842 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
843 {
844 if( verbose != 0 )
845 mbedtls_printf( "failed\n" );
846
847 goto cleanup;
848 }
849
850 if( verbose != 0 )
851 mbedtls_printf( "passed\n" );
852
854 }
855
856 ret = 0;
857 goto exit;
858
859cleanup:
861
862exit:
863 return( ret );
864}
865
866static int cmac_test_wth_cipher( int verbose,
867 const char* testname,
868 const unsigned char* key,
869 int keybits,
870 const unsigned char* messages,
871 const unsigned int message_lengths[4],
872 const unsigned char* expected_result,
873 mbedtls_cipher_type_t cipher_type,
874 int block_size,
875 int num_tests )
876{
877 const mbedtls_cipher_info_t *cipher_info;
878 int i, ret = 0;
879 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
880
881 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
882 if( cipher_info == NULL )
883 {
884 /* Failing at this point must be due to a build issue */
886 goto exit;
887 }
888
889 for( i = 0; i < num_tests; i++ )
890 {
891 if( verbose != 0 )
892 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
893
894 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
895 message_lengths[i], output ) ) != 0 )
896 {
897 if( verbose != 0 )
898 mbedtls_printf( "failed\n" );
899 goto exit;
900 }
901
902 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
903 {
904 if( verbose != 0 )
905 mbedtls_printf( "failed\n" );
906 goto exit;
907 }
908
909 if( verbose != 0 )
910 mbedtls_printf( "passed\n" );
911 }
912 ret = 0;
913
914exit:
915 return( ret );
916}
917
918#if defined(MBEDTLS_AES_C)
919static int test_aes128_cmac_prf( int verbose )
920{
921 int i;
922 int ret;
923 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
924
925 for( i = 0; i < NB_PRF_TESTS; i++ )
926 {
927 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
928 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
929 if( ret != 0 ||
930 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
931 {
932
933 if( verbose != 0 )
934 mbedtls_printf( "failed\n" );
935
936 return( ret );
937 }
938 else if( verbose != 0 )
939 {
940 mbedtls_printf( "passed\n" );
941 }
942 }
943 return( ret );
944}
945#endif /* MBEDTLS_AES_C */
946
947int mbedtls_cmac_self_test( int verbose )
948{
949 int ret;
950
951#if defined(MBEDTLS_AES_C)
952 /* AES-128 */
953 if( ( ret = cmac_test_subkeys( verbose,
954 "AES 128",
955 aes_128_key,
956 128,
957 (const unsigned char*)aes_128_subkeys,
960 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
961 {
962 return( ret );
963 }
964
965 if( ( ret = cmac_test_wth_cipher( verbose,
966 "AES 128",
967 aes_128_key,
968 128,
969 test_message,
970 aes_message_lengths,
971 (const unsigned char*)aes_128_expected_result,
974 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
975 {
976 return( ret );
977 }
978
979 /* AES-192 */
980 if( ( ret = cmac_test_subkeys( verbose,
981 "AES 192",
982 aes_192_key,
983 192,
984 (const unsigned char*)aes_192_subkeys,
987 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
988 {
989 return( ret );
990 }
991
992 if( ( ret = cmac_test_wth_cipher( verbose,
993 "AES 192",
994 aes_192_key,
995 192,
996 test_message,
997 aes_message_lengths,
998 (const unsigned char*)aes_192_expected_result,
1001 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
1002 {
1003 return( ret );
1004 }
1005
1006 /* AES-256 */
1007 if( ( ret = cmac_test_subkeys( verbose,
1008 "AES 256",
1009 aes_256_key,
1010 256,
1011 (const unsigned char*)aes_256_subkeys,
1014 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
1015 {
1016 return( ret );
1017 }
1018
1019 if( ( ret = cmac_test_wth_cipher ( verbose,
1020 "AES 256",
1021 aes_256_key,
1022 256,
1023 test_message,
1024 aes_message_lengths,
1025 (const unsigned char*)aes_256_expected_result,
1028 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
1029 {
1030 return( ret );
1031 }
1032#endif /* MBEDTLS_AES_C */
1033
1034#if defined(MBEDTLS_DES_C)
1035 /* 3DES 2 key */
1036 if( ( ret = cmac_test_subkeys( verbose,
1037 "3DES 2 key",
1038 des3_2key_key,
1039 192,
1040 (const unsigned char*)des3_2key_subkeys,
1043 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
1044 {
1045 return( ret );
1046 }
1047
1048 if( ( ret = cmac_test_wth_cipher( verbose,
1049 "3DES 2 key",
1050 des3_2key_key,
1051 192,
1052 test_message,
1053 des3_message_lengths,
1054 (const unsigned char*)des3_2key_expected_result,
1057 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
1058 {
1059 return( ret );
1060 }
1061
1062 /* 3DES 3 key */
1063 if( ( ret = cmac_test_subkeys( verbose,
1064 "3DES 3 key",
1065 des3_3key_key,
1066 192,
1067 (const unsigned char*)des3_3key_subkeys,
1070 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
1071 {
1072 return( ret );
1073 }
1074
1075 if( ( ret = cmac_test_wth_cipher( verbose,
1076 "3DES 3 key",
1077 des3_3key_key,
1078 192,
1079 test_message,
1080 des3_message_lengths,
1081 (const unsigned char*)des3_3key_expected_result,
1084 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
1085 {
1086 return( ret );
1087 }
1088#endif /* MBEDTLS_DES_C */
1089
1090#if defined(MBEDTLS_AES_C)
1091 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
1092 return( ret );
1093#endif /* MBEDTLS_AES_C */
1094
1095 if( verbose != 0 )
1096 mbedtls_printf( "\n" );
1097
1098 return( 0 );
1099}
1100
1101#endif /* MBEDTLS_SELF_TEST */
1102
1103#endif /* MBEDTLS_CMAC_C */
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static int state
Definition: maze.c:121
uint8 zero_key[]
Definition: pstcache.c:34
int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info)
This function initializes and fills the cipher-context structure with the appropriate values....
mbedtls_cipher_type_t
Supported {cipher type, cipher mode} pairs.
Definition: cipher.h:129
@ MBEDTLS_CIPHER_AES_128_ECB
Definition: cipher.h:132
@ MBEDTLS_CIPHER_AES_256_ECB
Definition: cipher.h:134
@ MBEDTLS_CIPHER_AES_192_ECB
Definition: cipher.h:133
@ MBEDTLS_CIPHER_DES_EDE3_ECB
Definition: cipher.h:166
int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, const unsigned char *key, int key_bitlen, const mbedtls_operation_t operation)
This function sets the key to use with the given context.
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
Definition: cipher.h:84
#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
Definition: cipher.h:85
void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx)
This function initializes a cipher_context as NONE.
void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
This function frees and clears the cipher-specific context of ctx. Freeing ctx itself remains the res...
int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen)
The generic cipher update function. It encrypts or decrypts using the given cipher context....
@ MBEDTLS_ENCRYPT
Definition: cipher.h:234
#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED
Definition: cipher.h:86
This file contains CMAC definitions and functions.
int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen)
This function feeds an input buffer into an ongoing CMAC computation.
int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
This function prepares the authentication of another message with the same key as the previous CMAC o...
#define MBEDTLS_AES_BLOCK_SIZE
Definition: cmac.h:71
int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx, unsigned char *output)
This function finishes the CMAC operation, and writes the result to the output buffer.
#define MBEDTLS_DES3_BLOCK_SIZE
Definition: cmac.h:72
#define MBEDTLS_CIPHER_BLKSIZE_MAX
Definition: cmac.h:75
int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_len, const unsigned char *input, size_t in_len, unsigned char output[16])
This function implements the AES-CMAC-PRF-128 pseudorandom function, as defined in RFC-4615: The Adva...
int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx, const unsigned char *key, size_t keybits)
This function sets the CMAC key, and prepares to authenticate the input data. Must be called with an ...
int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info, const unsigned char *key, size_t keylen, const unsigned char *input, size_t ilen, unsigned char *output)
This function calculates the full generic CMAC on the input buffer with the provided key.
#define NULL
Definition: types.h:112
unsigned int idx
Definition: utils.c:41
static void cleanup(void)
Definition: main.c:1335
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble n
Definition: glext.h:7729
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum GLenum GLenum input
Definition: glext.h:9031
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define key_length
Definition: crypt.c:1002
const char * expected_result
Definition: mimeole.c:1468
#define L(x)
Definition: ntvdm.h:50
void mbedtls_platform_zeroize(void *buf, size_t len)
Securely zeroize a buffer.
Definition: platform_util.c:98
Common and shared functions used by multiple modules in the Mbed TLS library.
#define verbose
Definition: rosglue.h:36
#define mbedtls_cipher_info_from_type
Configuration options (set of defines)
This file contains the definitions and functions of the Mbed TLS platform abstraction layer.
#define mbedtls_calloc
Definition: platform.h:169
#define exit(n)
Definition: config.h:202
#define memset(x, y, z)
Definition: compat.h:39
Definition: copy.c:22
unsigned char unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX]
Definition: cmac.h:92
size_t unprocessed_len
Definition: cmac.h:95
unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX]
Definition: cmac.h:88
#define mbedtls_printf
Definition: timing.c:57
int ret