blob: ff7cb2109e8c41984e509021eb228b16e7b3e583 [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
Robert Cragie3d23b1d2015-12-15 07:38:11 +000049/* Implementation that should never be optimized out by the compiler */
50static void mbedtls_zeroize( void *v, size_t n ) {
51 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
52}
53
54/*
55 * Initialize context
56 */
57void mbedtls_cmac_init( mbedtls_cmac_context *ctx )
58{
59 memset( ctx, 0, sizeof( mbedtls_cmac_context ) );
60}
61
62/*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000063 * Multiply by u in GF(2^128)
64 *
65 * As explained in the paper, this can be achieved as
66 * If MSB(p) = 0, then p = (p << 1)
67 * If MSB(p) = 1, then p = (p << 1) ^ Rb
68 * with Rb = 0x87
69 *
70 * Input and output MUST not point to the same buffer
Robert Cragie3d23b1d2015-12-15 07:38:11 +000071 */
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000072static void multiply_by_u( unsigned char *output, const unsigned char *input )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000073{
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000074 const unsigned char Rb = 0x87; /* block size 16 only */
75 unsigned char mask;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000076 unsigned char overflow = 0;
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000077 int i;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000078
79 for( i = 15; i >= 0; i-- )
80 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000081 output[i] = input[i] << 1 | overflow;
82 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000083 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000084
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000085 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
86 * using bit operations to avoid branches */
87 /* MSVC has a warning about unary minus on unsigned, but this is
88 * well-defined and precisely what we want to do here */
89#if defined(_MSC_VER)
90#pragma warning( push )
91#pragma warning( disable : 4146 )
92#endif
93 mask = - ( input[0] >> 7 );
94#if defined(_MSC_VER)
95#pragma warning( pop )
96#endif
97
98 output[15] ^= Rb & mask;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000099}
100
101/*
102 * Generate subkeys
103 */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000104static int generate_subkeys( mbedtls_cmac_context *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000105{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000106 int ret;
107 unsigned char L[16];
108 size_t olen;
109
110 /* Calculate Ek(0) */
111 memset( L, 0, 16 );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000112 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx,
113 L, 16, L, &olen ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000114 {
115 return( ret );
116 }
117
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000118 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000119 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000120 */
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000121 multiply_by_u( ctx->K1, L );
122 multiply_by_u( ctx->K2, ctx->K1 );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000123
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000124 mbedtls_zeroize( L, sizeof( L ) );
125
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000126 return( 0 );
127}
128
129int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx,
130 mbedtls_cipher_id_t cipher,
131 const unsigned char *key,
132 unsigned int keybits )
133{
134 int ret;
135 const mbedtls_cipher_info_t *cipher_info;
136
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000137 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
138 MBEDTLS_MODE_ECB );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000139 if( cipher_info == NULL )
140 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
141
142 if( cipher_info->block_size != 16 )
143 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
144
145 mbedtls_cipher_free( &ctx->cipher_ctx );
146
147 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
148 return( ret );
149
150 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000151 MBEDTLS_ENCRYPT ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000152 {
153 return( ret );
154 }
155
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000156 return( generate_subkeys( ctx ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000157}
158
159/*
160 * Free context
161 */
162void mbedtls_cmac_free( mbedtls_cmac_context *ctx )
163{
164 mbedtls_cipher_free( &ctx->cipher_ctx );
165 mbedtls_zeroize( ctx, sizeof( mbedtls_cmac_context ) );
166}
167
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000168/*
169 * Create padded last block from (partial) last block.
170 *
171 * We can't use the padding option from the cipher layer, as it only works for
172 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
173 */
174static void padding( unsigned char padded_block[16],
175 const unsigned char *last_block,
176 size_t length )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000177{
178 size_t j;
179
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000180 for( j = 0; j < 16; j++ )
181 {
182 if( j < length )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000183 padded_block[j] = last_block[j];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000184 else if( j == length )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000185 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000186 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000187 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000188 }
189}
190
191/*
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000192 * XOR 128-bit
193 * Here, macro results in smaller compiled code than static inline function
194 */
195#define XOR_128( o, i1, i2 ) \
196 for( i = 0; i < 16; i++ ) \
197 ( o )[i] = ( i1 )[i] ^ ( i2 )[i];
198
199/*
200 * Update the CMAC state using an input block x
201 */
202#define UPDATE_CMAC( x ) \
203do { \
204 XOR_128( state, ( x ), state ); \
205 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, \
206 state, 16, state, &olen ) ) != 0 ) \
207 return( ret ); \
208} while( 0 )
209
210/*
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000211 * Generate tag on complete message
212 */
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000213int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
214 const unsigned char *input, size_t in_len,
215 unsigned char *tag, size_t tag_len )
216
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000217{
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000218 unsigned char state[16];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000219 unsigned char M_last[16];
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000220 int n, i, j, ret, needs_padding;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000221 size_t olen;
222
223 /*
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000224 * Check in_len requirements: SP800-38B A
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000225 * 4 is a worst case bottom limit
226 */
227 if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
228 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
229
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000230 if( in_len == 0 )
231 needs_padding = 1;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000232 else
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000233 needs_padding = in_len % 16 != 0;
234
235 n = in_len / 16 + needs_padding;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000236
237 /* Calculate last block */
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000238 if( needs_padding )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000239 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000240 padding( M_last, input + 16 * ( n - 1 ), in_len % 16 );
241 XOR_128( M_last, M_last, ctx->K2 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000242 }
243 else
244 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000245 /* Last block is complete block */
246 XOR_128( M_last, input + 16 * ( n - 1 ), ctx->K1 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000247 }
248
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000249 memset( state, 0, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000250
251 for( j = 0; j < n - 1; j++ )
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000252 UPDATE_CMAC( input + 16 * j );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000253
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000254 UPDATE_CMAC( M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000255
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000256 memcpy( tag, state, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000257
258 return( 0 );
259}
260
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000261#undef XOR_128
262#undef UPDATE_CMAC
263
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000264/*
265 * Authenticated decryption
266 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000267int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
268 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000269 const unsigned char *tag, size_t tag_len )
270{
271 int ret;
272 unsigned char check_tag[16];
273 unsigned char i;
274 int diff;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000275
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000276 if( ( ret = mbedtls_cmac_generate( ctx, input, in_len,
277 check_tag, tag_len ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000278 {
279 return ret;
280 }
281
282 /* Check tag in "constant-time" */
283 for( diff = 0, i = 0; i < tag_len; i++ )
284 {
285 diff |= tag[i] ^ check_tag[i];
286 }
287
288 if( diff != 0 )
289 {
290 return( MBEDTLS_ERR_CMAC_VERIFY_FAILED );
291 }
292
293 return( 0 );
294}
295
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000296int mbedtls_aes_cmac_prf_128( mbedtls_cmac_context *ctx,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000297 const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000298 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000299 unsigned char *tag )
300{
301 int ret;
302 unsigned char zero_key[16];
303 unsigned char int_key[16];
304
305 if( key_length == 16 )
306 {
307 /* Use key as is */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000308 memcpy( int_key, key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000309 }
310 else
311 {
312 mbedtls_cmac_context zero_ctx;
313
314 /* Key is AES_CMAC(0, key) */
315 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000316 memset( zero_key, 0, 16 );
317 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
318 zero_key, 8 * sizeof zero_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000319 if( ret != 0 )
320 {
321 return( ret );
322 }
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000323 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000324 if( ret != 0 )
325 {
326 return( ret );
327 }
328 }
329
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000330 ret = mbedtls_cmac_setkey( ctx, MBEDTLS_CIPHER_ID_AES,
331 int_key, 8 * sizeof int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000332 if( ret != 0 )
333 {
334 return( ret );
335 }
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000336
337 mbedtls_zeroize( int_key, sizeof( int_key ) );
338
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000339 return( mbedtls_cmac_generate( ctx, input, in_len, tag, 16 ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000340}
341
342#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
343/*
344 * Examples 1 to 4 from SP800-3B corrected Appendix D.1
345 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
346 */
347
348#define NB_CMAC_TESTS 4
349#define NB_PRF_TESTS 3
350
351/* Key */
352static const unsigned char key[] = {
353 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
354 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
355};
356
357/* Assume we don't need to test Ek0 as this is a function of the cipher */
358
359/* Subkey K1 */
360static const unsigned char K1[] = {
361 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
362 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
363};
364
365/* Subkey K2 */
366static const unsigned char K2[] = {
367 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
368 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
369};
370
371/* All Messages */
372static const unsigned char M[] = {
373 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
374 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
375 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
376 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
377 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
378 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
379 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
380 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
381};
382
383static const unsigned char T[NB_CMAC_TESTS][16] = {
384 {
385 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
386 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
387 },
388 {
389 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
390 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
391 },
392 {
393 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
394 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
395 },
396 {
397 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
398 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
399 }
400};
401
402/* Sizes in bytes */
403static const size_t Mlen[NB_CMAC_TESTS] = {
404 0,
405 16,
406 40,
407 64
408};
409
410/* PRF K */
411static const unsigned char PRFK[] = {
412 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
413 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
414 0xed, 0xcb
415};
416
417/* Sizes in bytes */
418static const size_t PRFKlen[NB_PRF_TESTS] = {
419 18,
420 16,
421 10
422};
423
424/* PRF M */
425static const unsigned char PRFM[] = {
426 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
427 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000428 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000429};
430
431static const unsigned char PRFT[NB_PRF_TESTS][16] = {
432 {
433 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
434 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
435 },
436 {
437 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
438 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
439 },
440 {
441 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
442 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
443 }
444};
445
446
447int mbedtls_cmac_self_test( int verbose )
448{
449 mbedtls_cmac_context ctx;
450 unsigned char tag[16];
451 int i;
452 int ret;
453
454 mbedtls_cmac_init( &ctx );
455
456 if( mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
457 {
458 if( verbose != 0 )
459 mbedtls_printf( " CMAC: setup failed" );
460
461 return( 1 );
462 }
463
464 if( ( memcmp( ctx.K1, K1, 16 ) != 0 ) ||
465 ( memcmp( ctx.K2, K2, 16 ) != 0 ) )
466 {
467 if( verbose != 0 )
468 mbedtls_printf( " CMAC: subkey generation failed" );
469
470 return( 1 );
471 }
472
473 for( i = 0; i < NB_CMAC_TESTS; i++ )
474 {
475 mbedtls_printf( " AES-128-CMAC #%u: ", i );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000476
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000477 ret = mbedtls_cmac_generate( &ctx, M, Mlen[i], tag, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000478 if( ret != 0 ||
479 memcmp( tag, T[i], 16 ) != 0 )
480 {
481 if( verbose != 0 )
482 mbedtls_printf( "failed\n" );
483
484 return( 1 );
485 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000486
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000487 ret = mbedtls_cmac_verify( &ctx, M, Mlen[i], T[i], 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000488 if( ret != 0 )
489 {
490 if( verbose != 0 )
491 mbedtls_printf( "failed\n" );
492
493 return( 1 );
494 }
495
496 if( verbose != 0 )
497 mbedtls_printf( "passed\n" );
498 }
499
500 for( i = 0; i < NB_PRF_TESTS; i++ )
501 {
502 mbedtls_printf( " AES-CMAC-128-PRF #%u: ", i );
503
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000504 mbedtls_aes_cmac_prf_128( &ctx, PRFK, PRFKlen[i], PRFM, 20, tag );
505
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000506 if( ret != 0 ||
507 memcmp( tag, PRFT[i], 16 ) != 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 mbedtls_cmac_free( &ctx );
520
521 if( verbose != 0 )
522 mbedtls_printf( "\n" );
523
524 return( 0 );
525}
526
527#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
528
529#endif /* MBEDTLS_CMAC_C */