blob: 1287c820a71e40c9367fbb0e6ff5c0c44aebd79d [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
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000190/*
191 * Create padded last block from (partial) last block.
192 *
193 * We can't use the padding option from the cipher layer, as it only works for
194 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
195 */
196static void padding( unsigned char padded_block[16],
197 const unsigned char *last_block,
198 size_t length )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000199{
200 size_t j;
201
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000202 for( j = 0; j < 16; j++ )
203 {
204 if( j < length )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000205 padded_block[j] = last_block[j];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000206 else if( j == length )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000207 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000208 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000209 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000210 }
211}
212
213/*
214 * Generate tag on complete message
215 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000216static int cmac_generate( mbedtls_cmac_context *ctx,
217 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000218 unsigned char *tag, size_t tag_len )
219{
220 unsigned char Mn[16];
221 unsigned char M_last[16];
222 unsigned char padded[16];
223 int n, i, j, ret, flag;
224 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é-Gonnard690083c2016-01-13 10:48:02 +0000233 n = ( in_len + 15 ) / 16; /* n is number of rounds */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000234
235 if( n == 0 )
236 {
237 n = 1;
238 flag = 0;
239 }
240 else
241 {
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000242 flag = ( ( in_len % 16 ) == 0);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000243 }
244
245 /* Calculate last block */
246 if( flag )
247 {
248 /* Last block is complete block */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000249 XOR_128( &input[16 * ( n - 1 )], ctx->K1, M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000250 }
251 else
252 {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000253 padding( padded, &input[16 * ( n - 1 )], in_len % 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000254 XOR_128( padded, ctx->K2, M_last );
255 }
256
257 memset( Mn, 0, 16 );
258
259 for( j = 0; j < n - 1; j++ )
260 {
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000261 UPDATE_CMAC( &input[16 * j] );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000262 }
263
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000264 UPDATE_CMAC( M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000265
266 memcpy( tag, Mn, 16 );
267
268 return( 0 );
269}
270
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000271int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
272 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000273 unsigned char *tag, size_t tag_len )
274{
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000275 return( cmac_generate( ctx, input, in_len, tag, tag_len ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000276}
277
278/*
279 * Authenticated decryption
280 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000281int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
282 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000283 const unsigned char *tag, size_t tag_len )
284{
285 int ret;
286 unsigned char check_tag[16];
287 unsigned char i;
288 int diff;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000289
290 if( ( ret = cmac_generate( ctx, input, in_len, check_tag, tag_len ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000291 {
292 return ret;
293 }
294
295 /* Check tag in "constant-time" */
296 for( diff = 0, i = 0; i < tag_len; i++ )
297 {
298 diff |= tag[i] ^ check_tag[i];
299 }
300
301 if( diff != 0 )
302 {
303 return( MBEDTLS_ERR_CMAC_VERIFY_FAILED );
304 }
305
306 return( 0 );
307}
308
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000309int mbedtls_aes_cmac_prf_128( mbedtls_cmac_context *ctx,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000310 const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000311 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000312 unsigned char *tag )
313{
314 int ret;
315 unsigned char zero_key[16];
316 unsigned char int_key[16];
317
318 if( key_length == 16 )
319 {
320 /* Use key as is */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000321 memcpy( int_key, key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000322 }
323 else
324 {
325 mbedtls_cmac_context zero_ctx;
326
327 /* Key is AES_CMAC(0, key) */
328 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000329 memset( zero_key, 0, 16 );
330 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
331 zero_key, 8 * sizeof zero_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000332 if( ret != 0 )
333 {
334 return( ret );
335 }
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000336 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000337 if( ret != 0 )
338 {
339 return( ret );
340 }
341 }
342
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000343 ret = mbedtls_cmac_setkey( ctx, MBEDTLS_CIPHER_ID_AES,
344 int_key, 8 * sizeof int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000345 if( ret != 0 )
346 {
347 return( ret );
348 }
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000349
350 mbedtls_zeroize( int_key, sizeof( int_key ) );
351
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000352 return( mbedtls_cmac_generate( ctx, input, in_len, tag, 16 ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000353}
354
355#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
356/*
357 * Examples 1 to 4 from SP800-3B corrected Appendix D.1
358 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
359 */
360
361#define NB_CMAC_TESTS 4
362#define NB_PRF_TESTS 3
363
364/* Key */
365static const unsigned char key[] = {
366 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
367 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
368};
369
370/* Assume we don't need to test Ek0 as this is a function of the cipher */
371
372/* Subkey K1 */
373static const unsigned char K1[] = {
374 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
375 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
376};
377
378/* Subkey K2 */
379static const unsigned char K2[] = {
380 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
381 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
382};
383
384/* All Messages */
385static const unsigned char M[] = {
386 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
387 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
388 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
389 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
390 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
391 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
392 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
393 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
394};
395
396static const unsigned char T[NB_CMAC_TESTS][16] = {
397 {
398 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
399 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
400 },
401 {
402 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
403 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
404 },
405 {
406 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
407 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
408 },
409 {
410 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
411 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
412 }
413};
414
415/* Sizes in bytes */
416static const size_t Mlen[NB_CMAC_TESTS] = {
417 0,
418 16,
419 40,
420 64
421};
422
423/* PRF K */
424static const unsigned char PRFK[] = {
425 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
426 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
427 0xed, 0xcb
428};
429
430/* Sizes in bytes */
431static const size_t PRFKlen[NB_PRF_TESTS] = {
432 18,
433 16,
434 10
435};
436
437/* PRF M */
438static const unsigned char PRFM[] = {
439 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
440 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000441 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000442};
443
444static const unsigned char PRFT[NB_PRF_TESTS][16] = {
445 {
446 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
447 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
448 },
449 {
450 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
451 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
452 },
453 {
454 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
455 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
456 }
457};
458
459
460int mbedtls_cmac_self_test( int verbose )
461{
462 mbedtls_cmac_context ctx;
463 unsigned char tag[16];
464 int i;
465 int ret;
466
467 mbedtls_cmac_init( &ctx );
468
469 if( mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
470 {
471 if( verbose != 0 )
472 mbedtls_printf( " CMAC: setup failed" );
473
474 return( 1 );
475 }
476
477 if( ( memcmp( ctx.K1, K1, 16 ) != 0 ) ||
478 ( memcmp( ctx.K2, K2, 16 ) != 0 ) )
479 {
480 if( verbose != 0 )
481 mbedtls_printf( " CMAC: subkey generation failed" );
482
483 return( 1 );
484 }
485
486 for( i = 0; i < NB_CMAC_TESTS; i++ )
487 {
488 mbedtls_printf( " AES-128-CMAC #%u: ", i );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000489
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000490 ret = mbedtls_cmac_generate( &ctx, M, Mlen[i], tag, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000491 if( ret != 0 ||
492 memcmp( tag, T[i], 16 ) != 0 )
493 {
494 if( verbose != 0 )
495 mbedtls_printf( "failed\n" );
496
497 return( 1 );
498 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000499
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000500 ret = mbedtls_cmac_verify( &ctx, M, Mlen[i], T[i], 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000501 if( ret != 0 )
502 {
503 if( verbose != 0 )
504 mbedtls_printf( "failed\n" );
505
506 return( 1 );
507 }
508
509 if( verbose != 0 )
510 mbedtls_printf( "passed\n" );
511 }
512
513 for( i = 0; i < NB_PRF_TESTS; i++ )
514 {
515 mbedtls_printf( " AES-CMAC-128-PRF #%u: ", i );
516
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000517 mbedtls_aes_cmac_prf_128( &ctx, PRFK, PRFKlen[i], PRFM, 20, tag );
518
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000519 if( ret != 0 ||
520 memcmp( tag, PRFT[i], 16 ) != 0 )
521 {
522 if( verbose != 0 )
523 mbedtls_printf( "failed\n" );
524
525 return( 1 );
526 }
527
528 if( verbose != 0 )
529 mbedtls_printf( "passed\n" );
530 }
531
532 mbedtls_cmac_free( &ctx );
533
534 if( verbose != 0 )
535 mbedtls_printf( "\n" );
536
537 return( 0 );
538}
539
540#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
541
542#endif /* MBEDTLS_CMAC_C */