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