blob: 3c584049c0d14f1c31f85f8ccad29e73218cc497 [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/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070063 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000064 *
Brian Murray87e40402016-05-19 19:05:57 -070065 * As explained in the paper, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000066 * If MSB(p) = 0, then p = (p << 1)
Brian Murrayb0c3c432016-05-18 14:29:51 -070067 * If MSB(p) = 1, then p = (p << 1) ^ R_n
68 * with R_64 = 0x1B and R_128 = 0x87
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000069 *
70 * Input and output MUST not point to the same buffer
Brian Murrayb0c3c432016-05-18 14:29:51 -070071 * Block size must be 8 byes or 16 bytes.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000072 */
Brian Murrayb0c3c432016-05-18 14:29:51 -070073static int cmac_multiply_by_u( unsigned char *output,
74 const unsigned char *input,
Brian Murrayb439d452016-05-19 16:02:42 -070075 size_t blocksize )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000076{
Brian Murrayb0c3c432016-05-18 14:29:51 -070077 const unsigned char R_128 = 0x87;
78 const unsigned char R_64 = 0x1B;
79 unsigned char R_n, mask;
80 unsigned char overflow = 0x00;
81 int i, starting_index;
82
83 starting_index = blocksize -1;
84
Brian Murray6a3c0d22016-05-20 18:25:43 -070085 if( blocksize == 16 )
86 {
Brian Murrayb0c3c432016-05-18 14:29:51 -070087 R_n = R_128;
Brian Murray6a3c0d22016-05-20 18:25:43 -070088 } else if( blocksize == 8 )
89 {
Brian Murrayb0c3c432016-05-18 14:29:51 -070090 R_n = R_64;
Brian Murray6a3c0d22016-05-20 18:25:43 -070091 } else
92 {
Brian Murrayb439d452016-05-19 16:02:42 -070093 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
Brian Murrayb0c3c432016-05-18 14:29:51 -070094 }
95
Brian Murrayb0c3c432016-05-18 14:29:51 -070096 for( i = starting_index; i >= 0; i-- )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000097 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000098 output[i] = input[i] << 1 | overflow;
99 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000100 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000101
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000102 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
103 * using bit operations to avoid branches */
104 /* MSVC has a warning about unary minus on unsigned, but this is
105 * well-defined and precisely what we want to do here */
106#if defined(_MSC_VER)
107#pragma warning( push )
108#pragma warning( disable : 4146 )
109#endif
110 mask = - ( input[0] >> 7 );
111#if defined(_MSC_VER)
112#pragma warning( pop )
113#endif
114
Brian Murrayb0c3c432016-05-18 14:29:51 -0700115 output[starting_index] ^= R_n & mask;
Brian Murrayb439d452016-05-19 16:02:42 -0700116 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000117}
118
119/*
120 * Generate subkeys
121 */
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000122static int cmac_generate_subkeys( mbedtls_cmac_context *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000123{
Brian Murray57863ad2016-05-19 16:38:36 -0700124 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700125 unsigned char *L;
126 size_t olen, block_size;
127
Brian Murrayb0c3c432016-05-18 14:29:51 -0700128 block_size = ctx->cipher_ctx.cipher_info->block_size;
129
Brian Murrayb439d452016-05-19 16:02:42 -0700130 L = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Brian Murray4b64ab62016-05-20 06:33:01 -0700131 if( L == NULL )
Brian Murray57863ad2016-05-19 16:38:36 -0700132 {
133 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
134 goto exit;
135 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000136 /* Calculate Ek(0) */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000137 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700138 L, block_size, L, &olen ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000139 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700140 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000141 }
142
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000143 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000144 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000145 */
Brian Murrayb439d452016-05-19 16:02:42 -0700146 if( ( ret = cmac_multiply_by_u( ctx->K1, L , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700147 goto exit;
Brian Murray6a3c0d22016-05-20 18:25:43 -0700148 if( ( ret = cmac_multiply_by_u( ctx->K2, ctx->K1 , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700149 goto exit;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000150
Brian Murrayb0c3c432016-05-18 14:29:51 -0700151 exit:
Brian Murray57863ad2016-05-19 16:38:36 -0700152 if( L != NULL )
153 mbedtls_zeroize( L, sizeof( L ) );
Brian Murray4b64ab62016-05-20 06:33:01 -0700154 mbedtls_free( L );
Brian Murrayb439d452016-05-19 16:02:42 -0700155 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000156}
157
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000158/*
159 * Set key and prepare context for use
160 */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000161int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx,
162 mbedtls_cipher_id_t cipher,
163 const unsigned char *key,
164 unsigned int keybits )
165{
Brian Murray57863ad2016-05-19 16:38:36 -0700166 int ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000167 const mbedtls_cipher_info_t *cipher_info;
168
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000169 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
170 MBEDTLS_MODE_ECB );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000171 if( cipher_info == NULL )
172 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
173
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000174 mbedtls_cipher_free( &ctx->cipher_ctx );
175
176 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
177 return( ret );
178
179 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000180 MBEDTLS_ENCRYPT ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000181 {
182 return( ret );
183 }
184
Brian Murray2cfa5072016-05-23 20:17:04 -0700185 ctx->K1 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) );
186 ctx->K2 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) );
187
188 if( ctx->K1 == NULL || ctx->K2 == NULL )
189 {
190 mbedtls_free(ctx->K1);
191 mbedtls_free(ctx->K2);
192 return( MBEDTLS_ERR_CMAC_ALLOC_FAILED );
193 }
194
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000195 return( cmac_generate_subkeys( ctx ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000196}
197
198/*
199 * Free context
200 */
201void mbedtls_cmac_free( mbedtls_cmac_context *ctx )
202{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700203 int block_size;
204 block_size = ctx->cipher_ctx.cipher_info->block_size;
205
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000206 mbedtls_cipher_free( &ctx->cipher_ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700207
Brian Murray6a3c0d22016-05-20 18:25:43 -0700208 if( ctx->K1 != NULL )
209 mbedtls_zeroize( ctx->K1, block_size * sizeof( unsigned char ) );
210 if( ctx->K2 != NULL )
211 mbedtls_zeroize( ctx->K2, block_size * sizeof( unsigned char ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700212 mbedtls_free( ctx->K1 );
213 mbedtls_free( ctx->K2 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000214}
215
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000216/*
217 * Create padded last block from (partial) last block.
218 *
219 * We can't use the padding option from the cipher layer, as it only works for
220 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
221 */
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000222static void cmac_pad( unsigned char padded_block[16],
Brian Murrayb0c3c432016-05-18 14:29:51 -0700223 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000224 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700225 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000226{
227 size_t j;
228
Brian Murrayb0c3c432016-05-18 14:29:51 -0700229 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000230 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700231 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000232 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700233 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000234 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000235 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000236 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000237 }
238}
239
240/*
Brian Murrayb0c3c432016-05-18 14:29:51 -0700241 * XOR Block
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000242 * Here, macro results in smaller compiled code than static inline function
243 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700244#define XOR_BLOCK( o, i1, i2 ) \
245 for( i = 0; i < block_size; i++ ) \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000246 ( o )[i] = ( i1 )[i] ^ ( i2 )[i];
247
248/*
Brian Murray87e40402016-05-19 19:05:57 -0700249 * Update the CMAC state using an input block
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000250 */
251#define UPDATE_CMAC( x ) \
252do { \
Brian Murrayb0c3c432016-05-18 14:29:51 -0700253 XOR_BLOCK( state, ( x ), state ); \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000254 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, \
Brian Murrayb0c3c432016-05-18 14:29:51 -0700255 state, block_size, \
256 state, &olen ) ) != 0 ) \
Brian Murray57863ad2016-05-19 16:38:36 -0700257 { \
258 goto exit; \
259 } \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000260} while( 0 )
261
262/*
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000263 * Generate tag on complete message
264 */
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000265int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
266 const unsigned char *input, size_t in_len,
267 unsigned char *tag, size_t tag_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000268{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700269 unsigned char *state;
270 unsigned char *M_last;
Brian Murray57863ad2016-05-19 16:38:36 -0700271 int n, j, ret, needs_padding;
272 size_t olen, block_size, i;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700273
Brian Murrayb0c3c432016-05-18 14:29:51 -0700274 ret = 0;
275 block_size = ctx->cipher_ctx.cipher_info->block_size;
276
Brian Murrayb439d452016-05-19 16:02:42 -0700277 state = mbedtls_calloc( block_size, sizeof( unsigned char ) );
278 M_last = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000279
Brian Murray57863ad2016-05-19 16:38:36 -0700280 if( state == NULL || M_last == NULL )
281 {
282 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
283 goto exit;
284 }
285
Brian Murray87e40402016-05-19 19:05:57 -0700286 if( tag_len < 2 || tag_len > block_size || tag_len % 2 != 0 )
Brian Murray57863ad2016-05-19 16:38:36 -0700287 {
288 ret = MBEDTLS_ERR_CMAC_BAD_INPUT;
289 goto exit;
290 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000291
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000292 if( in_len == 0 )
293 needs_padding = 1;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000294 else
Brian Murrayb0c3c432016-05-18 14:29:51 -0700295 needs_padding = in_len % block_size != 0;
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000296
Brian Murrayb0c3c432016-05-18 14:29:51 -0700297 n = in_len / block_size + needs_padding;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000298
299 /* Calculate last block */
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000300 if( needs_padding )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000301 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700302 cmac_pad( M_last, block_size, input + block_size * ( n - 1 ), in_len % block_size );
303 XOR_BLOCK( M_last, M_last, ctx->K2 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000304 }
305 else
306 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000307 /* Last block is complete block */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700308 XOR_BLOCK( M_last, input + block_size * ( n - 1 ), ctx->K1 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000309 }
310
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000311 for( j = 0; j < n - 1; j++ )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700312 UPDATE_CMAC( input + block_size * j );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000313
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000314 UPDATE_CMAC( M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000315
Brian Murray00dc5f02016-05-19 14:23:50 -0700316 memcpy( tag, state, tag_len );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000317
Brian Murrayb0c3c432016-05-18 14:29:51 -0700318 exit:
Brian Murray4b64ab62016-05-20 06:33:01 -0700319 mbedtls_free( state );
320 mbedtls_free( M_last );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700321 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000322}
323
Brian Murrayb0c3c432016-05-18 14:29:51 -0700324#undef XOR_BLOCK
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000325#undef UPDATE_CMAC
326
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000327/*
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000328 * Verify tag on complete message
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000329 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000330int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
331 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000332 const unsigned char *tag, size_t tag_len )
333{
334 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700335 unsigned char *check_tag;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000336 unsigned char i;
337 int diff;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000338
Brian Murrayb439d452016-05-19 16:02:42 -0700339 check_tag = mbedtls_calloc( ctx->cipher_ctx.cipher_info->block_size,
340 sizeof( unsigned char ) );
Brian Murray4b64ab62016-05-20 06:33:01 -0700341 if( check_tag == NULL )
Brian Murray57863ad2016-05-19 16:38:36 -0700342 {
343 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
344 goto exit;
345 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700346
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000347 if( ( ret = mbedtls_cmac_generate( ctx, input, in_len,
348 check_tag, tag_len ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000349 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700350 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000351 }
352
353 /* Check tag in "constant-time" */
354 for( diff = 0, i = 0; i < tag_len; i++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000355 diff |= tag[i] ^ check_tag[i];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000356
357 if( diff != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700358 ret = MBEDTLS_ERR_CMAC_VERIFY_FAILED;
359 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000360
Brian Murrayb0c3c432016-05-18 14:29:51 -0700361 exit:
Brian Murray4b64ab62016-05-20 06:33:01 -0700362 mbedtls_free( check_tag );
Brian Murrayb439d452016-05-19 16:02:42 -0700363 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000364}
365
Brian Murrayb439d452016-05-19 16:02:42 -0700366#ifdef MBEDTLS_AES_C
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000367/*
368 * PRF based on CMAC with AES-128
Brian Murrayb0c3c432016-05-18 14:29:51 -0700369 * See RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000370 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700371int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000372 const unsigned char *input, size_t in_len,
Brian Murrayb439d452016-05-19 16:02:42 -0700373 unsigned char tag[16] )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000374{
375 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700376 mbedtls_cmac_context ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000377 unsigned char zero_key[16];
378 unsigned char int_key[16];
379
Brian Murrayb439d452016-05-19 16:02:42 -0700380 mbedtls_cmac_init(&ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700381
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000382 if( key_length == 16 )
383 {
384 /* Use key as is */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000385 memcpy( int_key, key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000386 }
387 else
388 {
389 mbedtls_cmac_context zero_ctx;
390
Brian Murrayb439d452016-05-19 16:02:42 -0700391 /* Key is AES_CMAC( 0, key ) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000392 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000393 memset( zero_key, 0, 16 );
394 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
Brian Murray6a3c0d22016-05-20 18:25:43 -0700395 zero_key, 8 * sizeof( zero_key ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000396 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700397 goto exit;
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000398
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000399 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000400 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700401 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000402 }
403
Brian Murrayb0c3c432016-05-18 14:29:51 -0700404 ret = mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
Brian Murray6a3c0d22016-05-20 18:25:43 -0700405 int_key, 8 * sizeof( int_key ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000406 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700407 goto exit;
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000408
Brian Murrayb0c3c432016-05-18 14:29:51 -0700409 ret = mbedtls_cmac_generate( &ctx, input, in_len, tag, 16 );
410
411 exit:
Brian Murray6a3c0d22016-05-20 18:25:43 -0700412 mbedtls_zeroize( int_key, sizeof( int_key ) );
413 mbedtls_cmac_free( &ctx );
414 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000415}
Brian Murrayb439d452016-05-19 16:02:42 -0700416#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000417
Brian Murray0f6af732016-05-19 15:59:23 -0700418#ifdef MBEDTLS_SELF_TEST
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000419/*
Brian Murray0f6af732016-05-19 15:59:23 -0700420 * CMAC test data from SP800-38B Appendix D.1 (corrected)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000421 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700422 *
423 * AES-CMAC-PRF-128 test data from RFC 4615
424 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000425 */
426
Brian Murray0f6af732016-05-19 15:59:23 -0700427#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000428#define NB_PRF_TESTS 3
Brian Murray0f6af732016-05-19 15:59:23 -0700429#define AES_BLOCK_SIZE 16
430#define DES3_BLOCK_SIZE 8
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000431
Brian Murray0f6af732016-05-19 15:59:23 -0700432#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
433/* All CMAC test inputs are truncated from the same 64 byte buffer. */
434static const unsigned char test_message[] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000435 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
436 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
437 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
438 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
439 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
440 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
441 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
442 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
443};
Brian Murray0cf14c12016-05-23 12:49:50 -0700444/* Function Prototype */
445int test_cmac_with_cipher( int verbose, const char* testname, const unsigned char* key,
446 int keybits, const unsigned char* messages,
447 const unsigned int message_lengths[4], const unsigned char* subkeys,
448 const unsigned char* expected_result, mbedtls_cipher_id_t cipher_id,
449 int block_size );
450
451
Brian Murray0f6af732016-05-19 15:59:23 -0700452#endif /* defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000453
Brian Murray0f6af732016-05-19 15:59:23 -0700454#ifdef MBEDTLS_AES_C
455/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700456static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700457 0,
458 16,
459 40,
460 64
461};
462
463/* AES 128 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700464static const unsigned char aes_128_key[16] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700465 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
466 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
467};
468static const unsigned char aes_128_subkeys[2][AES_BLOCK_SIZE] = {
469 {
470 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
471 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
472 },
473 {
474 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
475 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
476 }
477};
478static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000479 {
480 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
481 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
482 },
483 {
484 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
485 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
486 },
487 {
488 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
489 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
490 },
491 {
492 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
493 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
494 }
495};
496
Brian Murray0f6af732016-05-19 15:59:23 -0700497/* AES 192 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700498static const unsigned char aes_192_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700499 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
500 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
501 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000502};
Brian Murray0f6af732016-05-19 15:59:23 -0700503static const unsigned char aes_192_subkeys[2][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700504 {
Brian Murray0f6af732016-05-19 15:59:23 -0700505 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
506 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700507 },
508 {
Brian Murray0f6af732016-05-19 15:59:23 -0700509 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
510 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700511 }
512};
Brian Murray0f6af732016-05-19 15:59:23 -0700513static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700514 {
515 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
516 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
517 },
518 {
519 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
520 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
521 },
522 {
523 0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad,
524 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e
525 },
526 {
527 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
528 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
529 }
530};
531
Brian Murray0f6af732016-05-19 15:59:23 -0700532/* AES 256 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700533static const unsigned char aes_256_key[32] = {
Brian Murray87e40402016-05-19 19:05:57 -0700534 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
535 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
536 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
537 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700538};
539static const unsigned char aes_256_subkeys[2][AES_BLOCK_SIZE] = {
540 {
541 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
542 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
543 },
544 {
545 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
546 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
547 }
548};
549static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
550 {
551 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
552 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
553 },
554 {
555 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
556 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
557 },
558 {
559 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
560 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6
561 },
562 {
563 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
564 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
565 }
566};
567#endif /* MBEDTLS_AES_C */
568
569#ifdef MBEDTLS_DES_C
570/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700571static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700572 0,
573 8,
574 20,
575 32
576};
577
578/* 3DES 2 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700579static const unsigned char des3_2key_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700580 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5,
581 0x8a, 0x3d, 0x10, 0xba, 0x80, 0x57, 0x0d, 0x38,
582 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5
Brian Murray0f6af732016-05-19 15:59:23 -0700583};
584static const unsigned char des3_2key_subkeys[2][8] = {
585 {
586 0x8e, 0xcf, 0x37, 0x3e, 0xd7, 0x1a, 0xfa, 0xef
587 },
588 {
589 0x1d, 0x9e, 0x6e, 0x7d, 0xae, 0x35, 0xf5, 0xc5
590 }
591};
Brian Murray57863ad2016-05-19 16:38:36 -0700592static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700593 {
594 0xbd, 0x2e, 0xbf, 0x9a, 0x3b, 0xa0, 0x03, 0x61
595 },
596 {
597 0x4f, 0xf2, 0xab, 0x81, 0x3c, 0x53, 0xce, 0x83
598 },
599 {
600 0x62, 0xdd, 0x1b, 0x47, 0x19, 0x02, 0xbd, 0x4e
601 },
602 {
603 0x31, 0xb1, 0xe4, 0x31, 0xda, 0xbc, 0x4e, 0xb8
604 }
605};
606
Brian Murray0f6af732016-05-19 15:59:23 -0700607/* 3DES 3 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700608static const unsigned char des3_3key_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700609 0x8a, 0xa8, 0x3b, 0xf8, 0xcb, 0xda, 0x10, 0x62,
610 0x0b, 0xc1, 0xbf, 0x19, 0xfb, 0xb6, 0xcd, 0x58,
611 0xbc, 0x31, 0x3d, 0x4a, 0x37, 0x1c, 0xa8, 0xb5
Brian Murray0f6af732016-05-19 15:59:23 -0700612};
613static const unsigned char des3_3key_subkeys[2][8] = {
614 {
615 0x91, 0x98, 0xe9, 0xd3, 0x14, 0xe6, 0x53, 0x5f
616 },
617 {
618 0x23, 0x31, 0xd3, 0xa6, 0x29, 0xcc, 0xa6, 0xa5
619 }
620};
Brian Murray57863ad2016-05-19 16:38:36 -0700621static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700622 {
623 0xb7, 0xa6, 0x88, 0xe1, 0x22, 0xff, 0xaf, 0x95
624 },
625 {
626 0x8e, 0x8f, 0x29, 0x31, 0x36, 0x28, 0x37, 0x97
627 },
628 {
629 0x74, 0x3d, 0xdb, 0xe0, 0xce, 0x2d, 0xc2, 0xed
630 },
631 {
632 0x33, 0xe6, 0xb1, 0x09, 0x24, 0x00, 0xea, 0xe5
633 }
634};
635
Brian Murray0f6af732016-05-19 15:59:23 -0700636#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700637
Brian Murray0f6af732016-05-19 15:59:23 -0700638#ifdef MBEDTLS_AES_C
639/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000640static const unsigned char PRFK[] = {
641 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
642 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
643 0xed, 0xcb
644};
645
646/* Sizes in bytes */
647static const size_t PRFKlen[NB_PRF_TESTS] = {
648 18,
649 16,
650 10
651};
652
653/* PRF M */
654static const unsigned char PRFM[] = {
655 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
656 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000657 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000658};
659
660static const unsigned char PRFT[NB_PRF_TESTS][16] = {
661 {
662 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
663 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
664 },
665 {
666 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
667 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
668 },
669 {
670 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
671 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
672 }
673};
Brian Murray0f6af732016-05-19 15:59:23 -0700674#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000675
Brian Murrayb439d452016-05-19 16:02:42 -0700676int test_cmac_with_cipher( int verbose,
Brian Murray0cf14c12016-05-23 12:49:50 -0700677 const char* testname,
Brian Murray87e40402016-05-19 19:05:57 -0700678 const unsigned char* key,
679 int keybits,
680 const unsigned char* messages,
681 const unsigned int message_lengths[4],
682 const unsigned char* subkeys,
683 const unsigned char* expected_result,
684 mbedtls_cipher_id_t cipher_id,
685 int block_size )
Brian Murray00dc5f02016-05-19 14:23:50 -0700686{
Brian Murray87e40402016-05-19 19:05:57 -0700687 const int num_tests = 4;
688 mbedtls_cmac_context ctx;
Brian Murray00dc5f02016-05-19 14:23:50 -0700689 int i, ret;
690 unsigned char* tag;
691
692 tag = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Brian Murray6a3c0d22016-05-20 18:25:43 -0700693 if( tag == NULL )
694 {
Brian Murray57863ad2016-05-19 16:38:36 -0700695 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
696 goto exit;
697 }
698
Brian Murray00dc5f02016-05-19 14:23:50 -0700699 mbedtls_cmac_init( &ctx );
700
701 if( ( ret = mbedtls_cmac_setkey( &ctx, cipher_id, key, keybits ) ) != 0 )
702 {
703 if( verbose != 0 )
704 mbedtls_printf( " CMAC: setup failed\n" );
705 goto exit;
706 }
707
708 if( ( ret = memcmp( ctx.K1, subkeys, block_size ) != 0 ) ||
709 ( ret = memcmp( ctx.K2, &subkeys[block_size], block_size ) != 0 ) )
710 {
711 if( verbose != 0 )
712 mbedtls_printf( " CMAC: subkey generation failed\n" );
713 goto exit;
714 }
715
716 for( i = 0; i < num_tests; i++ )
717 {
718 if( verbose != 0 )
719 mbedtls_printf( " %s CMAC #%u: ", testname, i +1 );
720
721 if( ( ret = mbedtls_cmac_generate( &ctx, messages, message_lengths[i], tag, block_size ) ) != 0 )
722 {
723 if( verbose != 0 )
724 mbedtls_printf( "failed\n" );
725 goto exit;
726 }
727 if( ( ret = memcmp( tag, &expected_result[i * block_size], block_size ) ) != 0 )
728 {
729 if( verbose != 0 )
730 mbedtls_printf( "failed\n" );
731 goto exit;
732 }
733
734 if( ( ret = mbedtls_cmac_verify( &ctx, messages, message_lengths[i], &expected_result[i * block_size], block_size ) != 0 ) )
735 {
Brian Murray4b64ab62016-05-20 06:33:01 -0700736 if( verbose != 0 )
737 mbedtls_printf( "failed\n" );
738 goto exit;
Brian Murray00dc5f02016-05-19 14:23:50 -0700739 }
740 mbedtls_printf( "passed\n" );
741 }
742 exit:
Brian Murray4b64ab62016-05-20 06:33:01 -0700743 mbedtls_free( tag );
Brian Murray00dc5f02016-05-19 14:23:50 -0700744 mbedtls_cmac_free( &ctx );
745 return( ret );
746}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000747
Brian Murray0f6af732016-05-19 15:59:23 -0700748#ifdef MBEDTLS_AES_C
Brian Murray0cf14c12016-05-23 12:49:50 -0700749/* Function Prototype */
750int test_aes128_cmac_prf( int verbose );
751
Brian Murray6a3c0d22016-05-20 18:25:43 -0700752int test_aes128_cmac_prf( int verbose )
753{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000754 int i;
755 int ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700756 unsigned char tag[16];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700757 for( i = 0; i < NB_PRF_TESTS; i++ )
758 {
Brian Murray0f6af732016-05-19 15:59:23 -0700759 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
760 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, tag );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700761 if( ret != 0 ||
762 memcmp( tag, PRFT[i], 16 ) != 0 )
763 {
764 if( verbose != 0 )
765 mbedtls_printf( "failed\n" );
766
Brian Murray0f6af732016-05-19 15:59:23 -0700767 return( ret );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700768 } else if( verbose != 0 )
769 {
770 mbedtls_printf( "passed\n" );
771 }
772 }
Brian Murray0f6af732016-05-19 15:59:23 -0700773 return( ret );
774}
775#endif /* MBEDTLS_AES_C */
776
777int mbedtls_cmac_self_test( int verbose )
778{
779 int ret;
780
781#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700782 if( ( ret = test_cmac_with_cipher( verbose,
783 "AES 128",
784 aes_128_key,
785 128,
786 test_message,
787 aes_message_lengths,
Brian Murray57863ad2016-05-19 16:38:36 -0700788 (const unsigned char*) aes_128_subkeys,
789 (const unsigned char*) aes_128_expected_result,
Brian Murray9044b022016-05-19 16:36:56 -0700790 MBEDTLS_CIPHER_ID_AES,
791 AES_BLOCK_SIZE ) !=0 ) )
792 {
793 return( ret );
794 }
Brian Murray0f6af732016-05-19 15:59:23 -0700795
Brian Murray9044b022016-05-19 16:36:56 -0700796 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700797 "AES 192",
798 aes_192_key,
799 192,
800 test_message,
801 aes_message_lengths,
802 (const unsigned char*) aes_192_subkeys,
803 (const unsigned char*) aes_192_expected_result,
804 MBEDTLS_CIPHER_ID_AES,
805 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700806 {
807 return( ret );
808 }
Brian Murray0f6af732016-05-19 15:59:23 -0700809
Brian Murray9044b022016-05-19 16:36:56 -0700810 if( ( ret = test_cmac_with_cipher ( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700811 "AES 256",
Brian Murray6a3c0d22016-05-20 18:25:43 -0700812 aes_256_key,
813 256,
814 test_message,
815 aes_message_lengths,
816 (const unsigned char*) aes_256_subkeys,
817 (const unsigned char*) aes_256_expected_result,
818 MBEDTLS_CIPHER_ID_AES,
819 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700820 {
821 return( ret );
822 }
Brian Murray0f6af732016-05-19 15:59:23 -0700823#endif /* MBEDTLS_AES_C */
824
825#ifdef MBEDTLS_DES_C
Brian Murray9044b022016-05-19 16:36:56 -0700826 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700827 "3DES 2 key",
Brian Murray6a3c0d22016-05-20 18:25:43 -0700828 des3_2key_key,
829 192,
830 test_message,
831 des3_message_lengths,
832 (const unsigned char*) des3_2key_subkeys,
833 (const unsigned char*) des3_2key_expected_result,
834 MBEDTLS_CIPHER_ID_3DES,
835 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700836 {
837 return( ret );
838 }
Brian Murray0f6af732016-05-19 15:59:23 -0700839
Brian Murray9044b022016-05-19 16:36:56 -0700840 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700841 "3DES 3 key",
Brian Murray6a3c0d22016-05-20 18:25:43 -0700842 des3_3key_key,
843 192,
844 test_message,
845 des3_message_lengths,
846 (const unsigned char*) des3_3key_subkeys,
847 (const unsigned char*) des3_3key_expected_result,
848 MBEDTLS_CIPHER_ID_3DES,
849 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700850 {
851 return( ret );
852 }
Brian Murray0f6af732016-05-19 15:59:23 -0700853#endif /* MBEDTLS_DES_C */
854
855#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700856 if( ( ret = test_aes128_cmac_prf( verbose ) != 0 ) )
857 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -0700858#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700859
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000860 if( verbose != 0 )
861 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -0700862
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000863 return( 0 );
864}
865
Brian Murray0f6af732016-05-19 15:59:23 -0700866#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000867
868#endif /* MBEDTLS_CMAC_C */