blob: 1a6f31376e4373a447f079be6ac1199d58041158 [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 Murray0f6af732016-05-19 15:59:23 -0700444#endif /* defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000445
Brian Murray0f6af732016-05-19 15:59:23 -0700446#ifdef MBEDTLS_AES_C
447/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700448static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700449 0,
450 16,
451 40,
452 64
453};
454
455/* AES 128 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700456static const unsigned char aes_128_key[16] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700457 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
458 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
459};
460static const unsigned char aes_128_subkeys[2][AES_BLOCK_SIZE] = {
461 {
462 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
463 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
464 },
465 {
466 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
467 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
468 }
469};
470static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000471 {
472 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
473 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
474 },
475 {
476 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
477 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
478 },
479 {
480 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
481 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
482 },
483 {
484 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
485 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
486 }
487};
488
Brian Murray0f6af732016-05-19 15:59:23 -0700489/* AES 192 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700490static const unsigned char aes_192_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700491 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
492 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
493 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000494};
Brian Murray0f6af732016-05-19 15:59:23 -0700495static const unsigned char aes_192_subkeys[2][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700496 {
Brian Murray0f6af732016-05-19 15:59:23 -0700497 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
498 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700499 },
500 {
Brian Murray0f6af732016-05-19 15:59:23 -0700501 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
502 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700503 }
504};
Brian Murray0f6af732016-05-19 15:59:23 -0700505static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700506 {
507 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
508 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
509 },
510 {
511 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
512 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
513 },
514 {
515 0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad,
516 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e
517 },
518 {
519 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
520 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
521 }
522};
523
Brian Murray0f6af732016-05-19 15:59:23 -0700524/* AES 256 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700525static const unsigned char aes_256_key[32] = {
Brian Murray87e40402016-05-19 19:05:57 -0700526 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
527 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
528 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
529 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700530};
531static const unsigned char aes_256_subkeys[2][AES_BLOCK_SIZE] = {
532 {
533 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
534 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
535 },
536 {
537 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
538 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
539 }
540};
541static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
542 {
543 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
544 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
545 },
546 {
547 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
548 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
549 },
550 {
551 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
552 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6
553 },
554 {
555 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
556 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
557 }
558};
559#endif /* MBEDTLS_AES_C */
560
561#ifdef MBEDTLS_DES_C
562/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700563static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700564 0,
565 8,
566 20,
567 32
568};
569
570/* 3DES 2 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700571static const unsigned char des3_2key_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700572 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5,
573 0x8a, 0x3d, 0x10, 0xba, 0x80, 0x57, 0x0d, 0x38,
574 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5
Brian Murray0f6af732016-05-19 15:59:23 -0700575};
576static const unsigned char des3_2key_subkeys[2][8] = {
577 {
578 0x8e, 0xcf, 0x37, 0x3e, 0xd7, 0x1a, 0xfa, 0xef
579 },
580 {
581 0x1d, 0x9e, 0x6e, 0x7d, 0xae, 0x35, 0xf5, 0xc5
582 }
583};
Brian Murray57863ad2016-05-19 16:38:36 -0700584static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700585 {
586 0xbd, 0x2e, 0xbf, 0x9a, 0x3b, 0xa0, 0x03, 0x61
587 },
588 {
589 0x4f, 0xf2, 0xab, 0x81, 0x3c, 0x53, 0xce, 0x83
590 },
591 {
592 0x62, 0xdd, 0x1b, 0x47, 0x19, 0x02, 0xbd, 0x4e
593 },
594 {
595 0x31, 0xb1, 0xe4, 0x31, 0xda, 0xbc, 0x4e, 0xb8
596 }
597};
598
Brian Murray0f6af732016-05-19 15:59:23 -0700599/* 3DES 3 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700600static const unsigned char des3_3key_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700601 0x8a, 0xa8, 0x3b, 0xf8, 0xcb, 0xda, 0x10, 0x62,
602 0x0b, 0xc1, 0xbf, 0x19, 0xfb, 0xb6, 0xcd, 0x58,
603 0xbc, 0x31, 0x3d, 0x4a, 0x37, 0x1c, 0xa8, 0xb5
Brian Murray0f6af732016-05-19 15:59:23 -0700604};
605static const unsigned char des3_3key_subkeys[2][8] = {
606 {
607 0x91, 0x98, 0xe9, 0xd3, 0x14, 0xe6, 0x53, 0x5f
608 },
609 {
610 0x23, 0x31, 0xd3, 0xa6, 0x29, 0xcc, 0xa6, 0xa5
611 }
612};
Brian Murray57863ad2016-05-19 16:38:36 -0700613static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700614 {
615 0xb7, 0xa6, 0x88, 0xe1, 0x22, 0xff, 0xaf, 0x95
616 },
617 {
618 0x8e, 0x8f, 0x29, 0x31, 0x36, 0x28, 0x37, 0x97
619 },
620 {
621 0x74, 0x3d, 0xdb, 0xe0, 0xce, 0x2d, 0xc2, 0xed
622 },
623 {
624 0x33, 0xe6, 0xb1, 0x09, 0x24, 0x00, 0xea, 0xe5
625 }
626};
627
Brian Murray0f6af732016-05-19 15:59:23 -0700628#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700629
Brian Murray0f6af732016-05-19 15:59:23 -0700630#ifdef MBEDTLS_AES_C
631/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000632static const unsigned char PRFK[] = {
633 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
634 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
635 0xed, 0xcb
636};
637
638/* Sizes in bytes */
639static const size_t PRFKlen[NB_PRF_TESTS] = {
640 18,
641 16,
642 10
643};
644
645/* PRF M */
646static const unsigned char PRFM[] = {
647 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
648 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000649 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000650};
651
652static const unsigned char PRFT[NB_PRF_TESTS][16] = {
653 {
654 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
655 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
656 },
657 {
658 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
659 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
660 },
661 {
662 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
663 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
664 }
665};
Brian Murray0f6af732016-05-19 15:59:23 -0700666#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000667
Brian Murrayb439d452016-05-19 16:02:42 -0700668int test_cmac_with_cipher( int verbose,
Brian Murray87e40402016-05-19 19:05:57 -0700669 char* testname,
670 const unsigned char* key,
671 int keybits,
672 const unsigned char* messages,
673 const unsigned int message_lengths[4],
674 const unsigned char* subkeys,
675 const unsigned char* expected_result,
676 mbedtls_cipher_id_t cipher_id,
677 int block_size )
Brian Murray00dc5f02016-05-19 14:23:50 -0700678{
Brian Murray87e40402016-05-19 19:05:57 -0700679 const int num_tests = 4;
680 mbedtls_cmac_context ctx;
Brian Murray00dc5f02016-05-19 14:23:50 -0700681 int i, ret;
682 unsigned char* tag;
683
684 tag = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Brian Murray6a3c0d22016-05-20 18:25:43 -0700685 if( tag == NULL )
686 {
Brian Murray57863ad2016-05-19 16:38:36 -0700687 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
688 goto exit;
689 }
690
Brian Murray00dc5f02016-05-19 14:23:50 -0700691 mbedtls_cmac_init( &ctx );
692
693 if( ( ret = mbedtls_cmac_setkey( &ctx, cipher_id, key, keybits ) ) != 0 )
694 {
695 if( verbose != 0 )
696 mbedtls_printf( " CMAC: setup failed\n" );
697 goto exit;
698 }
699
700 if( ( ret = memcmp( ctx.K1, subkeys, block_size ) != 0 ) ||
701 ( ret = memcmp( ctx.K2, &subkeys[block_size], block_size ) != 0 ) )
702 {
703 if( verbose != 0 )
704 mbedtls_printf( " CMAC: subkey generation failed\n" );
705 goto exit;
706 }
707
708 for( i = 0; i < num_tests; i++ )
709 {
710 if( verbose != 0 )
711 mbedtls_printf( " %s CMAC #%u: ", testname, i +1 );
712
713 if( ( ret = mbedtls_cmac_generate( &ctx, messages, message_lengths[i], tag, block_size ) ) != 0 )
714 {
715 if( verbose != 0 )
716 mbedtls_printf( "failed\n" );
717 goto exit;
718 }
719 if( ( ret = memcmp( tag, &expected_result[i * block_size], block_size ) ) != 0 )
720 {
721 if( verbose != 0 )
722 mbedtls_printf( "failed\n" );
723 goto exit;
724 }
725
726 if( ( ret = mbedtls_cmac_verify( &ctx, messages, message_lengths[i], &expected_result[i * block_size], block_size ) != 0 ) )
727 {
Brian Murray4b64ab62016-05-20 06:33:01 -0700728 if( verbose != 0 )
729 mbedtls_printf( "failed\n" );
730 goto exit;
Brian Murray00dc5f02016-05-19 14:23:50 -0700731 }
732 mbedtls_printf( "passed\n" );
733 }
734 exit:
Brian Murray4b64ab62016-05-20 06:33:01 -0700735 mbedtls_free( tag );
Brian Murray00dc5f02016-05-19 14:23:50 -0700736 mbedtls_cmac_free( &ctx );
737 return( ret );
738}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000739
Brian Murray0f6af732016-05-19 15:59:23 -0700740#ifdef MBEDTLS_AES_C
Brian Murray6a3c0d22016-05-20 18:25:43 -0700741int test_aes128_cmac_prf( int verbose )
742{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000743 int i;
744 int ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700745 unsigned char tag[16];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700746 for( i = 0; i < NB_PRF_TESTS; i++ )
747 {
Brian Murray0f6af732016-05-19 15:59:23 -0700748 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
749 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, tag );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700750 if( ret != 0 ||
751 memcmp( tag, PRFT[i], 16 ) != 0 )
752 {
753 if( verbose != 0 )
754 mbedtls_printf( "failed\n" );
755
Brian Murray0f6af732016-05-19 15:59:23 -0700756 return( ret );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700757 } else if( verbose != 0 )
758 {
759 mbedtls_printf( "passed\n" );
760 }
761 }
Brian Murray0f6af732016-05-19 15:59:23 -0700762 return( ret );
763}
764#endif /* MBEDTLS_AES_C */
765
766int mbedtls_cmac_self_test( int verbose )
767{
768 int ret;
769
770#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700771 if( ( ret = test_cmac_with_cipher( verbose,
772 "AES 128",
773 aes_128_key,
774 128,
775 test_message,
776 aes_message_lengths,
Brian Murray57863ad2016-05-19 16:38:36 -0700777 (const unsigned char*) aes_128_subkeys,
778 (const unsigned char*) aes_128_expected_result,
Brian Murray9044b022016-05-19 16:36:56 -0700779 MBEDTLS_CIPHER_ID_AES,
780 AES_BLOCK_SIZE ) !=0 ) )
781 {
782 return( ret );
783 }
Brian Murray0f6af732016-05-19 15:59:23 -0700784
Brian Murray9044b022016-05-19 16:36:56 -0700785 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700786 "AES 192",
787 aes_192_key,
788 192,
789 test_message,
790 aes_message_lengths,
791 (const unsigned char*) aes_192_subkeys,
792 (const unsigned char*) aes_192_expected_result,
793 MBEDTLS_CIPHER_ID_AES,
794 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700795 {
796 return( ret );
797 }
Brian Murray0f6af732016-05-19 15:59:23 -0700798
Brian Murray9044b022016-05-19 16:36:56 -0700799 if( ( ret = test_cmac_with_cipher ( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700800 "AES 256",
Brian Murray6a3c0d22016-05-20 18:25:43 -0700801 aes_256_key,
802 256,
803 test_message,
804 aes_message_lengths,
805 (const unsigned char*) aes_256_subkeys,
806 (const unsigned char*) aes_256_expected_result,
807 MBEDTLS_CIPHER_ID_AES,
808 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700809 {
810 return( ret );
811 }
Brian Murray0f6af732016-05-19 15:59:23 -0700812#endif /* MBEDTLS_AES_C */
813
814#ifdef MBEDTLS_DES_C
Brian Murray9044b022016-05-19 16:36:56 -0700815 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700816 "3DES 2 key",
Brian Murray6a3c0d22016-05-20 18:25:43 -0700817 des3_2key_key,
818 192,
819 test_message,
820 des3_message_lengths,
821 (const unsigned char*) des3_2key_subkeys,
822 (const unsigned char*) des3_2key_expected_result,
823 MBEDTLS_CIPHER_ID_3DES,
824 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700825 {
826 return( ret );
827 }
Brian Murray0f6af732016-05-19 15:59:23 -0700828
Brian Murray9044b022016-05-19 16:36:56 -0700829 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700830 "3DES 3 key",
Brian Murray6a3c0d22016-05-20 18:25:43 -0700831 des3_3key_key,
832 192,
833 test_message,
834 des3_message_lengths,
835 (const unsigned char*) des3_3key_subkeys,
836 (const unsigned char*) des3_3key_expected_result,
837 MBEDTLS_CIPHER_ID_3DES,
838 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700839 {
840 return( ret );
841 }
Brian Murray0f6af732016-05-19 15:59:23 -0700842#endif /* MBEDTLS_DES_C */
843
844#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700845 if( ( ret = test_aes128_cmac_prf( verbose ) != 0 ) )
846 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -0700847#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700848
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000849 if( verbose != 0 )
850 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -0700851
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000852 return( 0 );
853}
854
Brian Murray0f6af732016-05-19 15:59:23 -0700855#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000856
857#endif /* MBEDTLS_CMAC_C */