blob: af0439a430eb8e3305174fcb58a5251d7c576a91 [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é-Gonnard3da54022016-01-13 11:00:47 +000057#define XOR_128( i1, i2, o ) \
Robert Cragie3d23b1d2015-12-15 07:38:11 +000058 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 ); \
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000067 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, \
68 Mn, 16, Mn, &olen ) ) != 0 ) \
Robert Cragie3d23b1d2015-12-15 07:38:11 +000069 return( ret );
70
71/* Implementation that should never be optimized out by the compiler */
72static void mbedtls_zeroize( void *v, size_t n ) {
73 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
74}
75
76/*
77 * Initialize context
78 */
79void mbedtls_cmac_init( mbedtls_cmac_context *ctx )
80{
81 memset( ctx, 0, sizeof( mbedtls_cmac_context ) );
82}
83
84/*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000085 * Multiply by u in GF(2^128)
86 *
87 * As explained in the paper, this can be achieved as
88 * If MSB(p) = 0, then p = (p << 1)
89 * If MSB(p) = 1, then p = (p << 1) ^ Rb
90 * with Rb = 0x87
91 *
92 * Input and output MUST not point to the same buffer
Robert Cragie3d23b1d2015-12-15 07:38:11 +000093 */
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000094static void multiply_by_u( unsigned char *output, const unsigned char *input )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000095{
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000096 const unsigned char Rb = 0x87; /* block size 16 only */
97 unsigned char mask;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000098 unsigned char overflow = 0;
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000099 int i;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000100
101 for( i = 15; i >= 0; i-- )
102 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000103 output[i] = input[i] << 1 | overflow;
104 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000105 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000106
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000107 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
108 * using bit operations to avoid branches */
109 /* MSVC has a warning about unary minus on unsigned, but this is
110 * well-defined and precisely what we want to do here */
111#if defined(_MSC_VER)
112#pragma warning( push )
113#pragma warning( disable : 4146 )
114#endif
115 mask = - ( input[0] >> 7 );
116#if defined(_MSC_VER)
117#pragma warning( pop )
118#endif
119
120 output[15] ^= Rb & mask;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000121}
122
123/*
124 * Generate subkeys
125 */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000126static int generate_subkeys( mbedtls_cmac_context *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000127{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000128 int ret;
129 unsigned char L[16];
130 size_t olen;
131
132 /* Calculate Ek(0) */
133 memset( L, 0, 16 );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000134 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx,
135 L, 16, L, &olen ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000136 {
137 return( ret );
138 }
139
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000140 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000141 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000142 */
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000143 multiply_by_u( ctx->K1, L );
144 multiply_by_u( ctx->K2, ctx->K1 );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000145
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000146 mbedtls_zeroize( L, sizeof( L ) );
147
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000148 return( 0 );
149}
150
151int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx,
152 mbedtls_cipher_id_t cipher,
153 const unsigned char *key,
154 unsigned int keybits )
155{
156 int ret;
157 const mbedtls_cipher_info_t *cipher_info;
158
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000159 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
160 MBEDTLS_MODE_ECB );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000161 if( cipher_info == NULL )
162 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
163
164 if( cipher_info->block_size != 16 )
165 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
166
167 mbedtls_cipher_free( &ctx->cipher_ctx );
168
169 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
170 return( ret );
171
172 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000173 MBEDTLS_ENCRYPT ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000174 {
175 return( ret );
176 }
177
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000178 return( generate_subkeys( ctx ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000179}
180
181/*
182 * Free context
183 */
184void mbedtls_cmac_free( mbedtls_cmac_context *ctx )
185{
186 mbedtls_cipher_free( &ctx->cipher_ctx );
187 mbedtls_zeroize( ctx, sizeof( mbedtls_cmac_context ) );
188}
189
190/* TODO: Use cipher padding function? */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000191static void padding( const unsigned char *lastb,
192 unsigned char *pad,
193 const size_t length )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000194{
195 size_t j;
196
197 /* original last block */
198 for( j = 0; j < 16; j++ )
199 {
200 if( j < length )
201 {
202 pad[j] = lastb[j];
203 }
204 else if( j == length )
205 {
206 pad[j] = 0x80;
207 }
208 else
209 {
210 pad[j] = 0x00;
211 }
212 }
213}
214
215/*
216 * Generate tag on complete message
217 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000218static int cmac_generate( mbedtls_cmac_context *ctx,
219 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000220 unsigned char *tag, size_t tag_len )
221{
222 unsigned char Mn[16];
223 unsigned char M_last[16];
224 unsigned char padded[16];
225 int n, i, j, ret, flag;
226 size_t olen;
227
228 /*
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000229 * Check in_len requirements: SP800-38B A
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000230 * 4 is a worst case bottom limit
231 */
232 if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
233 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
234
235 /* TODO: Use cipher padding function? */
236 // mbedtls_cipher_set_padding_mode( ctx->cipher, MBEDTLS_PADDING_ONE_AND_ZEROS );
237
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000238 n = ( in_len + 15 ) / 16; /* n is number of rounds */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000239
240 if( n == 0 )
241 {
242 n = 1;
243 flag = 0;
244 }
245 else
246 {
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000247 flag = ( ( in_len % 16 ) == 0);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000248 }
249
250 /* Calculate last block */
251 if( flag )
252 {
253 /* Last block is complete block */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000254 XOR_128( &input[16 * ( n - 1 )], ctx->K1, M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000255 }
256 else
257 {
258 /* TODO: Use cipher padding function? */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000259 padding( &input[16 * ( n - 1 )], padded, in_len % 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000260 XOR_128( padded, ctx->K2, M_last );
261 }
262
263 memset( Mn, 0, 16 );
264
265 for( j = 0; j < n - 1; j++ )
266 {
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000267 UPDATE_CMAC( &input[16 * j] );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000268 }
269
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000270 UPDATE_CMAC( M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000271
272 memcpy( tag, Mn, 16 );
273
274 return( 0 );
275}
276
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000277int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
278 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000279 unsigned char *tag, size_t tag_len )
280{
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000281 return( cmac_generate( ctx, input, in_len, tag, tag_len ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000282}
283
284/*
285 * Authenticated decryption
286 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000287int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
288 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000289 const unsigned char *tag, size_t tag_len )
290{
291 int ret;
292 unsigned char check_tag[16];
293 unsigned char i;
294 int diff;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000295
296 if( ( ret = cmac_generate( ctx, input, in_len, check_tag, tag_len ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000297 {
298 return ret;
299 }
300
301 /* Check tag in "constant-time" */
302 for( diff = 0, i = 0; i < tag_len; i++ )
303 {
304 diff |= tag[i] ^ check_tag[i];
305 }
306
307 if( diff != 0 )
308 {
309 return( MBEDTLS_ERR_CMAC_VERIFY_FAILED );
310 }
311
312 return( 0 );
313}
314
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000315int mbedtls_aes_cmac_prf_128( mbedtls_cmac_context *ctx,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000316 const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000317 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000318 unsigned char *tag )
319{
320 int ret;
321 unsigned char zero_key[16];
322 unsigned char int_key[16];
323
324 if( key_length == 16 )
325 {
326 /* Use key as is */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000327 memcpy( int_key, key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000328 }
329 else
330 {
331 mbedtls_cmac_context zero_ctx;
332
333 /* Key is AES_CMAC(0, key) */
334 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000335 memset( zero_key, 0, 16 );
336 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
337 zero_key, 8 * sizeof zero_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000338 if( ret != 0 )
339 {
340 return( ret );
341 }
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000342 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000343 if( ret != 0 )
344 {
345 return( ret );
346 }
347 }
348
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000349 ret = mbedtls_cmac_setkey( ctx, MBEDTLS_CIPHER_ID_AES,
350 int_key, 8 * sizeof int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000351 if( ret != 0 )
352 {
353 return( ret );
354 }
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000355
356 mbedtls_zeroize( int_key, sizeof( int_key ) );
357
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000358 return( mbedtls_cmac_generate( ctx, input, in_len, tag, 16 ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000359}
360
361#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
362/*
363 * Examples 1 to 4 from SP800-3B corrected Appendix D.1
364 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
365 */
366
367#define NB_CMAC_TESTS 4
368#define NB_PRF_TESTS 3
369
370/* Key */
371static const unsigned char key[] = {
372 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
373 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
374};
375
376/* Assume we don't need to test Ek0 as this is a function of the cipher */
377
378/* Subkey K1 */
379static const unsigned char K1[] = {
380 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
381 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
382};
383
384/* Subkey K2 */
385static const unsigned char K2[] = {
386 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
387 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
388};
389
390/* All Messages */
391static const unsigned char M[] = {
392 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
393 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
394 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
395 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
396 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
397 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
398 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
399 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
400};
401
402static const unsigned char T[NB_CMAC_TESTS][16] = {
403 {
404 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
405 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
406 },
407 {
408 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
409 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
410 },
411 {
412 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
413 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
414 },
415 {
416 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
417 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
418 }
419};
420
421/* Sizes in bytes */
422static const size_t Mlen[NB_CMAC_TESTS] = {
423 0,
424 16,
425 40,
426 64
427};
428
429/* PRF K */
430static const unsigned char PRFK[] = {
431 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
432 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
433 0xed, 0xcb
434};
435
436/* Sizes in bytes */
437static const size_t PRFKlen[NB_PRF_TESTS] = {
438 18,
439 16,
440 10
441};
442
443/* PRF M */
444static const unsigned char PRFM[] = {
445 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
446 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000447 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000448};
449
450static const unsigned char PRFT[NB_PRF_TESTS][16] = {
451 {
452 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
453 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
454 },
455 {
456 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
457 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
458 },
459 {
460 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
461 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
462 }
463};
464
465
466int mbedtls_cmac_self_test( int verbose )
467{
468 mbedtls_cmac_context ctx;
469 unsigned char tag[16];
470 int i;
471 int ret;
472
473 mbedtls_cmac_init( &ctx );
474
475 if( mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
476 {
477 if( verbose != 0 )
478 mbedtls_printf( " CMAC: setup failed" );
479
480 return( 1 );
481 }
482
483 if( ( memcmp( ctx.K1, K1, 16 ) != 0 ) ||
484 ( memcmp( ctx.K2, K2, 16 ) != 0 ) )
485 {
486 if( verbose != 0 )
487 mbedtls_printf( " CMAC: subkey generation failed" );
488
489 return( 1 );
490 }
491
492 for( i = 0; i < NB_CMAC_TESTS; i++ )
493 {
494 mbedtls_printf( " AES-128-CMAC #%u: ", i );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000495
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000496 ret = mbedtls_cmac_generate( &ctx, M, Mlen[i], tag, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000497 if( ret != 0 ||
498 memcmp( tag, T[i], 16 ) != 0 )
499 {
500 if( verbose != 0 )
501 mbedtls_printf( "failed\n" );
502
503 return( 1 );
504 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000505
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000506 ret = mbedtls_cmac_verify( &ctx, M, Mlen[i], T[i], 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000507 if( ret != 0 )
508 {
509 if( verbose != 0 )
510 mbedtls_printf( "failed\n" );
511
512 return( 1 );
513 }
514
515 if( verbose != 0 )
516 mbedtls_printf( "passed\n" );
517 }
518
519 for( i = 0; i < NB_PRF_TESTS; i++ )
520 {
521 mbedtls_printf( " AES-CMAC-128-PRF #%u: ", i );
522
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000523 mbedtls_aes_cmac_prf_128( &ctx, PRFK, PRFKlen[i], PRFM, 20, tag );
524
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000525 if( ret != 0 ||
526 memcmp( tag, PRFT[i], 16 ) != 0 )
527 {
528 if( verbose != 0 )
529 mbedtls_printf( "failed\n" );
530
531 return( 1 );
532 }
533
534 if( verbose != 0 )
535 mbedtls_printf( "passed\n" );
536 }
537
538 mbedtls_cmac_free( &ctx );
539
540 if( verbose != 0 )
541 mbedtls_printf( "\n" );
542
543 return( 0 );
544}
545
546#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
547
548#endif /* MBEDTLS_CMAC_C */