blob: 0d93c973658776f6da4c0d457fc2ff4f69218b95 [file] [log] [blame]
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001/*
2 * NIST SP800-38B compliant CMAC implementation
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
23 * Definition of CMAC:
24 * http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf
25 * RFC 4493 "The AES-CMAC Algorithm"
26 */
27
28#if !defined(MBEDTLS_CONFIG_FILE)
29#include "mbedtls/config.h"
30#else
31#include MBEDTLS_CONFIG_FILE
32#endif
33
34#if defined(MBEDTLS_CMAC_C)
35
36#include "mbedtls/cmac.h"
37
38#include <string.h>
39
40#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
41#if defined(MBEDTLS_PLATFORM_C)
42#include "mbedtls/platform.h"
43#else
44#include <stdio.h>
45#define mbedtls_printf printf
46#endif /* MBEDTLS_PLATFORM_C */
47#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
48
49/*
50 * Macros for common operations.
51 * Results in smaller compiled code than static inline functions.
52 */
53
54/*
55 * XOR 128-bit
56 */
57#define XOR_128(i1, i2, o) \
58 for( i = 0; i < 16; i++ ) \
59 ( o )[i] = ( i1 )[i] ^ ( i2 )[i];
60
61/*
62 * Update the CMAC state in Mn using an input block x
63 * TODO: Compiler optimisation
64 */
65#define UPDATE_CMAC( x ) \
66 XOR_128( Mn, ( x ), Mn ); \
67 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, Mn, 16, Mn, &olen ) ) != 0 ) \
68 return( ret );
69
70/* Implementation that should never be optimized out by the compiler */
71static void mbedtls_zeroize( void *v, size_t n ) {
72 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
73}
74
75/*
76 * Initialize context
77 */
78void mbedtls_cmac_init( mbedtls_cmac_context *ctx )
79{
80 memset( ctx, 0, sizeof( mbedtls_cmac_context ) );
81}
82
83/*
84 * Leftshift a 16-byte block by 1 bit
85 * \note output can be same as input
86 */
87static void leftshift_onebit(unsigned char *input, unsigned char *output)
88{
89 int i;
90 unsigned char temp;
91 unsigned char overflow = 0;
92
93 for( i = 15; i >= 0; i-- )
94 {
95 temp = input[i];
96 output[i] = temp << 1;
97 output[i] |= overflow;
98 overflow = temp >> 7;
99 }
100 return;
101}
102
103/*
104 * Generate subkeys
105 */
106static int generate_subkeys(mbedtls_cmac_context *ctx)
107{
108 static const unsigned char Rb[2] = {0x00, 0x87}; /* Note - block size 16 only */
109 int ret;
110 unsigned char L[16];
111 size_t olen;
112
113 /* Calculate Ek(0) */
114 memset( L, 0, 16 );
115 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, L, 16, L, &olen ) ) != 0 )
116 {
117 return( ret );
118 }
119
120 /*
121 * Generate K1
122 * If MSB(L) = 0, then K1 = (L << 1)
123 * If MSB(L) = 1, then K1 = (L << 1) ^ Rb
124 */
125 leftshift_onebit( L, ctx->K1 );
126 ctx->K1[15] ^= Rb[L[0] >> 7]; /* "Constant-time" operation */
127
128 /*
129 * Generate K2
130 * If MSB(K1) == 0, then K2 = (K1 << 1)
131 * If MSB(K1) == 1, then K2 = (K1 << 1) ^ Rb
132 */
133 leftshift_onebit( ctx->K1, ctx->K2 );
134 ctx->K2[15] ^= Rb[ctx->K1[0] >> 7]; /* "Constant-time" operation */
135
136 return( 0 );
137}
138
139int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx,
140 mbedtls_cipher_id_t cipher,
141 const unsigned char *key,
142 unsigned int keybits )
143{
144 int ret;
145 const mbedtls_cipher_info_t *cipher_info;
146
147 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
148 if( cipher_info == NULL )
149 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
150
151 if( cipher_info->block_size != 16 )
152 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
153
154 mbedtls_cipher_free( &ctx->cipher_ctx );
155
156 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
157 return( ret );
158
159 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
160 MBEDTLS_ENCRYPT ) ) != 0 )
161 {
162 return( ret );
163 }
164
165 return( generate_subkeys(ctx) );
166}
167
168/*
169 * Free context
170 */
171void mbedtls_cmac_free( mbedtls_cmac_context *ctx )
172{
173 mbedtls_cipher_free( &ctx->cipher_ctx );
174 mbedtls_zeroize( ctx, sizeof( mbedtls_cmac_context ) );
175}
176
177/* TODO: Use cipher padding function? */
178static void padding(const unsigned char *lastb, unsigned char *pad, const size_t length)
179{
180 size_t j;
181
182 /* original last block */
183 for( j = 0; j < 16; j++ )
184 {
185 if( j < length )
186 {
187 pad[j] = lastb[j];
188 }
189 else if( j == length )
190 {
191 pad[j] = 0x80;
192 }
193 else
194 {
195 pad[j] = 0x00;
196 }
197 }
198}
199
200/*
201 * Generate tag on complete message
202 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000203static int cmac_generate( mbedtls_cmac_context *ctx,
204 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000205 unsigned char *tag, size_t tag_len )
206{
207 unsigned char Mn[16];
208 unsigned char M_last[16];
209 unsigned char padded[16];
210 int n, i, j, ret, flag;
211 size_t olen;
212
213 /*
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000214 * Check in_len requirements: SP800-38B A
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000215 * 4 is a worst case bottom limit
216 */
217 if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
218 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
219
220 /* TODO: Use cipher padding function? */
221 // mbedtls_cipher_set_padding_mode( ctx->cipher, MBEDTLS_PADDING_ONE_AND_ZEROS );
222
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000223 n = ( in_len + 15 ) / 16; /* n is number of rounds */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000224
225 if( n == 0 )
226 {
227 n = 1;
228 flag = 0;
229 }
230 else
231 {
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000232 flag = ( ( in_len % 16 ) == 0);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000233 }
234
235 /* Calculate last block */
236 if( flag )
237 {
238 /* Last block is complete block */
239 XOR_128( &input[16 * (n - 1)], ctx->K1, M_last );
240 }
241 else
242 {
243 /* TODO: Use cipher padding function? */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000244 padding( &input[16 * (n - 1)], padded, in_len % 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000245 XOR_128( padded, ctx->K2, M_last );
246 }
247
248 memset( Mn, 0, 16 );
249
250 for( j = 0; j < n - 1; j++ )
251 {
252 UPDATE_CMAC(&input[16 * j]);
253 }
254
255 UPDATE_CMAC(M_last);
256
257 memcpy( tag, Mn, 16 );
258
259 return( 0 );
260}
261
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000262int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
263 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000264 unsigned char *tag, size_t tag_len )
265{
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000266 return( cmac_generate( ctx, input, in_len, tag, tag_len ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000267}
268
269/*
270 * Authenticated decryption
271 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000272int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
273 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000274 const unsigned char *tag, size_t tag_len )
275{
276 int ret;
277 unsigned char check_tag[16];
278 unsigned char i;
279 int diff;
280
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000281 if( ( ret = cmac_generate( ctx, input, in_len, check_tag, tag_len) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000282 {
283 return ret;
284 }
285
286 /* Check tag in "constant-time" */
287 for( diff = 0, i = 0; i < tag_len; i++ )
288 {
289 diff |= tag[i] ^ check_tag[i];
290 }
291
292 if( diff != 0 )
293 {
294 return( MBEDTLS_ERR_CMAC_VERIFY_FAILED );
295 }
296
297 return( 0 );
298}
299
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000300int mbedtls_aes_cmac_prf_128( mbedtls_cmac_context *ctx,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000301 const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000302 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000303 unsigned char *tag )
304{
305 int ret;
306 unsigned char zero_key[16];
307 unsigned char int_key[16];
308
309 if( key_length == 16 )
310 {
311 /* Use key as is */
312 memcpy(int_key, key, 16);
313 }
314 else
315 {
316 mbedtls_cmac_context zero_ctx;
317
318 /* Key is AES_CMAC(0, key) */
319 mbedtls_cmac_init( &zero_ctx );
320 memset(zero_key, 0, 16);
321 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES, zero_key, 8 * sizeof zero_key );
322 if( ret != 0 )
323 {
324 return( ret );
325 }
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000326 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000327 if( ret != 0 )
328 {
329 return( ret );
330 }
331 }
332
333 ret = mbedtls_cmac_setkey( ctx, MBEDTLS_CIPHER_ID_AES, int_key, 8 * sizeof int_key );
334 if( ret != 0 )
335 {
336 return( ret );
337 }
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000338 return( mbedtls_cmac_generate( ctx, input, in_len, tag, 16 ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000339}
340
341#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
342/*
343 * Examples 1 to 4 from SP800-3B corrected Appendix D.1
344 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
345 */
346
347#define NB_CMAC_TESTS 4
348#define NB_PRF_TESTS 3
349
350/* Key */
351static const unsigned char key[] = {
352 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
353 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
354};
355
356/* Assume we don't need to test Ek0 as this is a function of the cipher */
357
358/* Subkey K1 */
359static const unsigned char K1[] = {
360 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
361 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
362};
363
364/* Subkey K2 */
365static const unsigned char K2[] = {
366 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
367 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
368};
369
370/* All Messages */
371static const unsigned char M[] = {
372 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
373 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
374 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
375 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
376 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
377 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
378 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
379 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
380};
381
382static const unsigned char T[NB_CMAC_TESTS][16] = {
383 {
384 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
385 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
386 },
387 {
388 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
389 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
390 },
391 {
392 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
393 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
394 },
395 {
396 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
397 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
398 }
399};
400
401/* Sizes in bytes */
402static const size_t Mlen[NB_CMAC_TESTS] = {
403 0,
404 16,
405 40,
406 64
407};
408
409/* PRF K */
410static const unsigned char PRFK[] = {
411 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
412 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
413 0xed, 0xcb
414};
415
416/* Sizes in bytes */
417static const size_t PRFKlen[NB_PRF_TESTS] = {
418 18,
419 16,
420 10
421};
422
423/* PRF M */
424static const unsigned char PRFM[] = {
425 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
426 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
427 0x10, 0x11, 0x12, 0x13
428};
429
430static const unsigned char PRFT[NB_PRF_TESTS][16] = {
431 {
432 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
433 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
434 },
435 {
436 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
437 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
438 },
439 {
440 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
441 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
442 }
443};
444
445
446int mbedtls_cmac_self_test( int verbose )
447{
448 mbedtls_cmac_context ctx;
449 unsigned char tag[16];
450 int i;
451 int ret;
452
453 mbedtls_cmac_init( &ctx );
454
455 if( mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
456 {
457 if( verbose != 0 )
458 mbedtls_printf( " CMAC: setup failed" );
459
460 return( 1 );
461 }
462
463 if( ( memcmp( ctx.K1, K1, 16 ) != 0 ) ||
464 ( memcmp( ctx.K2, K2, 16 ) != 0 ) )
465 {
466 if( verbose != 0 )
467 mbedtls_printf( " CMAC: subkey generation failed" );
468
469 return( 1 );
470 }
471
472 for( i = 0; i < NB_CMAC_TESTS; i++ )
473 {
474 mbedtls_printf( " AES-128-CMAC #%u: ", i );
475
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000476 ret = mbedtls_cmac_generate( &ctx, M, Mlen[i], tag, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000477 if( ret != 0 ||
478 memcmp( tag, T[i], 16 ) != 0 )
479 {
480 if( verbose != 0 )
481 mbedtls_printf( "failed\n" );
482
483 return( 1 );
484 }
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000485 ret = mbedtls_cmac_verify( &ctx, M, Mlen[i], T[i], 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000486 if( ret != 0 )
487 {
488 if( verbose != 0 )
489 mbedtls_printf( "failed\n" );
490
491 return( 1 );
492 }
493
494 if( verbose != 0 )
495 mbedtls_printf( "passed\n" );
496 }
497
498 for( i = 0; i < NB_PRF_TESTS; i++ )
499 {
500 mbedtls_printf( " AES-CMAC-128-PRF #%u: ", i );
501
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000502 mbedtls_aes_cmac_prf_128( &ctx, PRFK, PRFKlen[i], PRFM, 20, tag);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000503
504 if( ret != 0 ||
505 memcmp( tag, PRFT[i], 16 ) != 0 )
506 {
507 if( verbose != 0 )
508 mbedtls_printf( "failed\n" );
509
510 return( 1 );
511 }
512
513 if( verbose != 0 )
514 mbedtls_printf( "passed\n" );
515 }
516
517 mbedtls_cmac_free( &ctx );
518
519 if( verbose != 0 )
520 mbedtls_printf( "\n" );
521
522 return( 0 );
523}
524
525#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
526
527#endif /* MBEDTLS_CMAC_C */