blob: d9e94a6fc0bd661f750f9dd356a4976ed523b959 [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 */
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +000057#define XOR_128( o, i1, i2 ) \
Robert Cragie3d23b1d2015-12-15 07:38:11 +000058 for( i = 0; i < 16; i++ ) \
59 ( o )[i] = ( i1 )[i] ^ ( i2 )[i];
60
61/*
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +000062 * Update the CMAC state using an input block x
Robert Cragie3d23b1d2015-12-15 07:38:11 +000063 */
64#define UPDATE_CMAC( x ) \
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +000065do { \
66 XOR_128( state, ( x ), state ); \
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000067 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, \
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +000068 state, 16, state, &olen ) ) != 0 ) \
69 return( ret ); \
70} while( 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000071
72/* Implementation that should never be optimized out by the compiler */
73static void mbedtls_zeroize( void *v, size_t n ) {
74 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
75}
76
77/*
78 * Initialize context
79 */
80void mbedtls_cmac_init( mbedtls_cmac_context *ctx )
81{
82 memset( ctx, 0, sizeof( mbedtls_cmac_context ) );
83}
84
85/*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000086 * Multiply by u in GF(2^128)
87 *
88 * As explained in the paper, this can be achieved as
89 * If MSB(p) = 0, then p = (p << 1)
90 * If MSB(p) = 1, then p = (p << 1) ^ Rb
91 * with Rb = 0x87
92 *
93 * Input and output MUST not point to the same buffer
Robert Cragie3d23b1d2015-12-15 07:38:11 +000094 */
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000095static void multiply_by_u( unsigned char *output, const unsigned char *input )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000096{
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000097 const unsigned char Rb = 0x87; /* block size 16 only */
98 unsigned char mask;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000099 unsigned char overflow = 0;
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000100 int i;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000101
102 for( i = 15; i >= 0; i-- )
103 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000104 output[i] = input[i] << 1 | overflow;
105 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000106 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000107
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000108 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
109 * using bit operations to avoid branches */
110 /* MSVC has a warning about unary minus on unsigned, but this is
111 * well-defined and precisely what we want to do here */
112#if defined(_MSC_VER)
113#pragma warning( push )
114#pragma warning( disable : 4146 )
115#endif
116 mask = - ( input[0] >> 7 );
117#if defined(_MSC_VER)
118#pragma warning( pop )
119#endif
120
121 output[15] ^= Rb & mask;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000122}
123
124/*
125 * Generate subkeys
126 */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000127static int generate_subkeys( mbedtls_cmac_context *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000128{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000129 int ret;
130 unsigned char L[16];
131 size_t olen;
132
133 /* Calculate Ek(0) */
134 memset( L, 0, 16 );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000135 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx,
136 L, 16, L, &olen ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000137 {
138 return( ret );
139 }
140
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000141 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000142 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000143 */
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000144 multiply_by_u( ctx->K1, L );
145 multiply_by_u( ctx->K2, ctx->K1 );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000146
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000147 mbedtls_zeroize( L, sizeof( L ) );
148
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000149 return( 0 );
150}
151
152int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx,
153 mbedtls_cipher_id_t cipher,
154 const unsigned char *key,
155 unsigned int keybits )
156{
157 int ret;
158 const mbedtls_cipher_info_t *cipher_info;
159
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000160 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
161 MBEDTLS_MODE_ECB );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000162 if( cipher_info == NULL )
163 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
164
165 if( cipher_info->block_size != 16 )
166 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
167
168 mbedtls_cipher_free( &ctx->cipher_ctx );
169
170 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
171 return( ret );
172
173 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000174 MBEDTLS_ENCRYPT ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000175 {
176 return( ret );
177 }
178
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000179 return( generate_subkeys( ctx ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000180}
181
182/*
183 * Free context
184 */
185void mbedtls_cmac_free( mbedtls_cmac_context *ctx )
186{
187 mbedtls_cipher_free( &ctx->cipher_ctx );
188 mbedtls_zeroize( ctx, sizeof( mbedtls_cmac_context ) );
189}
190
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000191/*
192 * Create padded last block from (partial) last block.
193 *
194 * We can't use the padding option from the cipher layer, as it only works for
195 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
196 */
197static void padding( unsigned char padded_block[16],
198 const unsigned char *last_block,
199 size_t length )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000200{
201 size_t j;
202
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000203 for( j = 0; j < 16; j++ )
204 {
205 if( j < length )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000206 padded_block[j] = last_block[j];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000207 else if( j == length )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000208 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000209 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000210 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000211 }
212}
213
214/*
215 * Generate tag on complete message
216 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000217static int cmac_generate( mbedtls_cmac_context *ctx,
218 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000219 unsigned char *tag, size_t tag_len )
220{
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000221 unsigned char state[16];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000222 unsigned char M_last[16];
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000223 int n, i, j, ret, needs_padding;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000224 size_t olen;
225
226 /*
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000227 * Check in_len requirements: SP800-38B A
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000228 * 4 is a worst case bottom limit
229 */
230 if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
231 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
232
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000233 if( in_len == 0 )
234 needs_padding = 1;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000235 else
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000236 needs_padding = in_len % 16 != 0;
237
238 n = in_len / 16 + needs_padding;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000239
240 /* Calculate last block */
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000241 if( needs_padding )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000242 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000243 padding( M_last, input + 16 * ( n - 1 ), in_len % 16 );
244 XOR_128( M_last, M_last, ctx->K2 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000245 }
246 else
247 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000248 /* Last block is complete block */
249 XOR_128( M_last, input + 16 * ( n - 1 ), ctx->K1 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000250 }
251
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000252 memset( state, 0, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000253
254 for( j = 0; j < n - 1; j++ )
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000255 UPDATE_CMAC( input + 16 * j );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000256
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000257 UPDATE_CMAC( M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000258
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000259 memcpy( tag, state, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000260
261 return( 0 );
262}
263
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000264int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
265 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000266 unsigned char *tag, size_t tag_len )
267{
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000268 return( cmac_generate( ctx, input, in_len, tag, tag_len ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000269}
270
271/*
272 * Authenticated decryption
273 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000274int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
275 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000276 const unsigned char *tag, size_t tag_len )
277{
278 int ret;
279 unsigned char check_tag[16];
280 unsigned char i;
281 int diff;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000282
283 if( ( ret = cmac_generate( ctx, input, in_len, check_tag, tag_len ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000284 {
285 return ret;
286 }
287
288 /* Check tag in "constant-time" */
289 for( diff = 0, i = 0; i < tag_len; i++ )
290 {
291 diff |= tag[i] ^ check_tag[i];
292 }
293
294 if( diff != 0 )
295 {
296 return( MBEDTLS_ERR_CMAC_VERIFY_FAILED );
297 }
298
299 return( 0 );
300}
301
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000302int mbedtls_aes_cmac_prf_128( mbedtls_cmac_context *ctx,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000303 const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000304 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000305 unsigned char *tag )
306{
307 int ret;
308 unsigned char zero_key[16];
309 unsigned char int_key[16];
310
311 if( key_length == 16 )
312 {
313 /* Use key as is */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000314 memcpy( int_key, key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000315 }
316 else
317 {
318 mbedtls_cmac_context zero_ctx;
319
320 /* Key is AES_CMAC(0, key) */
321 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000322 memset( zero_key, 0, 16 );
323 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
324 zero_key, 8 * sizeof zero_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000325 if( ret != 0 )
326 {
327 return( ret );
328 }
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000329 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000330 if( ret != 0 )
331 {
332 return( ret );
333 }
334 }
335
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000336 ret = mbedtls_cmac_setkey( ctx, MBEDTLS_CIPHER_ID_AES,
337 int_key, 8 * sizeof int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000338 if( ret != 0 )
339 {
340 return( ret );
341 }
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000342
343 mbedtls_zeroize( int_key, sizeof( int_key ) );
344
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000345 return( mbedtls_cmac_generate( ctx, input, in_len, tag, 16 ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000346}
347
348#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
349/*
350 * Examples 1 to 4 from SP800-3B corrected Appendix D.1
351 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
352 */
353
354#define NB_CMAC_TESTS 4
355#define NB_PRF_TESTS 3
356
357/* Key */
358static const unsigned char key[] = {
359 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
360 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
361};
362
363/* Assume we don't need to test Ek0 as this is a function of the cipher */
364
365/* Subkey K1 */
366static const unsigned char K1[] = {
367 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
368 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
369};
370
371/* Subkey K2 */
372static const unsigned char K2[] = {
373 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
374 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
375};
376
377/* All Messages */
378static const unsigned char M[] = {
379 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
380 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
381 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
382 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
383 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
384 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
385 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
386 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
387};
388
389static const unsigned char T[NB_CMAC_TESTS][16] = {
390 {
391 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
392 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
393 },
394 {
395 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
396 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
397 },
398 {
399 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
400 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
401 },
402 {
403 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
404 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
405 }
406};
407
408/* Sizes in bytes */
409static const size_t Mlen[NB_CMAC_TESTS] = {
410 0,
411 16,
412 40,
413 64
414};
415
416/* PRF K */
417static const unsigned char PRFK[] = {
418 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
419 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
420 0xed, 0xcb
421};
422
423/* Sizes in bytes */
424static const size_t PRFKlen[NB_PRF_TESTS] = {
425 18,
426 16,
427 10
428};
429
430/* PRF M */
431static const unsigned char PRFM[] = {
432 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
433 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000434 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000435};
436
437static const unsigned char PRFT[NB_PRF_TESTS][16] = {
438 {
439 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
440 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
441 },
442 {
443 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
444 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
445 },
446 {
447 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
448 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
449 }
450};
451
452
453int mbedtls_cmac_self_test( int verbose )
454{
455 mbedtls_cmac_context ctx;
456 unsigned char tag[16];
457 int i;
458 int ret;
459
460 mbedtls_cmac_init( &ctx );
461
462 if( mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
463 {
464 if( verbose != 0 )
465 mbedtls_printf( " CMAC: setup failed" );
466
467 return( 1 );
468 }
469
470 if( ( memcmp( ctx.K1, K1, 16 ) != 0 ) ||
471 ( memcmp( ctx.K2, K2, 16 ) != 0 ) )
472 {
473 if( verbose != 0 )
474 mbedtls_printf( " CMAC: subkey generation failed" );
475
476 return( 1 );
477 }
478
479 for( i = 0; i < NB_CMAC_TESTS; i++ )
480 {
481 mbedtls_printf( " AES-128-CMAC #%u: ", i );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000482
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000483 ret = mbedtls_cmac_generate( &ctx, M, Mlen[i], tag, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000484 if( ret != 0 ||
485 memcmp( tag, T[i], 16 ) != 0 )
486 {
487 if( verbose != 0 )
488 mbedtls_printf( "failed\n" );
489
490 return( 1 );
491 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000492
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000493 ret = mbedtls_cmac_verify( &ctx, M, Mlen[i], T[i], 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000494 if( ret != 0 )
495 {
496 if( verbose != 0 )
497 mbedtls_printf( "failed\n" );
498
499 return( 1 );
500 }
501
502 if( verbose != 0 )
503 mbedtls_printf( "passed\n" );
504 }
505
506 for( i = 0; i < NB_PRF_TESTS; i++ )
507 {
508 mbedtls_printf( " AES-CMAC-128-PRF #%u: ", i );
509
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000510 mbedtls_aes_cmac_prf_128( &ctx, PRFK, PRFKlen[i], PRFM, 20, tag );
511
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000512 if( ret != 0 ||
513 memcmp( tag, PRFT[i], 16 ) != 0 )
514 {
515 if( verbose != 0 )
516 mbedtls_printf( "failed\n" );
517
518 return( 1 );
519 }
520
521 if( verbose != 0 )
522 mbedtls_printf( "passed\n" );
523 }
524
525 mbedtls_cmac_free( &ctx );
526
527 if( verbose != 0 )
528 mbedtls_printf( "\n" );
529
530 return( 0 );
531}
532
533#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
534
535#endif /* MBEDTLS_CMAC_C */