blob: 063a9d1c35848efcad09a1771ea90bee8878347a [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{
Robert Cragie3d23b1d2015-12-15 07:38:11 +000077
Brian Murrayb0c3c432016-05-18 14:29:51 -070078 const unsigned char R_128 = 0x87;
79 const unsigned char R_64 = 0x1B;
80 unsigned char R_n, mask;
81 unsigned char overflow = 0x00;
82 int i, starting_index;
83
84 starting_index = blocksize -1;
85
Brian Murrayb439d452016-05-19 16:02:42 -070086 if( blocksize == 16 ){
Brian Murrayb0c3c432016-05-18 14:29:51 -070087 R_n = R_128;
Brian Murrayb439d452016-05-19 16:02:42 -070088 } else if( blocksize == 8 ) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070089 R_n = R_64;
90 } else {
Brian Murrayb439d452016-05-19 16:02:42 -070091 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
Brian Murrayb0c3c432016-05-18 14:29:51 -070092 }
93
94
95 for( i = starting_index; i >= 0; i-- )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000096 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000097 output[i] = input[i] << 1 | overflow;
98 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000099 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000100
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000101 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
102 * using bit operations to avoid branches */
103 /* MSVC has a warning about unary minus on unsigned, but this is
104 * well-defined and precisely what we want to do here */
105#if defined(_MSC_VER)
106#pragma warning( push )
107#pragma warning( disable : 4146 )
108#endif
109 mask = - ( input[0] >> 7 );
110#if defined(_MSC_VER)
111#pragma warning( pop )
112#endif
113
Brian Murrayb0c3c432016-05-18 14:29:51 -0700114 output[starting_index] ^= R_n & mask;
Brian Murrayb439d452016-05-19 16:02:42 -0700115 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000116}
117
118/*
119 * Generate subkeys
120 */
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000121static int cmac_generate_subkeys( mbedtls_cmac_context *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000122{
Brian Murray57863ad2016-05-19 16:38:36 -0700123 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700124 unsigned char *L;
125 size_t olen, block_size;
126
127 ret = 0;
128 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 Murray57863ad2016-05-19 16:38:36 -0700131 if( L == NULL)
132 {
133 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
134 goto exit;
135 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000136 /* Calculate Ek(0) */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700137 memset( L, 0, block_size );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000138 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700139 L, block_size, L, &olen ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000140 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700141 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000142 }
143
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000144 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000145 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000146 */
Brian Murrayb439d452016-05-19 16:02:42 -0700147 if( ( ret = cmac_multiply_by_u( ctx->K1, L , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700148 goto exit;
Brian Murrayb439d452016-05-19 16:02:42 -0700149 if( ( cmac_multiply_by_u( ctx->K2, ctx->K1 , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700150 goto exit;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000151
Brian Murrayb0c3c432016-05-18 14:29:51 -0700152 exit:
Brian Murray57863ad2016-05-19 16:38:36 -0700153 if( L != NULL )
154 mbedtls_zeroize( L, sizeof( L ) );
Brian Murrayb439d452016-05-19 16:02:42 -0700155 free( L );
156 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000157}
158
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000159/*
160 * Set key and prepare context for use
161 */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000162int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx,
163 mbedtls_cipher_id_t cipher,
164 const unsigned char *key,
165 unsigned int keybits )
166{
Brian Murray57863ad2016-05-19 16:38:36 -0700167 int ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000168 const mbedtls_cipher_info_t *cipher_info;
169
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000170 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
171 MBEDTLS_MODE_ECB );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000172 if( cipher_info == NULL )
173 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
174
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000175 mbedtls_cipher_free( &ctx->cipher_ctx );
176
177 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
178 return( ret );
179
180 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000181 MBEDTLS_ENCRYPT ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000182 {
183 return( ret );
184 }
185
Brian Murray2cfa5072016-05-23 20:17:04 -0700186 ctx->K1 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) );
187 ctx->K2 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) );
188
189 if( ctx->K1 == NULL || ctx->K2 == NULL )
190 {
191 mbedtls_free(ctx->K1);
192 mbedtls_free(ctx->K2);
193 return( MBEDTLS_ERR_CMAC_ALLOC_FAILED );
194 }
195
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000196 return( cmac_generate_subkeys( ctx ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000197}
198
199/*
200 * Free context
201 */
202void mbedtls_cmac_free( mbedtls_cmac_context *ctx )
203{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700204 int block_size;
205 block_size = ctx->cipher_ctx.cipher_info->block_size;
206
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000207 mbedtls_cipher_free( &ctx->cipher_ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700208
Brian Murrayb439d452016-05-19 16:02:42 -0700209 mbedtls_zeroize( ctx->K1, block_size * sizeof( unsigned char ) );
210 mbedtls_zeroize( ctx->K2, block_size * sizeof( unsigned char ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700211 mbedtls_free( ctx->K1 );
212 mbedtls_free( ctx->K2 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000213}
214
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000215/*
216 * Create padded last block from (partial) last block.
217 *
218 * We can't use the padding option from the cipher layer, as it only works for
219 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
220 */
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000221static void cmac_pad( unsigned char padded_block[16],
Brian Murrayb0c3c432016-05-18 14:29:51 -0700222 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000223 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700224 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000225{
226 size_t j;
227
Brian Murrayb0c3c432016-05-18 14:29:51 -0700228 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000229 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700230 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000231 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700232 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000233 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000234 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000235 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000236 }
237}
238
239/*
Brian Murrayb0c3c432016-05-18 14:29:51 -0700240 * XOR Block
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000241 * Here, macro results in smaller compiled code than static inline function
242 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700243#define XOR_BLOCK( o, i1, i2 ) \
244 for( i = 0; i < block_size; i++ ) \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000245 ( o )[i] = ( i1 )[i] ^ ( i2 )[i];
246
247/*
Brian Murray87e40402016-05-19 19:05:57 -0700248 * Update the CMAC state using an input block
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000249 */
250#define UPDATE_CMAC( x ) \
251do { \
Brian Murrayb0c3c432016-05-18 14:29:51 -0700252 XOR_BLOCK( state, ( x ), state ); \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000253 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, \
Brian Murrayb0c3c432016-05-18 14:29:51 -0700254 state, block_size, \
255 state, &olen ) ) != 0 ) \
Brian Murray57863ad2016-05-19 16:38:36 -0700256 { \
257 goto exit; \
258 } \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000259} while( 0 )
260
261/*
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000262 * Generate tag on complete message
263 */
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000264int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
265 const unsigned char *input, size_t in_len,
266 unsigned char *tag, size_t tag_len )
267
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
Brian Murrayb0c3c432016-05-18 14:29:51 -0700311 memset( state, 0, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000312
313 for( j = 0; j < n - 1; j++ )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700314 UPDATE_CMAC( input + block_size * j );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000315
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000316 UPDATE_CMAC( M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000317
Brian Murray00dc5f02016-05-19 14:23:50 -0700318 memcpy( tag, state, tag_len );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000319
Brian Murrayb0c3c432016-05-18 14:29:51 -0700320 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700321 free( state );
322 free( M_last );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700323 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000324}
325
Brian Murrayb0c3c432016-05-18 14:29:51 -0700326#undef XOR_BLOCK
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000327#undef UPDATE_CMAC
328
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000329/*
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000330 * Verify tag on complete message
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000331 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000332int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
333 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000334 const unsigned char *tag, size_t tag_len )
335{
336 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700337 unsigned char *check_tag;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000338 unsigned char i;
339 int diff;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000340
Brian Murrayb439d452016-05-19 16:02:42 -0700341 check_tag = mbedtls_calloc( ctx->cipher_ctx.cipher_info->block_size,
342 sizeof( unsigned char ) );
Brian Murray57863ad2016-05-19 16:38:36 -0700343 if(check_tag == NULL)
344 {
345 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
346 goto exit;
347 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700348
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000349 if( ( ret = mbedtls_cmac_generate( ctx, input, in_len,
350 check_tag, tag_len ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000351 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700352 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000353 }
354
355 /* Check tag in "constant-time" */
356 for( diff = 0, i = 0; i < tag_len; i++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000357 diff |= tag[i] ^ check_tag[i];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000358
359 if( diff != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700360 ret = MBEDTLS_ERR_CMAC_VERIFY_FAILED;
361 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000362
Brian Murrayb0c3c432016-05-18 14:29:51 -0700363 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700364 free( check_tag );
365 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000366}
367
Brian Murrayb439d452016-05-19 16:02:42 -0700368#ifdef MBEDTLS_AES_C
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000369/*
370 * PRF based on CMAC with AES-128
Brian Murrayb0c3c432016-05-18 14:29:51 -0700371 * See RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000372 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700373int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000374 const unsigned char *input, size_t in_len,
Brian Murrayb439d452016-05-19 16:02:42 -0700375 unsigned char tag[16] )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000376{
377 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700378 mbedtls_cmac_context ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000379 unsigned char zero_key[16];
380 unsigned char int_key[16];
381
Brian Murrayb439d452016-05-19 16:02:42 -0700382 mbedtls_cmac_init(&ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700383
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000384 if( key_length == 16 )
385 {
386 /* Use key as is */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000387 memcpy( int_key, key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000388 }
389 else
390 {
391 mbedtls_cmac_context zero_ctx;
392
Brian Murrayb439d452016-05-19 16:02:42 -0700393 /* Key is AES_CMAC( 0, key ) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000394 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000395 memset( zero_key, 0, 16 );
396 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
397 zero_key, 8 * sizeof zero_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000398 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700399 goto exit;
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000400
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000401 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000402 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700403 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000404 }
405
Brian Murrayb0c3c432016-05-18 14:29:51 -0700406 ret = mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000407 int_key, 8 * sizeof int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000408 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700409 goto exit;
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000410
411 mbedtls_zeroize( int_key, sizeof( int_key ) );
412
Brian Murrayb0c3c432016-05-18 14:29:51 -0700413 ret = mbedtls_cmac_generate( &ctx, input, in_len, tag, 16 );
414
415 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700416 mbedtls_cmac_free( &ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700417 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000418}
Brian Murrayb439d452016-05-19 16:02:42 -0700419#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000420
Brian Murray0f6af732016-05-19 15:59:23 -0700421#ifdef MBEDTLS_SELF_TEST
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000422/*
Brian Murray0f6af732016-05-19 15:59:23 -0700423 * CMAC test data from SP800-38B Appendix D.1 (corrected)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000424 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700425 *
426 * AES-CMAC-PRF-128 test data from RFC 4615
427 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000428 */
429
Brian Murray0f6af732016-05-19 15:59:23 -0700430#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000431#define NB_PRF_TESTS 3
Brian Murray0f6af732016-05-19 15:59:23 -0700432#define AES_BLOCK_SIZE 16
433#define DES3_BLOCK_SIZE 8
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000434
Brian Murray0f6af732016-05-19 15:59:23 -0700435#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
436/* All CMAC test inputs are truncated from the same 64 byte buffer. */
437static const unsigned char test_message[] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000438 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
439 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
440 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
441 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
442 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
443 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
444 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
445 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
446};
Brian Murray0f6af732016-05-19 15:59:23 -0700447#endif /* defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000448
Brian Murray0f6af732016-05-19 15:59:23 -0700449#ifdef MBEDTLS_AES_C
450/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700451static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700452 0,
453 16,
454 40,
455 64
456};
457
458/* AES 128 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700459static const unsigned char aes_128_key[16] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700460 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
461 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
462};
463static const unsigned char aes_128_subkeys[2][AES_BLOCK_SIZE] = {
464 {
465 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
466 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
467 },
468 {
469 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
470 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
471 }
472};
473static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000474 {
475 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
476 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
477 },
478 {
479 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
480 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
481 },
482 {
483 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
484 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
485 },
486 {
487 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
488 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
489 }
490};
491
Brian Murray0f6af732016-05-19 15:59:23 -0700492/* AES 192 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700493static const unsigned char aes_192_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700494 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
495 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
496 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000497};
Brian Murray0f6af732016-05-19 15:59:23 -0700498static const unsigned char aes_192_subkeys[2][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700499 {
Brian Murray0f6af732016-05-19 15:59:23 -0700500 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
501 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700502 },
503 {
Brian Murray0f6af732016-05-19 15:59:23 -0700504 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
505 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700506 }
507};
Brian Murray0f6af732016-05-19 15:59:23 -0700508static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700509 {
510 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
511 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
512 },
513 {
514 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
515 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
516 },
517 {
518 0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad,
519 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e
520 },
521 {
522 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
523 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
524 }
525};
526
Brian Murray0f6af732016-05-19 15:59:23 -0700527/* AES 256 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700528static const unsigned char aes_256_key[32] = {
Brian Murray87e40402016-05-19 19:05:57 -0700529 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
530 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
531 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
532 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700533};
534static const unsigned char aes_256_subkeys[2][AES_BLOCK_SIZE] = {
535 {
536 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
537 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
538 },
539 {
540 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
541 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
542 }
543};
544static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
545 {
546 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
547 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
548 },
549 {
550 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
551 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
552 },
553 {
554 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
555 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6
556 },
557 {
558 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
559 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
560 }
561};
562#endif /* MBEDTLS_AES_C */
563
564#ifdef MBEDTLS_DES_C
565/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700566static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700567 0,
568 8,
569 20,
570 32
571};
572
573/* 3DES 2 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700574static const unsigned char des3_2key_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700575 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5,
576 0x8a, 0x3d, 0x10, 0xba, 0x80, 0x57, 0x0d, 0x38,
577 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5
Brian Murray0f6af732016-05-19 15:59:23 -0700578};
579static const unsigned char des3_2key_subkeys[2][8] = {
580 {
581 0x8e, 0xcf, 0x37, 0x3e, 0xd7, 0x1a, 0xfa, 0xef
582 },
583 {
584 0x1d, 0x9e, 0x6e, 0x7d, 0xae, 0x35, 0xf5, 0xc5
585 }
586};
Brian Murray57863ad2016-05-19 16:38:36 -0700587static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700588 {
589 0xbd, 0x2e, 0xbf, 0x9a, 0x3b, 0xa0, 0x03, 0x61
590 },
591 {
592 0x4f, 0xf2, 0xab, 0x81, 0x3c, 0x53, 0xce, 0x83
593 },
594 {
595 0x62, 0xdd, 0x1b, 0x47, 0x19, 0x02, 0xbd, 0x4e
596 },
597 {
598 0x31, 0xb1, 0xe4, 0x31, 0xda, 0xbc, 0x4e, 0xb8
599 }
600};
601
Brian Murray0f6af732016-05-19 15:59:23 -0700602/* 3DES 3 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700603static const unsigned char des3_3key_key[24] = {
Brian Murray87e40402016-05-19 19:05:57 -0700604 0x8a, 0xa8, 0x3b, 0xf8, 0xcb, 0xda, 0x10, 0x62,
605 0x0b, 0xc1, 0xbf, 0x19, 0xfb, 0xb6, 0xcd, 0x58,
606 0xbc, 0x31, 0x3d, 0x4a, 0x37, 0x1c, 0xa8, 0xb5
Brian Murray0f6af732016-05-19 15:59:23 -0700607};
608static const unsigned char des3_3key_subkeys[2][8] = {
609 {
610 0x91, 0x98, 0xe9, 0xd3, 0x14, 0xe6, 0x53, 0x5f
611 },
612 {
613 0x23, 0x31, 0xd3, 0xa6, 0x29, 0xcc, 0xa6, 0xa5
614 }
615};
Brian Murray57863ad2016-05-19 16:38:36 -0700616static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700617 {
618 0xb7, 0xa6, 0x88, 0xe1, 0x22, 0xff, 0xaf, 0x95
619 },
620 {
621 0x8e, 0x8f, 0x29, 0x31, 0x36, 0x28, 0x37, 0x97
622 },
623 {
624 0x74, 0x3d, 0xdb, 0xe0, 0xce, 0x2d, 0xc2, 0xed
625 },
626 {
627 0x33, 0xe6, 0xb1, 0x09, 0x24, 0x00, 0xea, 0xe5
628 }
629};
630
Brian Murray0f6af732016-05-19 15:59:23 -0700631#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700632
Brian Murray0f6af732016-05-19 15:59:23 -0700633#ifdef MBEDTLS_AES_C
634/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000635static const unsigned char PRFK[] = {
636 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
637 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
638 0xed, 0xcb
639};
640
641/* Sizes in bytes */
642static const size_t PRFKlen[NB_PRF_TESTS] = {
643 18,
644 16,
645 10
646};
647
648/* PRF M */
649static const unsigned char PRFM[] = {
650 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
651 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000652 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000653};
654
655static const unsigned char PRFT[NB_PRF_TESTS][16] = {
656 {
657 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
658 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
659 },
660 {
661 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
662 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
663 },
664 {
665 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
666 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
667 }
668};
Brian Murray0f6af732016-05-19 15:59:23 -0700669#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000670
Brian Murrayb439d452016-05-19 16:02:42 -0700671int test_cmac_with_cipher( int verbose,
Brian Murray87e40402016-05-19 19:05:57 -0700672 char* testname,
673 const unsigned char* key,
674 int keybits,
675 const unsigned char* messages,
676 const unsigned int message_lengths[4],
677 const unsigned char* subkeys,
678 const unsigned char* expected_result,
679 mbedtls_cipher_id_t cipher_id,
680 int block_size )
Brian Murray00dc5f02016-05-19 14:23:50 -0700681{
Brian Murray87e40402016-05-19 19:05:57 -0700682 const int num_tests = 4;
683 mbedtls_cmac_context ctx;
Brian Murray00dc5f02016-05-19 14:23:50 -0700684 int i, ret;
685 unsigned char* tag;
686
687 tag = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Brian Murray57863ad2016-05-19 16:38:36 -0700688 if( tag == NULL ){
689 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
690 goto exit;
691 }
692
Brian Murray00dc5f02016-05-19 14:23:50 -0700693 mbedtls_cmac_init( &ctx );
694
695 if( ( ret = mbedtls_cmac_setkey( &ctx, cipher_id, key, keybits ) ) != 0 )
696 {
697 if( verbose != 0 )
698 mbedtls_printf( " CMAC: setup failed\n" );
699 goto exit;
700 }
701
702 if( ( ret = memcmp( ctx.K1, subkeys, block_size ) != 0 ) ||
703 ( ret = memcmp( ctx.K2, &subkeys[block_size], block_size ) != 0 ) )
704 {
705 if( verbose != 0 )
706 mbedtls_printf( " CMAC: subkey generation failed\n" );
707 goto exit;
708 }
709
710 for( i = 0; i < num_tests; i++ )
711 {
712 if( verbose != 0 )
713 mbedtls_printf( " %s CMAC #%u: ", testname, i +1 );
714
715 if( ( ret = mbedtls_cmac_generate( &ctx, messages, message_lengths[i], tag, block_size ) ) != 0 )
716 {
717 if( verbose != 0 )
718 mbedtls_printf( "failed\n" );
719 goto exit;
720 }
721 if( ( ret = memcmp( tag, &expected_result[i * block_size], block_size ) ) != 0 )
722 {
723 if( verbose != 0 )
724 mbedtls_printf( "failed\n" );
725 goto exit;
726 }
727
728 if( ( ret = mbedtls_cmac_verify( &ctx, messages, message_lengths[i], &expected_result[i * block_size], block_size ) != 0 ) )
729 {
730 if( verbose != 0 )
731 mbedtls_printf( "failed\n" );
732 goto exit;
733 }
734 mbedtls_printf( "passed\n" );
735 }
736 exit:
737 free( tag );
738 mbedtls_cmac_free( &ctx );
739 return( ret );
740}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000741
Brian Murray0f6af732016-05-19 15:59:23 -0700742#ifdef MBEDTLS_AES_C
Brian Murray57863ad2016-05-19 16:38:36 -0700743int test_aes128_cmac_prf( int verbose ) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000744 int i;
745 int ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700746 unsigned char tag[16];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700747 for( i = 0; i < NB_PRF_TESTS; i++ )
748 {
Brian Murray0f6af732016-05-19 15:59:23 -0700749 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
750 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, tag );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700751 if( ret != 0 ||
752 memcmp( tag, PRFT[i], 16 ) != 0 )
753 {
754 if( verbose != 0 )
755 mbedtls_printf( "failed\n" );
756
Brian Murray0f6af732016-05-19 15:59:23 -0700757 return( ret );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700758 } else if( verbose != 0 )
759 {
760 mbedtls_printf( "passed\n" );
761 }
762 }
Brian Murray0f6af732016-05-19 15:59:23 -0700763 return( ret );
764}
765#endif /* MBEDTLS_AES_C */
766
767int mbedtls_cmac_self_test( int verbose )
768{
769 int ret;
770
771#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700772 if( ( ret = test_cmac_with_cipher( verbose,
773 "AES 128",
774 aes_128_key,
775 128,
776 test_message,
777 aes_message_lengths,
Brian Murray57863ad2016-05-19 16:38:36 -0700778 (const unsigned char*) aes_128_subkeys,
779 (const unsigned char*) aes_128_expected_result,
Brian Murray9044b022016-05-19 16:36:56 -0700780 MBEDTLS_CIPHER_ID_AES,
781 AES_BLOCK_SIZE ) !=0 ) )
782 {
783 return( ret );
784 }
Brian Murray0f6af732016-05-19 15:59:23 -0700785
Brian Murray9044b022016-05-19 16:36:56 -0700786 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700787 "AES 192",
788 aes_192_key,
789 192,
790 test_message,
791 aes_message_lengths,
792 (const unsigned char*) aes_192_subkeys,
793 (const unsigned char*) aes_192_expected_result,
794 MBEDTLS_CIPHER_ID_AES,
795 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700796 {
797 return( ret );
798 }
Brian Murray0f6af732016-05-19 15:59:23 -0700799
Brian Murray9044b022016-05-19 16:36:56 -0700800 if( ( ret = test_cmac_with_cipher ( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700801 "AES 256",
802 aes_256_key,
803 256,
804 test_message,
805 aes_message_lengths,
806 (const unsigned char*) aes_256_subkeys,
807 (const unsigned char*) aes_256_expected_result,
808 MBEDTLS_CIPHER_ID_AES,
809 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700810 {
811 return( ret );
812 }
Brian Murray0f6af732016-05-19 15:59:23 -0700813#endif /* MBEDTLS_AES_C */
814
815#ifdef MBEDTLS_DES_C
Brian Murray9044b022016-05-19 16:36:56 -0700816 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700817 "3DES 2 key",
818 des3_2key_key,
819 192,
820 test_message,
821 des3_message_lengths,
822 (const unsigned char*) des3_2key_subkeys,
823 (const unsigned char*) des3_2key_expected_result,
824 MBEDTLS_CIPHER_ID_3DES,
825 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700826 {
827 return( ret );
828 }
Brian Murray0f6af732016-05-19 15:59:23 -0700829
Brian Murray9044b022016-05-19 16:36:56 -0700830 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700831 "3DES 3 key",
832 des3_3key_key,
833 192,
834 test_message,
835 des3_message_lengths,
836 (const unsigned char*) des3_3key_subkeys,
837 (const unsigned char*) des3_3key_expected_result,
838 MBEDTLS_CIPHER_ID_3DES,
839 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700840 {
841 return( ret );
842 }
Brian Murray0f6af732016-05-19 15:59:23 -0700843#endif /* MBEDTLS_DES_C */
844
845#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700846 if( ( ret = test_aes128_cmac_prf( verbose ) != 0 ) )
847 return( ret );
848
Brian Murray0f6af732016-05-19 15:59:23 -0700849#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700850
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000851 if( verbose != 0 )
852 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -0700853
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000854 return( 0 );
855}
856
Brian Murray0f6af732016-05-19 15:59:23 -0700857#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000858
859#endif /* MBEDTLS_CMAC_C */