blob: 4d7a1f1693b0afc29be2e2d08a8166fb48ecf6d5 [file] [log] [blame]
Andres Amaya Garciaaf610a02016-12-14 10:13:43 +00001/**
Brian Murray53e23b62016-09-13 14:00:15 -07002 * \file cmac.c
Simon Butcher327398a2016-10-05 14:09:11 +01003 *
Simon Butcher69283e52016-10-06 12:49:58 +01004 * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
Robert Cragie3d23b1d2015-12-15 07:38:11 +00005 *
Brian Murray53e23b62016-09-13 14:00:15 -07006 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
Robert Cragie3d23b1d2015-12-15 07:38:11 +00007 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
10 * not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23
24/*
Brian Murray53e23b62016-09-13 14:00:15 -070025 * References:
Simon Butcher327398a2016-10-05 14:09:11 +010026 *
27 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
28 * CMAC Mode for Authentication
Janos Follathcd13bd22016-12-13 11:51:04 +000029 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
Simon Butcher327398a2016-10-05 14:09:11 +010030 *
31 * - RFC 4493 - The AES-CMAC Algorithm
32 * https://tools.ietf.org/html/rfc4493
33 *
34 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
35 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
36 * Algorithm for the Internet Key Exchange Protocol (IKE)
37 * https://tools.ietf.org/html/rfc4615
38 *
39 * Additional test vectors: ISO/IEC 9797-1
40 *
Robert Cragie3d23b1d2015-12-15 07:38:11 +000041 */
42
43#if !defined(MBEDTLS_CONFIG_FILE)
44#include "mbedtls/config.h"
45#else
46#include MBEDTLS_CONFIG_FILE
47#endif
48
49#if defined(MBEDTLS_CMAC_C)
50
51#include "mbedtls/cmac.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050052#include "mbedtls/platform_util.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000053
54#include <string.h>
55
Brian Murray8b4111c2016-09-13 15:58:46 -070056
Robert Cragie3d23b1d2015-12-15 07:38:11 +000057#if defined(MBEDTLS_PLATFORM_C)
58#include "mbedtls/platform.h"
59#else
Brian Murray8b4111c2016-09-13 15:58:46 -070060#include <stdlib.h>
61#define mbedtls_calloc calloc
62#define mbedtls_free free
Simon Butcherd241f1c2016-10-06 10:39:49 +010063#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000064#include <stdio.h>
Brian Murray8b4111c2016-09-13 15:58:46 -070065#define mbedtls_printf printf
Brian J Murray2adecba2016-11-06 04:45:15 -080066#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +000067#endif /* MBEDTLS_PLATFORM_C */
Brian Murray8b4111c2016-09-13 15:58:46 -070068
Ron Eldor621080d2017-12-21 10:57:43 +020069#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020070
Robert Cragie3d23b1d2015-12-15 07:38:11 +000071/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070072 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000073 *
Brian Murray72b69e32016-09-13 14:21:01 -070074 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000075 *
Simon Butcher327398a2016-10-05 14:09:11 +010076 * If MSB(p) = 0, then p = (p << 1)
77 * If MSB(p) = 1, then p = (p << 1) ^ R_n
78 * with R_64 = 0x1B and R_128 = 0x87
79 *
80 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -080081 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000082 */
Brian Murrayb0c3c432016-05-18 14:29:51 -070083static int cmac_multiply_by_u( unsigned char *output,
84 const unsigned char *input,
Brian Murray53e23b62016-09-13 14:00:15 -070085 size_t blocksize )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000086{
Brian Murrayb0c3c432016-05-18 14:29:51 -070087 const unsigned char R_128 = 0x87;
88 const unsigned char R_64 = 0x1B;
89 unsigned char R_n, mask;
90 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010091 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070092
Simon Butcher69283e52016-10-06 12:49:58 +010093 if( blocksize == MBEDTLS_AES_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -070094 {
Brian Murrayb0c3c432016-05-18 14:29:51 -070095 R_n = R_128;
Simon Butcher327398a2016-10-05 14:09:11 +010096 }
Simon Butcher69283e52016-10-06 12:49:58 +010097 else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -070098 {
Brian Murrayb0c3c432016-05-18 14:29:51 -070099 R_n = R_64;
Simon Butcher327398a2016-10-05 14:09:11 +0100100 }
101 else
Brian Murray6a3c0d22016-05-20 18:25:43 -0700102 {
Simon Butcher327398a2016-10-05 14:09:11 +0100103 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700104 }
105
Simon B3249cb72016-11-03 01:11:37 +0000106 for( i = (int)blocksize - 1; i >= 0; i-- )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000107 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000108 output[i] = input[i] << 1 | overflow;
109 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000110 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000111
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000112 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
113 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +0100114
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000115 /* MSVC has a warning about unary minus on unsigned, but this is
116 * well-defined and precisely what we want to do here */
117#if defined(_MSC_VER)
118#pragma warning( push )
119#pragma warning( disable : 4146 )
120#endif
121 mask = - ( input[0] >> 7 );
122#if defined(_MSC_VER)
123#pragma warning( pop )
124#endif
125
Simon Butcher327398a2016-10-05 14:09:11 +0100126 output[ blocksize - 1 ] ^= R_n & mask;
127
Brian Murrayb439d452016-05-19 16:02:42 -0700128 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000129}
130
131/*
132 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +0100133 *
134 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000135 */
Simon Butcher327398a2016-10-05 14:09:11 +0100136static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
137 unsigned char* K1, unsigned char* K2 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000138{
Brian Murray57863ad2016-05-19 16:38:36 -0700139 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100140 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700141 size_t olen, block_size;
142
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500143 mbedtls_platform_zeroize( L, sizeof( L ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700144
Simon Butcher327398a2016-10-05 14:09:11 +0100145 block_size = ctx->cipher_info->block_size;
146
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000147 /* Calculate Ek(0) */
Simon Butcher327398a2016-10-05 14:09:11 +0100148 if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700149 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000150
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000151 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000152 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000153 */
Simon Butcher327398a2016-10-05 14:09:11 +0100154 if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700155 goto exit;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000156
Simon Butcher327398a2016-10-05 14:09:11 +0100157 if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 )
158 goto exit;
159
160exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500161 mbedtls_platform_zeroize( L, sizeof( L ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100162
163 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000164}
Ron Eldor621080d2017-12-21 10:57:43 +0200165#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000166
Ron Eldor621080d2017-12-21 10:57:43 +0200167#if !defined(MBEDTLS_CMAC_ALT)
Simon Butcher69283e52016-10-06 12:49:58 +0100168static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
169 const unsigned char *input2,
170 const size_t block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000171{
Hanno Becker61937d42017-04-26 15:01:23 +0100172 size_t idx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000173
Hanno Becker61937d42017-04-26 15:01:23 +0100174 for( idx = 0; idx < block_size; idx++ )
175 output[ idx ] = input1[ idx ] ^ input2[ idx ];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000176}
177
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000178/*
179 * Create padded last block from (partial) last block.
180 *
181 * We can't use the padding option from the cipher layer, as it only works for
182 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
183 */
Simon Butcher69283e52016-10-06 12:49:58 +0100184static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
Brian Murray53e23b62016-09-13 14:00:15 -0700185 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000186 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700187 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000188{
189 size_t j;
190
Brian Murrayb0c3c432016-05-18 14:29:51 -0700191 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000192 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700193 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000194 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700195 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000196 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000197 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000198 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000199 }
200}
201
Simon Butcher327398a2016-10-05 14:09:11 +0100202int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
Simon Butcher94ffde72016-10-05 15:33:53 +0100203 const unsigned char *key, size_t keybits )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000204{
Simon Butcher327398a2016-10-05 14:09:11 +0100205 mbedtls_cipher_type_t type;
206 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100207 int retval;
208
209 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
210 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
211
Simon B3249cb72016-11-03 01:11:37 +0000212 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
Simon Butcher327398a2016-10-05 14:09:11 +0100213 MBEDTLS_ENCRYPT ) ) != 0 )
214 return( retval );
215
Simon Butcher327398a2016-10-05 14:09:11 +0100216 type = ctx->cipher_info->type;
217
218 switch( type )
219 {
220 case MBEDTLS_CIPHER_AES_128_ECB:
221 case MBEDTLS_CIPHER_AES_192_ECB:
222 case MBEDTLS_CIPHER_AES_256_ECB:
223 case MBEDTLS_CIPHER_DES_EDE3_ECB:
224 break;
225 default:
226 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
227 }
228
229 /* Allocated and initialise in the cipher context memory for the CMAC
230 * context */
231 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
232 if( cmac_ctx == NULL )
233 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
234
235 ctx->cmac_ctx = cmac_ctx;
236
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500237 mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100238
239 return 0;
240}
241
242int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
243 const unsigned char *input, size_t ilen )
244{
245 mbedtls_cmac_context_t* cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700246 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000247 int ret = 0;
248 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700249
Simon Butcher327398a2016-10-05 14:09:11 +0100250 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
251 ctx->cmac_ctx == NULL )
252 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700253
Simon Butcher327398a2016-10-05 14:09:11 +0100254 cmac_ctx = ctx->cmac_ctx;
255 block_size = ctx->cipher_info->block_size;
256 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000257
Simon Butcher6b0774a2016-10-10 21:37:42 +0100258 /* Is there data still to process from the last call, that's greater in
259 * size than a block? */
Simon Butcher327398a2016-10-05 14:09:11 +0100260 if( cmac_ctx->unprocessed_len > 0 &&
Andres AGa592dcc2016-10-06 15:23:39 +0100261 ilen > block_size - cmac_ctx->unprocessed_len )
Brian Murray57863ad2016-05-19 16:38:36 -0700262 {
Simon Butcher327398a2016-10-05 14:09:11 +0100263 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
264 input,
265 block_size - cmac_ctx->unprocessed_len );
266
267 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
268
269 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
270 &olen ) ) != 0 )
271 {
272 goto exit;
273 }
274
Simon Butcher6b0774a2016-10-10 21:37:42 +0100275 input += block_size - cmac_ctx->unprocessed_len;
276 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100277 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700278 }
279
Simon Butcher327398a2016-10-05 14:09:11 +0100280 /* n is the number of blocks including any final partial block */
281 n = ( ilen + block_size - 1 ) / block_size;
282
Simon B3249cb72016-11-03 01:11:37 +0000283 /* Iterate across the input data in block sized chunks, excluding any
284 * final partial or complete block */
285 for( j = 1; j < n; j++ )
Brian Murray57863ad2016-05-19 16:38:36 -0700286 {
Simon Butcher327398a2016-10-05 14:09:11 +0100287 cmac_xor_block( state, input, state, block_size );
288
289 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
290 &olen ) ) != 0 )
291 goto exit;
292
293 ilen -= block_size;
294 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700295 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000296
Simon Butcher327398a2016-10-05 14:09:11 +0100297 /* If there is data left over that wasn't aligned to a block */
298 if( ilen > 0 )
299 {
Simon Butcher6b0774a2016-10-10 21:37:42 +0100300 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
301 input,
302 ilen );
303 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100304 }
305
306exit:
307 return( ret );
308}
309
310int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
311 unsigned char *output )
312{
313 mbedtls_cmac_context_t* cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100314 unsigned char *state, *last_block;
315 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
316 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
317 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100318 int ret;
319 size_t olen, block_size;
320
321 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
322 output == NULL )
323 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
324
325 cmac_ctx = ctx->cmac_ctx;
326 block_size = ctx->cipher_info->block_size;
327 state = cmac_ctx->state;
328
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500329 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
330 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100331 cmac_generate_subkeys( ctx, K1, K2 );
332
Simon Butcher69283e52016-10-06 12:49:58 +0100333 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000334
335 /* Calculate last block */
Janos Follathe3d882a2016-10-11 10:49:26 +0100336 if( cmac_ctx->unprocessed_len < block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000337 {
Simon Butcher327398a2016-10-05 14:09:11 +0100338 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
339 cmac_xor_block( M_last, M_last, K2, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000340 }
341 else
342 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000343 /* Last block is complete block */
Simon Butcher327398a2016-10-05 14:09:11 +0100344 cmac_xor_block( M_last, last_block, K1, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000345 }
346
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000347
Simon Butcher327398a2016-10-05 14:09:11 +0100348 cmac_xor_block( state, M_last, state, block_size );
349 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
350 &olen ) ) != 0 )
351 {
352 goto exit;
353 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000354
Simon Butcher327398a2016-10-05 14:09:11 +0100355 memcpy( output, state, block_size );
356
357exit:
358 /* Wipe the generated keys on the stack, and any other transients to avoid
359 * side channel leakage */
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500360 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
361 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100362
363 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500364 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
365 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100366
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500367 mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
Simon Butcher327398a2016-10-05 14:09:11 +0100368 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000369}
370
Simon Butcher327398a2016-10-05 14:09:11 +0100371int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000372{
Simon Butcher327398a2016-10-05 14:09:11 +0100373 mbedtls_cmac_context_t* cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000374
Simon Butcher327398a2016-10-05 14:09:11 +0100375 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
376 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700377
Simon Butcher327398a2016-10-05 14:09:11 +0100378 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000379
Simon Butcher327398a2016-10-05 14:09:11 +0100380 /* Reset the internal state */
381 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500382 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
383 sizeof( cmac_ctx->unprocessed_block ) );
384 mbedtls_platform_zeroize( cmac_ctx->state,
385 sizeof( cmac_ctx->state ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000386
Simon Butcher327398a2016-10-05 14:09:11 +0100387 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000388}
389
Simon Butcher327398a2016-10-05 14:09:11 +0100390int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
391 const unsigned char *key, size_t keylen,
392 const unsigned char *input, size_t ilen,
393 unsigned char *output )
394{
395 mbedtls_cipher_context_t ctx;
396 int ret;
397
398 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
399 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
400
401 mbedtls_cipher_init( &ctx );
402
403 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
404 goto exit;
405
406 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
Simon Butcher327398a2016-10-05 14:09:11 +0100407 if( ret != 0 )
408 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100409
410 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
411 if( ret != 0 )
412 goto exit;
413
Simon Butcher69283e52016-10-06 12:49:58 +0100414 ret = mbedtls_cipher_cmac_finish( &ctx, output );
Simon Butcher327398a2016-10-05 14:09:11 +0100415
416exit:
Simon Butcher69283e52016-10-06 12:49:58 +0100417 mbedtls_cipher_free( &ctx );
418
Simon Butcher327398a2016-10-05 14:09:11 +0100419 return( ret );
420}
Simon Butcher327398a2016-10-05 14:09:11 +0100421
Simon Butcher69283e52016-10-06 12:49:58 +0100422#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000423/*
Simon Butcher69283e52016-10-06 12:49:58 +0100424 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000425 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700426int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000427 const unsigned char *input, size_t in_len,
Simon Butcher327398a2016-10-05 14:09:11 +0100428 unsigned char *output )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000429{
430 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100431 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100432 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
433 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
434
435 if( key == NULL || input == NULL || output == NULL )
436 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000437
Simon Butcher327398a2016-10-05 14:09:11 +0100438 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
439 if( cipher_info == NULL )
440 {
441 /* Failing at this point must be due to a build issue */
442 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
443 goto exit;
444 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700445
Simon Butcher69283e52016-10-06 12:49:58 +0100446 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000447 {
448 /* Use key as is */
Simon Butcher69283e52016-10-06 12:49:58 +0100449 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000450 }
451 else
452 {
Simon Butcher69283e52016-10-06 12:49:58 +0100453 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000454
Simon Butcher327398a2016-10-05 14:09:11 +0100455 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
456 key_length, int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000457 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700458 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000459 }
460
Simon Butcher327398a2016-10-05 14:09:11 +0100461 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
462 output );
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000463
Simon Butcher327398a2016-10-05 14:09:11 +0100464exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500465 mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700466
Simon Butcher327398a2016-10-05 14:09:11 +0100467 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000468}
Brian Murrayb439d452016-05-19 16:02:42 -0700469#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000470
Steven Cooreman63342772017-04-04 11:47:16 +0200471#endif /* !MBEDTLS_CMAC_ALT */
472
Simon Butcher69283e52016-10-06 12:49:58 +0100473#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000474/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000475 * CMAC test data for SP800-38B
476 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
477 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700478 *
479 * AES-CMAC-PRF-128 test data from RFC 4615
480 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000481 */
482
Brian Murray0f6af732016-05-19 15:59:23 -0700483#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000484#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100485
Brian Murray0f6af732016-05-19 15:59:23 -0700486#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
487/* All CMAC test inputs are truncated from the same 64 byte buffer. */
488static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000489 /* PT */
490 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
491 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
492 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
493 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
494 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
495 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
496 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
497 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000498};
Simon Butcher69283e52016-10-06 12:49:58 +0100499#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700500
Simon Butcher69283e52016-10-06 12:49:58 +0100501#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700502/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700503static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000504 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700505 0,
506 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000507 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700508 64
509};
510
Janos Follathcd13bd22016-12-13 11:51:04 +0000511/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700512static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000513 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
514 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700515};
Simon Butcher69283e52016-10-06 12:49:58 +0100516static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700517 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000518 /* K1 */
519 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
520 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700521 },
522 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000523 /* K2 */
524 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
525 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700526 }
527};
Simon Butcher69283e52016-10-06 12:49:58 +0100528static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000529 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000530 /* Example #1 */
531 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
532 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000533 },
534 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000535 /* Example #2 */
536 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
537 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000538 },
539 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000540 /* Example #3 */
541 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
542 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000543 },
544 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000545 /* Example #4 */
546 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
547 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000548 }
549};
550
Janos Follathcd13bd22016-12-13 11:51:04 +0000551/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700552static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000553 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
554 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
555 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000556};
Simon Butcher69283e52016-10-06 12:49:58 +0100557static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700558 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000559 /* K1 */
560 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
561 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700562 },
563 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000564 /* K2 */
565 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
566 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700567 }
568};
Simon Butcher69283e52016-10-06 12:49:58 +0100569static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700570 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000571 /* Example #1 */
572 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
573 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700574 },
575 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000576 /* Example #2 */
577 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
578 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700579 },
580 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000581 /* Example #3 */
582 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
583 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700584 },
585 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000586 /* Example #4 */
587 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
588 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700589 }
590};
591
Janos Follathcd13bd22016-12-13 11:51:04 +0000592/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700593static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000594 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
595 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
596 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
597 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700598};
Simon Butcher69283e52016-10-06 12:49:58 +0100599static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700600 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000601 /* K1 */
602 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
603 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700604 },
605 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000606 /* K2 */
607 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
608 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700609 }
610};
Simon Butcher69283e52016-10-06 12:49:58 +0100611static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700612 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000613 /* Example #1 */
614 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
615 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700616 },
617 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000618 /* Example #2 */
619 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
620 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700621 },
622 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000623 /* Example #3 */
624 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
625 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700626 },
627 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000628 /* Example #4 */
629 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
630 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700631 }
632};
633#endif /* MBEDTLS_AES_C */
634
Simon Butcher69283e52016-10-06 12:49:58 +0100635#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700636/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700637static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700638 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000639 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700640 20,
641 32
642};
643
Janos Follathcd13bd22016-12-13 11:51:04 +0000644/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700645static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000646 /* Key1 */
647 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
648 /* Key2 */
649 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
650 /* Key3 */
651 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700652};
653static const unsigned char des3_2key_subkeys[2][8] = {
654 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000655 /* K1 */
656 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700657 },
658 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000659 /* K2 */
660 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700661 }
662};
Simon Butcher69283e52016-10-06 12:49:58 +0100663static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700664 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000665 /* Sample #1 */
666 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700667 },
668 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000669 /* Sample #2 */
670 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700671 },
672 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000673 /* Sample #3 */
674 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700675 },
676 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000677 /* Sample #4 */
678 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700679 }
680};
681
Janos Follathcd13bd22016-12-13 11:51:04 +0000682/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700683static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000684 /* Key1 */
685 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
686 /* Key2 */
687 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
688 /* Key3 */
689 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700690};
691static const unsigned char des3_3key_subkeys[2][8] = {
692 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000693 /* K1 */
694 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700695 },
696 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000697 /* K2 */
698 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700699 }
700};
Simon Butcher69283e52016-10-06 12:49:58 +0100701static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700702 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000703 /* Sample #1 */
704 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700705 },
706 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000707 /* Sample #2 */
708 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700709 },
710 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000711 /* Sample #3 */
712 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700713 },
714 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000715 /* Sample #4 */
716 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700717 }
718};
719
Brian Murray0f6af732016-05-19 15:59:23 -0700720#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700721
Simon Butcher69283e52016-10-06 12:49:58 +0100722#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700723/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000724static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000725 /* Key */
726 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
727 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000728 0xed, 0xcb
729};
730
731/* Sizes in bytes */
732static const size_t PRFKlen[NB_PRF_TESTS] = {
733 18,
734 16,
735 10
736};
737
Janos Follathcd13bd22016-12-13 11:51:04 +0000738/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000739static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000740 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
741 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000742 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000743};
744
745static const unsigned char PRFT[NB_PRF_TESTS][16] = {
746 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000747 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
748 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000749 },
750 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000751 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
752 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000753 },
754 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000755 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
756 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000757 }
758};
Brian Murray0f6af732016-05-19 15:59:23 -0700759#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000760
Simon Butcher327398a2016-10-05 14:09:11 +0100761static int cmac_test_subkeys( int verbose,
762 const char* testname,
763 const unsigned char* key,
764 int keybits,
765 const unsigned char* subkeys,
766 mbedtls_cipher_type_t cipher_type,
767 int block_size,
768 int num_tests )
769{
Brian Murray2fab5c92016-12-15 18:51:13 -0800770 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100771 mbedtls_cipher_context_t ctx;
772 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100773 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
774 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100775
776 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
777 if( cipher_info == NULL )
778 {
779 /* Failing at this point must be due to a build issue */
Simon Butcher69283e52016-10-06 12:49:58 +0100780 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Simon Butcher327398a2016-10-05 14:09:11 +0100781 }
782
783 for( i = 0; i < num_tests; i++ )
784 {
785 if( verbose != 0 )
Simon Butcher69283e52016-10-06 12:49:58 +0100786 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
Simon Butcher327398a2016-10-05 14:09:11 +0100787
Janos Follathd4443582016-10-12 10:00:42 +0100788 mbedtls_cipher_init( &ctx );
789
Simon Butcher327398a2016-10-05 14:09:11 +0100790 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
791 {
792 if( verbose != 0 )
793 mbedtls_printf( "test execution failed\n" );
794
Janos Follathd4443582016-10-12 10:00:42 +0100795 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100796 }
797
798 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
799 MBEDTLS_ENCRYPT ) ) != 0 )
800 {
801 if( verbose != 0 )
802 mbedtls_printf( "test execution failed\n" );
803
Janos Follathd4443582016-10-12 10:00:42 +0100804 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100805 }
806
807 ret = cmac_generate_subkeys( &ctx, K1, K2 );
808 if( ret != 0 )
809 {
810 if( verbose != 0 )
811 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100812
813 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100814 }
815
Simon Butcher420be4e2016-10-07 12:55:43 +0100816 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
817 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100818 {
819 if( verbose != 0 )
820 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100821
822 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100823 }
824
825 if( verbose != 0 )
826 mbedtls_printf( "passed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100827
828 mbedtls_cipher_free( &ctx );
Simon Butcher327398a2016-10-05 14:09:11 +0100829 }
830
Janos Follathd4443582016-10-12 10:00:42 +0100831 goto exit;
832
833cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100834 mbedtls_cipher_free( &ctx );
835
Janos Follathd4443582016-10-12 10:00:42 +0100836exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100837 return( ret );
838}
839
Simon Butcher69283e52016-10-06 12:49:58 +0100840static int cmac_test_wth_cipher( int verbose,
841 const char* testname,
842 const unsigned char* key,
843 int keybits,
844 const unsigned char* messages,
845 const unsigned int message_lengths[4],
846 const unsigned char* expected_result,
847 mbedtls_cipher_type_t cipher_type,
848 int block_size,
849 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700850{
Simon Butcher327398a2016-10-05 14:09:11 +0100851 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800852 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100853 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700854
Simon Butcher327398a2016-10-05 14:09:11 +0100855 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
856 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700857 {
Simon Butcher327398a2016-10-05 14:09:11 +0100858 /* Failing at this point must be due to a build issue */
859 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700860 goto exit;
861 }
862
863 for( i = 0; i < num_tests; i++ )
864 {
865 if( verbose != 0 )
Andres AGa592dcc2016-10-06 15:23:39 +0100866 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700867
Simon Butcher327398a2016-10-05 14:09:11 +0100868 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
869 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700870 {
871 if( verbose != 0 )
872 mbedtls_printf( "failed\n" );
873 goto exit;
874 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700875
Simon Butcher327398a2016-10-05 14:09:11 +0100876 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700877 {
878 if( verbose != 0 )
879 mbedtls_printf( "failed\n" );
880 goto exit;
881 }
882
Brian Murray9ce2e092016-05-24 22:46:43 -0700883 if( verbose != 0 )
884 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700885 }
Simon Butcher327398a2016-10-05 14:09:11 +0100886
Simon Butcher69283e52016-10-06 12:49:58 +0100887exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100888 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700889}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000890
Simon Butcher69283e52016-10-06 12:49:58 +0100891#if defined(MBEDTLS_AES_C)
892static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700893{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000894 int i;
895 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100896 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100897
Brian Murrayb0c3c432016-05-18 14:29:51 -0700898 for( i = 0; i < NB_PRF_TESTS; i++ )
899 {
Brian Murray0f6af732016-05-19 15:59:23 -0700900 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100901 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700902 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100903 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700904 {
Simon Butcher327398a2016-10-05 14:09:11 +0100905
Brian Murrayb0c3c432016-05-18 14:29:51 -0700906 if( verbose != 0 )
907 mbedtls_printf( "failed\n" );
908
Brian Murray0f6af732016-05-19 15:59:23 -0700909 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100910 }
911 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700912 {
913 mbedtls_printf( "passed\n" );
914 }
915 }
Brian Murray0f6af732016-05-19 15:59:23 -0700916 return( ret );
917}
918#endif /* MBEDTLS_AES_C */
919
920int mbedtls_cmac_self_test( int verbose )
921{
922 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100923
Simon Butcher69283e52016-10-06 12:49:58 +0100924#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100925 /* AES-128 */
926 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100927 "AES 128",
928 aes_128_key,
929 128,
930 (const unsigned char*)aes_128_subkeys,
931 MBEDTLS_CIPHER_AES_128_ECB,
932 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100933 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100934 {
935 return( ret );
936 }
937
Brian Murrayae1cb122016-05-23 15:01:59 -0700938 if( ( ret = cmac_test_wth_cipher( verbose,
939 "AES 128",
940 aes_128_key,
941 128,
942 test_message,
943 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100944 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100945 MBEDTLS_CIPHER_AES_128_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100946 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100947 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100948 {
949 return( ret );
950 }
951
952 /* AES-192 */
953 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100954 "AES 192",
955 aes_192_key,
956 192,
957 (const unsigned char*)aes_192_subkeys,
958 MBEDTLS_CIPHER_AES_192_ECB,
959 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100960 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700961 {
962 return( ret );
963 }
Brian Murray0f6af732016-05-19 15:59:23 -0700964
Brian Murrayae1cb122016-05-23 15:01:59 -0700965 if( ( ret = cmac_test_wth_cipher( verbose,
966 "AES 192",
967 aes_192_key,
968 192,
969 test_message,
970 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100971 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100972 MBEDTLS_CIPHER_AES_192_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100973 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100974 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100975 {
Simon Butcher327398a2016-10-05 14:09:11 +0100976 return( ret );
977 }
978
979 /* AES-256 */
980 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100981 "AES 256",
982 aes_256_key,
983 256,
984 (const unsigned char*)aes_256_subkeys,
985 MBEDTLS_CIPHER_AES_256_ECB,
986 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100987 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700988 {
989 return( ret );
990 }
Brian Murray0f6af732016-05-19 15:59:23 -0700991
Simon Butcher69283e52016-10-06 12:49:58 +0100992 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -0700993 "AES 256",
994 aes_256_key,
995 256,
996 test_message,
997 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100998 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100999 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001000 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001001 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001002 {
1003 return( ret );
1004 }
Brian Murray0f6af732016-05-19 15:59:23 -07001005#endif /* MBEDTLS_AES_C */
1006
Simon Butcher69283e52016-10-06 12:49:58 +01001007#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001008 /* 3DES 2 key */
1009 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001010 "3DES 2 key",
1011 des3_2key_key,
1012 192,
1013 (const unsigned char*)des3_2key_subkeys,
1014 MBEDTLS_CIPHER_DES_EDE3_ECB,
1015 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001016 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001017 {
1018 return( ret );
1019 }
1020
Brian Murrayae1cb122016-05-23 15:01:59 -07001021 if( ( ret = cmac_test_wth_cipher( verbose,
1022 "3DES 2 key",
1023 des3_2key_key,
1024 192,
1025 test_message,
1026 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001027 (const unsigned char*)des3_2key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001028 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001029 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001030 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001031 {
1032 return( ret );
1033 }
Brian Murray0f6af732016-05-19 15:59:23 -07001034
Simon Butcher327398a2016-10-05 14:09:11 +01001035 /* 3DES 3 key */
1036 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001037 "3DES 3 key",
1038 des3_3key_key,
1039 192,
1040 (const unsigned char*)des3_3key_subkeys,
1041 MBEDTLS_CIPHER_DES_EDE3_ECB,
1042 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001043 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001044 {
1045 return( ret );
1046 }
1047
Brian Murrayae1cb122016-05-23 15:01:59 -07001048 if( ( ret = cmac_test_wth_cipher( verbose,
1049 "3DES 3 key",
1050 des3_3key_key,
1051 192,
1052 test_message,
1053 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001054 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001055 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001056 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001057 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001058 {
1059 return( ret );
1060 }
Brian Murray0f6af732016-05-19 15:59:23 -07001061#endif /* MBEDTLS_DES_C */
1062
Simon Butcher69283e52016-10-06 12:49:58 +01001063#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001064 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001065 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001066#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001067
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001068 if( verbose != 0 )
1069 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001070
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001071 return( 0 );
1072}
1073
Brian Murray0f6af732016-05-19 15:59:23 -07001074#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001075
1076#endif /* MBEDTLS_CMAC_C */