blob: 09a705d650ff641af707050a68afe02690ab0140 [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 Murrayb0c3c432016-05-18 14:29:51 -070065 * As explained in the paper, this can 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/*
248 * Update the CMAC state using an input block x
249 */
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
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000286 /*
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000287 * Check in_len requirements: SP800-38B A
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000288 * 4 is a worst case bottom limit
289 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700290 if( tag_len < 4 || tag_len > block_size || tag_len % 2 != 0 )
Brian Murray57863ad2016-05-19 16:38:36 -0700291 {
292 ret = MBEDTLS_ERR_CMAC_BAD_INPUT;
293 goto exit;
294 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000295
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000296 if( in_len == 0 )
297 needs_padding = 1;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000298 else
Brian Murrayb0c3c432016-05-18 14:29:51 -0700299 needs_padding = in_len % block_size != 0;
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000300
Brian Murrayb0c3c432016-05-18 14:29:51 -0700301 n = in_len / block_size + needs_padding;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000302
303 /* Calculate last block */
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000304 if( needs_padding )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000305 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700306 cmac_pad( M_last, block_size, input + block_size * ( n - 1 ), in_len % block_size );
307 XOR_BLOCK( M_last, M_last, ctx->K2 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000308 }
309 else
310 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000311 /* Last block is complete block */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700312 XOR_BLOCK( M_last, input + block_size * ( n - 1 ), ctx->K1 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000313 }
314
Brian Murrayb0c3c432016-05-18 14:29:51 -0700315 memset( state, 0, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000316
317 for( j = 0; j < n - 1; j++ )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700318 UPDATE_CMAC( input + block_size * j );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000319
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000320 UPDATE_CMAC( M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000321
Brian Murray00dc5f02016-05-19 14:23:50 -0700322 memcpy( tag, state, tag_len );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000323
Brian Murrayb0c3c432016-05-18 14:29:51 -0700324 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700325 free( state );
326 free( M_last );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700327 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000328}
329
Brian Murrayb0c3c432016-05-18 14:29:51 -0700330#undef XOR_BLOCK
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000331#undef UPDATE_CMAC
332
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000333/*
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000334 * Verify tag on complete message
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000335 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000336int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
337 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000338 const unsigned char *tag, size_t tag_len )
339{
340 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700341 unsigned char *check_tag;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000342 unsigned char i;
343 int diff;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000344
Brian Murrayb439d452016-05-19 16:02:42 -0700345 check_tag = mbedtls_calloc( ctx->cipher_ctx.cipher_info->block_size,
346 sizeof( unsigned char ) );
Brian Murray57863ad2016-05-19 16:38:36 -0700347 if(check_tag == NULL)
348 {
349 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
350 goto exit;
351 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700352
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000353 if( ( ret = mbedtls_cmac_generate( ctx, input, in_len,
354 check_tag, tag_len ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000355 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700356 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000357 }
358
359 /* Check tag in "constant-time" */
360 for( diff = 0, i = 0; i < tag_len; i++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000361 diff |= tag[i] ^ check_tag[i];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000362
363 if( diff != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700364 ret = MBEDTLS_ERR_CMAC_VERIFY_FAILED;
365 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000366
Brian Murrayb0c3c432016-05-18 14:29:51 -0700367 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700368 free( check_tag );
369 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000370}
371
Brian Murrayb439d452016-05-19 16:02:42 -0700372#ifdef MBEDTLS_AES_C
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000373/*
374 * PRF based on CMAC with AES-128
Brian Murrayb0c3c432016-05-18 14:29:51 -0700375 * See RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000376 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700377int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000378 const unsigned char *input, size_t in_len,
Brian Murrayb439d452016-05-19 16:02:42 -0700379 unsigned char tag[16] )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000380{
381 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700382 mbedtls_cmac_context ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000383 unsigned char zero_key[16];
384 unsigned char int_key[16];
385
Brian Murrayb439d452016-05-19 16:02:42 -0700386 mbedtls_cmac_init(&ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700387
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000388 if( key_length == 16 )
389 {
390 /* Use key as is */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000391 memcpy( int_key, key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000392 }
393 else
394 {
395 mbedtls_cmac_context zero_ctx;
396
Brian Murrayb439d452016-05-19 16:02:42 -0700397 /* Key is AES_CMAC( 0, key ) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000398 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000399 memset( zero_key, 0, 16 );
400 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
401 zero_key, 8 * sizeof zero_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000402 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700403 goto exit;
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000404
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000405 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000406 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700407 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000408 }
409
Brian Murrayb0c3c432016-05-18 14:29:51 -0700410 ret = mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000411 int_key, 8 * sizeof int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000412 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700413 goto exit;
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000414
415 mbedtls_zeroize( int_key, sizeof( int_key ) );
416
Brian Murrayb0c3c432016-05-18 14:29:51 -0700417 ret = mbedtls_cmac_generate( &ctx, input, in_len, tag, 16 );
418
419 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700420 mbedtls_cmac_free( &ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700421 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000422}
Brian Murrayb439d452016-05-19 16:02:42 -0700423#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000424
Brian Murray0f6af732016-05-19 15:59:23 -0700425#ifdef MBEDTLS_SELF_TEST
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000426/*
Brian Murray0f6af732016-05-19 15:59:23 -0700427 * CMAC test data from SP800-38B Appendix D.1 (corrected)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000428 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700429 *
430 * AES-CMAC-PRF-128 test data from RFC 4615
431 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000432 */
433
Brian Murray0f6af732016-05-19 15:59:23 -0700434#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000435#define NB_PRF_TESTS 3
Brian Murray0f6af732016-05-19 15:59:23 -0700436#define AES_BLOCK_SIZE 16
437#define DES3_BLOCK_SIZE 8
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000438
Brian Murray0f6af732016-05-19 15:59:23 -0700439#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
440/* All CMAC test inputs are truncated from the same 64 byte buffer. */
441static const unsigned char test_message[] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000442 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
443 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
444 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
445 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
446 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
447 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
448 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
449 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
450};
Brian Murray0f6af732016-05-19 15:59:23 -0700451#endif /* defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000452
Brian Murray0f6af732016-05-19 15:59:23 -0700453#ifdef MBEDTLS_AES_C
454/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700455static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700456 0,
457 16,
458 40,
459 64
460};
461
462/* AES 128 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700463static const unsigned char aes_128_key[16] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700464 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
465 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
466};
467static const unsigned char aes_128_subkeys[2][AES_BLOCK_SIZE] = {
468 {
469 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
470 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
471 },
472 {
473 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
474 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
475 }
476};
477static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000478 {
479 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
480 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
481 },
482 {
483 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
484 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
485 },
486 {
487 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
488 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
489 },
490 {
491 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
492 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
493 }
494};
495
Brian Murray0f6af732016-05-19 15:59:23 -0700496/* AES 192 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700497static const unsigned char aes_192_key[24] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700498 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
499 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
500 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000501};
Brian Murray0f6af732016-05-19 15:59:23 -0700502static const unsigned char aes_192_subkeys[2][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700503 {
Brian Murray0f6af732016-05-19 15:59:23 -0700504 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
505 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700506 },
507 {
Brian Murray0f6af732016-05-19 15:59:23 -0700508 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
509 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700510 }
511};
Brian Murray0f6af732016-05-19 15:59:23 -0700512static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700513 {
514 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
515 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
516 },
517 {
518 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
519 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
520 },
521 {
522 0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad,
523 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e
524 },
525 {
526 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
527 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
528 }
529};
530
Brian Murray0f6af732016-05-19 15:59:23 -0700531/* AES 256 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700532static const unsigned char aes_256_key[32] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700533 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
534 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
535 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
536 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
537};
538static const unsigned char aes_256_subkeys[2][AES_BLOCK_SIZE] = {
539 {
540 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
541 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
542 },
543 {
544 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
545 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
546 }
547};
548static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
549 {
550 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
551 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
552 },
553 {
554 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
555 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
556 },
557 {
558 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
559 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6
560 },
561 {
562 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
563 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
564 }
565};
566#endif /* MBEDTLS_AES_C */
567
568#ifdef MBEDTLS_DES_C
569/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700570static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700571 0,
572 8,
573 20,
574 32
575};
576
577/* 3DES 2 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700578static const unsigned char des3_2key_key[24] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700579 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5,
580 0x8a, 0x3d, 0x10, 0xba, 0x80, 0x57, 0x0d, 0x38,
581 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5
582};
583static const unsigned char des3_2key_subkeys[2][8] = {
584 {
585 0x8e, 0xcf, 0x37, 0x3e, 0xd7, 0x1a, 0xfa, 0xef
586 },
587 {
588 0x1d, 0x9e, 0x6e, 0x7d, 0xae, 0x35, 0xf5, 0xc5
589 }
590};
Brian Murray57863ad2016-05-19 16:38:36 -0700591static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700592 {
593 0xbd, 0x2e, 0xbf, 0x9a, 0x3b, 0xa0, 0x03, 0x61
594 },
595 {
596 0x4f, 0xf2, 0xab, 0x81, 0x3c, 0x53, 0xce, 0x83
597 },
598 {
599 0x62, 0xdd, 0x1b, 0x47, 0x19, 0x02, 0xbd, 0x4e
600 },
601 {
602 0x31, 0xb1, 0xe4, 0x31, 0xda, 0xbc, 0x4e, 0xb8
603 }
604};
605
Brian Murray0f6af732016-05-19 15:59:23 -0700606/* 3DES 3 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700607static const unsigned char des3_3key_key[24] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700608 0x8a, 0xa8, 0x3b, 0xf8, 0xcb, 0xda, 0x10, 0x62,
609 0x0b, 0xc1, 0xbf, 0x19, 0xfb, 0xb6, 0xcd, 0x58,
610 0xbc, 0x31, 0x3d, 0x4a, 0x37, 0x1c, 0xa8, 0xb5
611};
612static const unsigned char des3_3key_subkeys[2][8] = {
613 {
614 0x91, 0x98, 0xe9, 0xd3, 0x14, 0xe6, 0x53, 0x5f
615 },
616 {
617 0x23, 0x31, 0xd3, 0xa6, 0x29, 0xcc, 0xa6, 0xa5
618 }
619};
Brian Murray57863ad2016-05-19 16:38:36 -0700620static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700621 {
622 0xb7, 0xa6, 0x88, 0xe1, 0x22, 0xff, 0xaf, 0x95
623 },
624 {
625 0x8e, 0x8f, 0x29, 0x31, 0x36, 0x28, 0x37, 0x97
626 },
627 {
628 0x74, 0x3d, 0xdb, 0xe0, 0xce, 0x2d, 0xc2, 0xed
629 },
630 {
631 0x33, 0xe6, 0xb1, 0x09, 0x24, 0x00, 0xea, 0xe5
632 }
633};
634
Brian Murray0f6af732016-05-19 15:59:23 -0700635#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700636
Brian Murray0f6af732016-05-19 15:59:23 -0700637#ifdef MBEDTLS_AES_C
638/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000639static const unsigned char PRFK[] = {
640 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
641 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
642 0xed, 0xcb
643};
644
645/* Sizes in bytes */
646static const size_t PRFKlen[NB_PRF_TESTS] = {
647 18,
648 16,
649 10
650};
651
652/* PRF M */
653static const unsigned char PRFM[] = {
654 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
655 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000656 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000657};
658
659static const unsigned char PRFT[NB_PRF_TESTS][16] = {
660 {
661 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
662 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
663 },
664 {
665 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
666 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
667 },
668 {
669 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
670 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
671 }
672};
Brian Murray0f6af732016-05-19 15:59:23 -0700673#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000674
Brian Murrayb439d452016-05-19 16:02:42 -0700675int test_cmac_with_cipher( int verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700676 char* testname,
Brian Murray00dc5f02016-05-19 14:23:50 -0700677 const unsigned char* key,
678 int keybits,
679 const unsigned char* messages,
Brian Murray57863ad2016-05-19 16:38:36 -0700680 const unsigned int message_lengths[4],
Brian Murray00dc5f02016-05-19 14:23:50 -0700681 const unsigned char* subkeys,
682 const unsigned char* expected_result,
683 mbedtls_cipher_id_t cipher_id,
Brian Murrayb439d452016-05-19 16:02:42 -0700684 int block_size )
Brian Murray00dc5f02016-05-19 14:23:50 -0700685{
686 const int num_tests = 4;
687 mbedtls_cmac_context ctx;
688 int i, ret;
689 unsigned char* tag;
690
691 tag = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Brian Murray57863ad2016-05-19 16:38:36 -0700692 if( tag == NULL ){
693 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
694 goto exit;
695 }
696
Brian Murray00dc5f02016-05-19 14:23:50 -0700697 mbedtls_cmac_init( &ctx );
698
699 if( ( ret = mbedtls_cmac_setkey( &ctx, cipher_id, key, keybits ) ) != 0 )
700 {
701 if( verbose != 0 )
702 mbedtls_printf( " CMAC: setup failed\n" );
703 goto exit;
704 }
705
706 if( ( ret = memcmp( ctx.K1, subkeys, block_size ) != 0 ) ||
707 ( ret = memcmp( ctx.K2, &subkeys[block_size], block_size ) != 0 ) )
708 {
709 if( verbose != 0 )
710 mbedtls_printf( " CMAC: subkey generation failed\n" );
711 goto exit;
712 }
713
714 for( i = 0; i < num_tests; i++ )
715 {
716 if( verbose != 0 )
717 mbedtls_printf( " %s CMAC #%u: ", testname, i +1 );
718
719 if( ( ret = mbedtls_cmac_generate( &ctx, messages, message_lengths[i], tag, block_size ) ) != 0 )
720 {
721 if( verbose != 0 )
722 mbedtls_printf( "failed\n" );
723 goto exit;
724 }
725 if( ( ret = memcmp( tag, &expected_result[i * block_size], block_size ) ) != 0 )
726 {
727 if( verbose != 0 )
728 mbedtls_printf( "failed\n" );
729 goto exit;
730 }
731
732 if( ( ret = mbedtls_cmac_verify( &ctx, messages, message_lengths[i], &expected_result[i * block_size], block_size ) != 0 ) )
733 {
734 if( verbose != 0 )
735 mbedtls_printf( "failed\n" );
736 goto exit;
737 }
738 mbedtls_printf( "passed\n" );
739 }
740 exit:
741 free( tag );
742 mbedtls_cmac_free( &ctx );
743 return( ret );
744}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000745
Brian Murray0f6af732016-05-19 15:59:23 -0700746#ifdef MBEDTLS_AES_C
Brian Murray57863ad2016-05-19 16:38:36 -0700747int test_aes128_cmac_prf( int verbose ) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000748 int i;
749 int ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700750 unsigned char tag[16];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700751 for( i = 0; i < NB_PRF_TESTS; i++ )
752 {
Brian Murray0f6af732016-05-19 15:59:23 -0700753 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
754 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, tag );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700755 if( ret != 0 ||
756 memcmp( tag, PRFT[i], 16 ) != 0 )
757 {
758 if( verbose != 0 )
759 mbedtls_printf( "failed\n" );
760
Brian Murray0f6af732016-05-19 15:59:23 -0700761 return( ret );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700762 } else if( verbose != 0 )
763 {
764 mbedtls_printf( "passed\n" );
765 }
766 }
Brian Murray0f6af732016-05-19 15:59:23 -0700767 return( ret );
768}
769#endif /* MBEDTLS_AES_C */
770
771int mbedtls_cmac_self_test( int verbose )
772{
773 int ret;
774
775#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700776 if( ( ret = test_cmac_with_cipher( verbose,
777 "AES 128",
778 aes_128_key,
779 128,
780 test_message,
781 aes_message_lengths,
Brian Murray57863ad2016-05-19 16:38:36 -0700782 (const unsigned char*) aes_128_subkeys,
783 (const unsigned char*) aes_128_expected_result,
Brian Murray9044b022016-05-19 16:36:56 -0700784 MBEDTLS_CIPHER_ID_AES,
785 AES_BLOCK_SIZE ) !=0 ) )
786 {
787 return( ret );
788 }
Brian Murray0f6af732016-05-19 15:59:23 -0700789
Brian Murray9044b022016-05-19 16:36:56 -0700790 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700791 "AES 192",
792 aes_192_key,
793 192,
794 test_message,
795 aes_message_lengths,
796 (const unsigned char*) aes_192_subkeys,
797 (const unsigned char*) aes_192_expected_result,
798 MBEDTLS_CIPHER_ID_AES,
799 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700800 {
801 return( ret );
802 }
Brian Murray0f6af732016-05-19 15:59:23 -0700803
Brian Murray9044b022016-05-19 16:36:56 -0700804 if( ( ret = test_cmac_with_cipher ( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700805 "AES 256",
806 aes_256_key,
807 256,
808 test_message,
809 aes_message_lengths,
810 (const unsigned char*) aes_256_subkeys,
811 (const unsigned char*) aes_256_expected_result,
812 MBEDTLS_CIPHER_ID_AES,
813 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700814 {
815 return( ret );
816 }
Brian Murray0f6af732016-05-19 15:59:23 -0700817#endif /* MBEDTLS_AES_C */
818
819#ifdef MBEDTLS_DES_C
Brian Murray9044b022016-05-19 16:36:56 -0700820 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700821 "3DES 2 key",
822 des3_2key_key,
823 192,
824 test_message,
825 des3_message_lengths,
826 (const unsigned char*) des3_2key_subkeys,
827 (const unsigned char*) des3_2key_expected_result,
828 MBEDTLS_CIPHER_ID_3DES,
829 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700830 {
831 return( ret );
832 }
Brian Murray0f6af732016-05-19 15:59:23 -0700833
Brian Murray9044b022016-05-19 16:36:56 -0700834 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700835 "3DES 3 key",
836 des3_3key_key,
837 192,
838 test_message,
839 des3_message_lengths,
840 (const unsigned char*) des3_3key_subkeys,
841 (const unsigned char*) des3_3key_expected_result,
842 MBEDTLS_CIPHER_ID_3DES,
843 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700844 {
845 return( ret );
846 }
Brian Murray0f6af732016-05-19 15:59:23 -0700847#endif /* MBEDTLS_DES_C */
848
849#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700850 if( ( ret = test_aes128_cmac_prf( verbose ) != 0 ) )
851 return( ret );
852
Brian Murray0f6af732016-05-19 15:59:23 -0700853#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700854
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000855 if( verbose != 0 )
856 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -0700857
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000858 return( 0 );
859}
860
Brian Murray0f6af732016-05-19 15:59:23 -0700861#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000862
863#endif /* MBEDTLS_CMAC_C */