blob: 39ebb8709855be9a66947c9bfce899369cb6431e [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
Brian Murray00dc5f02016-05-19 14:23:50 -070062
Robert Cragie3d23b1d2015-12-15 07:38:11 +000063/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070064 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000065 *
Brian Murrayb0c3c432016-05-18 14:29:51 -070066 * As explained in the paper, this can computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000067 * If MSB(p) = 0, then p = (p << 1)
Brian Murrayb0c3c432016-05-18 14:29:51 -070068 * If MSB(p) = 1, then p = (p << 1) ^ R_n
69 * with R_64 = 0x1B and R_128 = 0x87
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000070 *
71 * Input and output MUST not point to the same buffer
Brian Murrayb0c3c432016-05-18 14:29:51 -070072 * Block size must be 8 byes or 16 bytes.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000073 */
Brian Murrayb0c3c432016-05-18 14:29:51 -070074static int cmac_multiply_by_u( unsigned char *output,
75 const unsigned char *input,
Brian Murrayb439d452016-05-19 16:02:42 -070076 size_t blocksize )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000077{
Robert Cragie3d23b1d2015-12-15 07:38:11 +000078
Brian Murrayb0c3c432016-05-18 14:29:51 -070079 const unsigned char R_128 = 0x87;
80 const unsigned char R_64 = 0x1B;
81 unsigned char R_n, mask;
82 unsigned char overflow = 0x00;
83 int i, starting_index;
84
85 starting_index = blocksize -1;
86
Brian Murrayb439d452016-05-19 16:02:42 -070087 if( blocksize == 16 ){
Brian Murrayb0c3c432016-05-18 14:29:51 -070088 R_n = R_128;
Brian Murrayb439d452016-05-19 16:02:42 -070089 } else if( blocksize == 8 ) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070090 R_n = R_64;
91 } else {
Brian Murrayb439d452016-05-19 16:02:42 -070092 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
Brian Murrayb0c3c432016-05-18 14:29:51 -070093 }
94
95
96 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
128 ret = 0;
129 block_size = ctx->cipher_ctx.cipher_info->block_size;
130
Brian Murrayb439d452016-05-19 16:02:42 -0700131 L = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Brian Murray57863ad2016-05-19 16:38:36 -0700132 if( L == NULL)
133 {
134 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
135 goto exit;
136 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000137 /* Calculate Ek(0) */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700138 memset( L, 0, block_size );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000139 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700140 L, block_size, L, &olen ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000141 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700142 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000143 }
144
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000145 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000146 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000147 */
Brian Murrayb439d452016-05-19 16:02:42 -0700148 if( ( ret = cmac_multiply_by_u( ctx->K1, L , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700149 goto exit;
Brian Murrayb439d452016-05-19 16:02:42 -0700150 if( ( cmac_multiply_by_u( ctx->K2, ctx->K1 , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700151 goto exit;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000152
Brian Murrayb0c3c432016-05-18 14:29:51 -0700153 exit:
Brian Murray57863ad2016-05-19 16:38:36 -0700154 if( L != NULL )
155 mbedtls_zeroize( L, sizeof( L ) );
Brian Murrayb439d452016-05-19 16:02:42 -0700156 free( L );
157 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000158}
159
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000160/*
161 * Set key and prepare context for use
162 */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000163int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx,
164 mbedtls_cipher_id_t cipher,
165 const unsigned char *key,
166 unsigned int keybits )
167{
Brian Murray57863ad2016-05-19 16:38:36 -0700168 int ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000169 const mbedtls_cipher_info_t *cipher_info;
170
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000171 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
172 MBEDTLS_MODE_ECB );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000173 if( cipher_info == NULL )
174 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
175
Brian Murrayb0c3c432016-05-18 14:29:51 -0700176 ctx->K1 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) );
177 ctx->K2 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000178
Brian Murray57863ad2016-05-19 16:38:36 -0700179 if(ctx->K1 == NULL || ctx->K2 == NULL )
180 return MBEDTLS_ERR_CMAC_ALLOC_FAILED;
181
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000182 mbedtls_cipher_free( &ctx->cipher_ctx );
183
184 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
185 return( ret );
186
187 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000188 MBEDTLS_ENCRYPT ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000189 {
190 return( ret );
191 }
192
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000193 return( cmac_generate_subkeys( ctx ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000194}
195
196/*
197 * Free context
198 */
199void mbedtls_cmac_free( mbedtls_cmac_context *ctx )
200{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700201 int block_size;
202 block_size = ctx->cipher_ctx.cipher_info->block_size;
203
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000204 mbedtls_cipher_free( &ctx->cipher_ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700205
Brian Murrayb439d452016-05-19 16:02:42 -0700206 mbedtls_zeroize( ctx->K1, block_size * sizeof( unsigned char ) );
207 mbedtls_zeroize( ctx->K2, block_size * sizeof( unsigned char ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700208 mbedtls_free( ctx->K1 );
209 mbedtls_free( ctx->K2 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000210}
211
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000212/*
213 * Create padded last block from (partial) last block.
214 *
215 * We can't use the padding option from the cipher layer, as it only works for
216 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
217 */
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000218static void cmac_pad( unsigned char padded_block[16],
Brian Murrayb0c3c432016-05-18 14:29:51 -0700219 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000220 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700221 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000222{
223 size_t j;
224
Brian Murrayb0c3c432016-05-18 14:29:51 -0700225 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000226 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700227 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000228 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700229 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000230 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000231 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000232 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000233 }
234}
235
236/*
Brian Murrayb0c3c432016-05-18 14:29:51 -0700237 * XOR Block
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000238 * Here, macro results in smaller compiled code than static inline function
239 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700240#define XOR_BLOCK( o, i1, i2 ) \
241 for( i = 0; i < block_size; i++ ) \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000242 ( o )[i] = ( i1 )[i] ^ ( i2 )[i];
243
244/*
245 * Update the CMAC state using an input block x
246 */
247#define UPDATE_CMAC( x ) \
248do { \
Brian Murrayb0c3c432016-05-18 14:29:51 -0700249 XOR_BLOCK( state, ( x ), state ); \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000250 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, \
Brian Murrayb0c3c432016-05-18 14:29:51 -0700251 state, block_size, \
252 state, &olen ) ) != 0 ) \
Brian Murray57863ad2016-05-19 16:38:36 -0700253 { \
254 goto exit; \
255 } \
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000256} while( 0 )
257
258/*
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000259 * Generate tag on complete message
260 */
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000261int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
262 const unsigned char *input, size_t in_len,
263 unsigned char *tag, size_t tag_len )
264
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000265{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700266
267 unsigned char *state;
268 unsigned char *M_last;
Brian Murray57863ad2016-05-19 16:38:36 -0700269 int n, j, ret, needs_padding;
270 size_t olen, block_size, i;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700271
272
273 ret = 0;
274 block_size = ctx->cipher_ctx.cipher_info->block_size;
275
Brian Murrayb439d452016-05-19 16:02:42 -0700276 state = mbedtls_calloc( block_size, sizeof( unsigned char ) );
277 M_last = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000278
Brian Murray57863ad2016-05-19 16:38:36 -0700279 if( state == NULL || M_last == NULL )
280 {
281 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
282 goto exit;
283 }
284
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000285 /*
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000286 * Check in_len requirements: SP800-38B A
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000287 * 4 is a worst case bottom limit
288 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700289 if( tag_len < 4 || tag_len > block_size || tag_len % 2 != 0 )
Brian Murray57863ad2016-05-19 16:38:36 -0700290 {
291 ret = MBEDTLS_ERR_CMAC_BAD_INPUT;
292 goto exit;
293 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000294
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000295 if( in_len == 0 )
296 needs_padding = 1;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000297 else
Brian Murrayb0c3c432016-05-18 14:29:51 -0700298 needs_padding = in_len % block_size != 0;
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000299
Brian Murrayb0c3c432016-05-18 14:29:51 -0700300 n = in_len / block_size + needs_padding;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000301
302 /* Calculate last block */
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000303 if( needs_padding )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000304 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700305 cmac_pad( M_last, block_size, input + block_size * ( n - 1 ), in_len % block_size );
306 XOR_BLOCK( M_last, M_last, ctx->K2 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000307 }
308 else
309 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000310 /* Last block is complete block */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700311 XOR_BLOCK( M_last, input + block_size * ( n - 1 ), ctx->K1 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000312 }
313
Brian Murrayb0c3c432016-05-18 14:29:51 -0700314 memset( state, 0, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000315
316 for( j = 0; j < n - 1; j++ )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700317 UPDATE_CMAC( input + block_size * j );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000318
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000319 UPDATE_CMAC( M_last );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000320
Brian Murray00dc5f02016-05-19 14:23:50 -0700321 memcpy( tag, state, tag_len );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000322
Brian Murrayb0c3c432016-05-18 14:29:51 -0700323 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700324 free( state );
325 free( M_last );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700326 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000327}
328
Brian Murrayb0c3c432016-05-18 14:29:51 -0700329#undef XOR_BLOCK
Manuel Pégourié-Gonnardd18c7072016-01-13 15:03:05 +0000330#undef UPDATE_CMAC
331
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000332/*
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000333 * Verify tag on complete message
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000334 */
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000335int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
336 const unsigned char *input, size_t in_len,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000337 const unsigned char *tag, size_t tag_len )
338{
339 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700340 unsigned char *check_tag;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000341 unsigned char i;
342 int diff;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000343
Brian Murrayb439d452016-05-19 16:02:42 -0700344 check_tag = mbedtls_calloc( ctx->cipher_ctx.cipher_info->block_size,
345 sizeof( unsigned char ) );
Brian Murray57863ad2016-05-19 16:38:36 -0700346 if(check_tag == NULL)
347 {
348 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
349 goto exit;
350 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700351
Manuel Pégourié-Gonnardab9c5fd2016-01-13 15:05:57 +0000352 if( ( ret = mbedtls_cmac_generate( ctx, input, in_len,
353 check_tag, tag_len ) ) != 0 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000354 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700355 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000356 }
357
358 /* Check tag in "constant-time" */
359 for( diff = 0, i = 0; i < tag_len; i++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000360 diff |= tag[i] ^ check_tag[i];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000361
362 if( diff != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700363 ret = MBEDTLS_ERR_CMAC_VERIFY_FAILED;
364 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000365
Brian Murrayb0c3c432016-05-18 14:29:51 -0700366 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700367 free( check_tag );
368 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000369}
370
Brian Murrayb439d452016-05-19 16:02:42 -0700371#ifdef MBEDTLS_AES_C
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000372/*
373 * PRF based on CMAC with AES-128
Brian Murrayb0c3c432016-05-18 14:29:51 -0700374 * See RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000375 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700376int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000377 const unsigned char *input, size_t in_len,
Brian Murrayb439d452016-05-19 16:02:42 -0700378 unsigned char tag[16] )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000379{
380 int ret;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700381 mbedtls_cmac_context ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000382 unsigned char zero_key[16];
383 unsigned char int_key[16];
384
Brian Murrayb439d452016-05-19 16:02:42 -0700385 mbedtls_cmac_init(&ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700386
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000387 if( key_length == 16 )
388 {
389 /* Use key as is */
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000390 memcpy( int_key, key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000391 }
392 else
393 {
394 mbedtls_cmac_context zero_ctx;
395
Brian Murrayb439d452016-05-19 16:02:42 -0700396 /* Key is AES_CMAC( 0, key ) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000397 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000398 memset( zero_key, 0, 16 );
399 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
400 zero_key, 8 * sizeof zero_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000401 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700402 goto exit;
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000403
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000404 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000405 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700406 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000407 }
408
Brian Murrayb0c3c432016-05-18 14:29:51 -0700409 ret = mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000410 int_key, 8 * sizeof int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000411 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700412 goto exit;
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000413
414 mbedtls_zeroize( int_key, sizeof( int_key ) );
415
Brian Murrayb0c3c432016-05-18 14:29:51 -0700416 ret = mbedtls_cmac_generate( &ctx, input, in_len, tag, 16 );
417
418 exit:
Brian Murrayb439d452016-05-19 16:02:42 -0700419 mbedtls_cmac_free( &ctx );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700420 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000421}
Brian Murrayb439d452016-05-19 16:02:42 -0700422#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000423
Brian Murray0f6af732016-05-19 15:59:23 -0700424#ifdef MBEDTLS_SELF_TEST
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000425/*
Brian Murray0f6af732016-05-19 15:59:23 -0700426 * CMAC test data from SP800-38B Appendix D.1 (corrected)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000427 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700428 *
429 * AES-CMAC-PRF-128 test data from RFC 4615
430 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000431 */
432
Brian Murray0f6af732016-05-19 15:59:23 -0700433#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000434#define NB_PRF_TESTS 3
Brian Murray0f6af732016-05-19 15:59:23 -0700435#define AES_BLOCK_SIZE 16
436#define DES3_BLOCK_SIZE 8
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000437
Brian Murray0f6af732016-05-19 15:59:23 -0700438#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
439/* All CMAC test inputs are truncated from the same 64 byte buffer. */
440static const unsigned char test_message[] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000441 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
442 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
443 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
444 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
445 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
446 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
447 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
448 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
449};
Brian Murray0f6af732016-05-19 15:59:23 -0700450#endif /* defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000451
Brian Murray0f6af732016-05-19 15:59:23 -0700452#ifdef MBEDTLS_AES_C
453/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700454static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700455 0,
456 16,
457 40,
458 64
459};
460
461/* AES 128 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700462static const unsigned char aes_128_key[16] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700463 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
464 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
465};
466static const unsigned char aes_128_subkeys[2][AES_BLOCK_SIZE] = {
467 {
468 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
469 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
470 },
471 {
472 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
473 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
474 }
475};
476static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000477 {
478 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
479 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
480 },
481 {
482 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
483 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
484 },
485 {
486 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
487 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
488 },
489 {
490 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
491 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
492 }
493};
494
Brian Murray0f6af732016-05-19 15:59:23 -0700495/* AES 192 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700496static const unsigned char aes_192_key[24] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700497 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
498 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
499 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000500};
Brian Murray0f6af732016-05-19 15:59:23 -0700501static const unsigned char aes_192_subkeys[2][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700502 {
Brian Murray0f6af732016-05-19 15:59:23 -0700503 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
504 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700505 },
506 {
Brian Murray0f6af732016-05-19 15:59:23 -0700507 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
508 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700509 }
510};
Brian Murray0f6af732016-05-19 15:59:23 -0700511static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700512 {
513 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
514 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
515 },
516 {
517 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
518 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
519 },
520 {
521 0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad,
522 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e
523 },
524 {
525 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
526 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
527 }
528};
529
Brian Murray0f6af732016-05-19 15:59:23 -0700530/* AES 256 CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700531static const unsigned char aes_256_key[32] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700532 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
533 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
534 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
535 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
536};
537static const unsigned char aes_256_subkeys[2][AES_BLOCK_SIZE] = {
538 {
539 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
540 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
541 },
542 {
543 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
544 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
545 }
546};
547static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
548 {
549 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
550 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
551 },
552 {
553 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
554 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
555 },
556 {
557 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
558 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6
559 },
560 {
561 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
562 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
563 }
564};
565#endif /* MBEDTLS_AES_C */
566
567#ifdef MBEDTLS_DES_C
568/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700569static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700570 0,
571 8,
572 20,
573 32
574};
575
576/* 3DES 2 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700577static const unsigned char des3_2key_key[24] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700578 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5,
579 0x8a, 0x3d, 0x10, 0xba, 0x80, 0x57, 0x0d, 0x38,
580 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5
581};
582static const unsigned char des3_2key_subkeys[2][8] = {
583 {
584 0x8e, 0xcf, 0x37, 0x3e, 0xd7, 0x1a, 0xfa, 0xef
585 },
586 {
587 0x1d, 0x9e, 0x6e, 0x7d, 0xae, 0x35, 0xf5, 0xc5
588 }
589};
Brian Murray57863ad2016-05-19 16:38:36 -0700590static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700591 {
592 0xbd, 0x2e, 0xbf, 0x9a, 0x3b, 0xa0, 0x03, 0x61
593 },
594 {
595 0x4f, 0xf2, 0xab, 0x81, 0x3c, 0x53, 0xce, 0x83
596 },
597 {
598 0x62, 0xdd, 0x1b, 0x47, 0x19, 0x02, 0xbd, 0x4e
599 },
600 {
601 0x31, 0xb1, 0xe4, 0x31, 0xda, 0xbc, 0x4e, 0xb8
602 }
603};
604
Brian Murray0f6af732016-05-19 15:59:23 -0700605/* 3DES 3 Key CMAC Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700606static const unsigned char des3_3key_key[24] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700607 0x8a, 0xa8, 0x3b, 0xf8, 0xcb, 0xda, 0x10, 0x62,
608 0x0b, 0xc1, 0xbf, 0x19, 0xfb, 0xb6, 0xcd, 0x58,
609 0xbc, 0x31, 0x3d, 0x4a, 0x37, 0x1c, 0xa8, 0xb5
610};
611static const unsigned char des3_3key_subkeys[2][8] = {
612 {
613 0x91, 0x98, 0xe9, 0xd3, 0x14, 0xe6, 0x53, 0x5f
614 },
615 {
616 0x23, 0x31, 0xd3, 0xa6, 0x29, 0xcc, 0xa6, 0xa5
617 }
618};
Brian Murray57863ad2016-05-19 16:38:36 -0700619static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700620 {
621 0xb7, 0xa6, 0x88, 0xe1, 0x22, 0xff, 0xaf, 0x95
622 },
623 {
624 0x8e, 0x8f, 0x29, 0x31, 0x36, 0x28, 0x37, 0x97
625 },
626 {
627 0x74, 0x3d, 0xdb, 0xe0, 0xce, 0x2d, 0xc2, 0xed
628 },
629 {
630 0x33, 0xe6, 0xb1, 0x09, 0x24, 0x00, 0xea, 0xe5
631 }
632};
633
Brian Murray0f6af732016-05-19 15:59:23 -0700634#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700635
Brian Murray0f6af732016-05-19 15:59:23 -0700636#ifdef MBEDTLS_AES_C
637/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000638static const unsigned char PRFK[] = {
639 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
640 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
641 0xed, 0xcb
642};
643
644/* Sizes in bytes */
645static const size_t PRFKlen[NB_PRF_TESTS] = {
646 18,
647 16,
648 10
649};
650
651/* PRF M */
652static const unsigned char PRFM[] = {
653 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
654 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000655 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000656};
657
658static const unsigned char PRFT[NB_PRF_TESTS][16] = {
659 {
660 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
661 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
662 },
663 {
664 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
665 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
666 },
667 {
668 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
669 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
670 }
671};
Brian Murray0f6af732016-05-19 15:59:23 -0700672#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000673
Brian Murrayb439d452016-05-19 16:02:42 -0700674int test_cmac_with_cipher( int verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700675 char* testname,
Brian Murray00dc5f02016-05-19 14:23:50 -0700676 const unsigned char* key,
677 int keybits,
678 const unsigned char* messages,
Brian Murray57863ad2016-05-19 16:38:36 -0700679 const unsigned int message_lengths[4],
Brian Murray00dc5f02016-05-19 14:23:50 -0700680 const unsigned char* subkeys,
681 const unsigned char* expected_result,
682 mbedtls_cipher_id_t cipher_id,
Brian Murrayb439d452016-05-19 16:02:42 -0700683 int block_size )
Brian Murray00dc5f02016-05-19 14:23:50 -0700684{
685 const int num_tests = 4;
686 mbedtls_cmac_context ctx;
687 int i, ret;
688 unsigned char* tag;
689
690 tag = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Brian Murray57863ad2016-05-19 16:38:36 -0700691 if( tag == NULL ){
692 ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED;
693 goto exit;
694 }
695
Brian Murray00dc5f02016-05-19 14:23:50 -0700696 mbedtls_cmac_init( &ctx );
697
698 if( ( ret = mbedtls_cmac_setkey( &ctx, cipher_id, key, keybits ) ) != 0 )
699 {
700 if( verbose != 0 )
701 mbedtls_printf( " CMAC: setup failed\n" );
702 goto exit;
703 }
704
705 if( ( ret = memcmp( ctx.K1, subkeys, block_size ) != 0 ) ||
706 ( ret = memcmp( ctx.K2, &subkeys[block_size], block_size ) != 0 ) )
707 {
708 if( verbose != 0 )
709 mbedtls_printf( " CMAC: subkey generation failed\n" );
710 goto exit;
711 }
712
713 for( i = 0; i < num_tests; i++ )
714 {
715 if( verbose != 0 )
716 mbedtls_printf( " %s CMAC #%u: ", testname, i +1 );
717
718 if( ( ret = mbedtls_cmac_generate( &ctx, messages, message_lengths[i], tag, block_size ) ) != 0 )
719 {
720 if( verbose != 0 )
721 mbedtls_printf( "failed\n" );
722 goto exit;
723 }
724 if( ( ret = memcmp( tag, &expected_result[i * block_size], block_size ) ) != 0 )
725 {
726 if( verbose != 0 )
727 mbedtls_printf( "failed\n" );
728 goto exit;
729 }
730
731 if( ( ret = mbedtls_cmac_verify( &ctx, messages, message_lengths[i], &expected_result[i * block_size], block_size ) != 0 ) )
732 {
733 if( verbose != 0 )
734 mbedtls_printf( "failed\n" );
735 goto exit;
736 }
737 mbedtls_printf( "passed\n" );
738 }
739 exit:
740 free( tag );
741 mbedtls_cmac_free( &ctx );
742 return( ret );
743}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000744
Brian Murray0f6af732016-05-19 15:59:23 -0700745#ifdef MBEDTLS_AES_C
Brian Murray57863ad2016-05-19 16:38:36 -0700746int test_aes128_cmac_prf( int verbose ) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000747 int i;
748 int ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700749 unsigned char tag[16];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700750 for( i = 0; i < NB_PRF_TESTS; i++ )
751 {
Brian Murray0f6af732016-05-19 15:59:23 -0700752 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
753 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, tag );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700754 if( ret != 0 ||
755 memcmp( tag, PRFT[i], 16 ) != 0 )
756 {
757 if( verbose != 0 )
758 mbedtls_printf( "failed\n" );
759
Brian Murray0f6af732016-05-19 15:59:23 -0700760 return( ret );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700761 } else if( verbose != 0 )
762 {
763 mbedtls_printf( "passed\n" );
764 }
765 }
Brian Murray0f6af732016-05-19 15:59:23 -0700766 return( ret );
767}
768#endif /* MBEDTLS_AES_C */
769
770int mbedtls_cmac_self_test( int verbose )
771{
772 int ret;
773
774#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700775 if( ( ret = test_cmac_with_cipher( verbose,
776 "AES 128",
777 aes_128_key,
778 128,
779 test_message,
780 aes_message_lengths,
Brian Murray57863ad2016-05-19 16:38:36 -0700781 (const unsigned char*) aes_128_subkeys,
782 (const unsigned char*) aes_128_expected_result,
Brian Murray9044b022016-05-19 16:36:56 -0700783 MBEDTLS_CIPHER_ID_AES,
784 AES_BLOCK_SIZE ) !=0 ) )
785 {
786 return( ret );
787 }
Brian Murray0f6af732016-05-19 15:59:23 -0700788
Brian Murray9044b022016-05-19 16:36:56 -0700789 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700790 "AES 192",
791 aes_192_key,
792 192,
793 test_message,
794 aes_message_lengths,
795 (const unsigned char*) aes_192_subkeys,
796 (const unsigned char*) aes_192_expected_result,
797 MBEDTLS_CIPHER_ID_AES,
798 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700799 {
800 return( ret );
801 }
Brian Murray0f6af732016-05-19 15:59:23 -0700802
Brian Murray9044b022016-05-19 16:36:56 -0700803 if( ( ret = test_cmac_with_cipher ( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700804 "AES 256",
805 aes_256_key,
806 256,
807 test_message,
808 aes_message_lengths,
809 (const unsigned char*) aes_256_subkeys,
810 (const unsigned char*) aes_256_expected_result,
811 MBEDTLS_CIPHER_ID_AES,
812 AES_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700813 {
814 return( ret );
815 }
Brian Murray0f6af732016-05-19 15:59:23 -0700816#endif /* MBEDTLS_AES_C */
817
818#ifdef MBEDTLS_DES_C
Brian Murray9044b022016-05-19 16:36:56 -0700819 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700820 "3DES 2 key",
821 des3_2key_key,
822 192,
823 test_message,
824 des3_message_lengths,
825 (const unsigned char*) des3_2key_subkeys,
826 (const unsigned char*) des3_2key_expected_result,
827 MBEDTLS_CIPHER_ID_3DES,
828 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700829 {
830 return( ret );
831 }
Brian Murray0f6af732016-05-19 15:59:23 -0700832
Brian Murray9044b022016-05-19 16:36:56 -0700833 if( ( ret = test_cmac_with_cipher( verbose,
Brian Murray57863ad2016-05-19 16:38:36 -0700834 "3DES 3 key",
835 des3_3key_key,
836 192,
837 test_message,
838 des3_message_lengths,
839 (const unsigned char*) des3_3key_subkeys,
840 (const unsigned char*) des3_3key_expected_result,
841 MBEDTLS_CIPHER_ID_3DES,
842 DES3_BLOCK_SIZE ) !=0 ) )
Brian Murray9044b022016-05-19 16:36:56 -0700843 {
844 return( ret );
845 }
Brian Murray0f6af732016-05-19 15:59:23 -0700846#endif /* MBEDTLS_DES_C */
847
848#ifdef MBEDTLS_AES_C
Brian Murray9044b022016-05-19 16:36:56 -0700849 if( ( ret = test_aes128_cmac_prf( verbose ) != 0 ) )
850 return( ret );
851
Brian Murray0f6af732016-05-19 15:59:23 -0700852#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700853
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000854 if( verbose != 0 )
855 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -0700856
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000857 return( 0 );
858}
859
Brian Murray0f6af732016-05-19 15:59:23 -0700860#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000861
862#endif /* MBEDTLS_CMAC_C */