blob: 5d101e1c7d0bfd346b5489898110e839556b82c9 [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
Gilles Peskinedf761d52018-03-01 22:18:14 +0100831 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100832 goto exit;
833
834cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100835 mbedtls_cipher_free( &ctx );
836
Janos Follathd4443582016-10-12 10:00:42 +0100837exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100838 return( ret );
839}
840
Simon Butcher69283e52016-10-06 12:49:58 +0100841static int cmac_test_wth_cipher( int verbose,
842 const char* testname,
843 const unsigned char* key,
844 int keybits,
845 const unsigned char* messages,
846 const unsigned int message_lengths[4],
847 const unsigned char* expected_result,
848 mbedtls_cipher_type_t cipher_type,
849 int block_size,
850 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700851{
Simon Butcher327398a2016-10-05 14:09:11 +0100852 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800853 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100854 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700855
Simon Butcher327398a2016-10-05 14:09:11 +0100856 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
857 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700858 {
Simon Butcher327398a2016-10-05 14:09:11 +0100859 /* Failing at this point must be due to a build issue */
860 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700861 goto exit;
862 }
863
864 for( i = 0; i < num_tests; i++ )
865 {
866 if( verbose != 0 )
Andres AGa592dcc2016-10-06 15:23:39 +0100867 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700868
Simon Butcher327398a2016-10-05 14:09:11 +0100869 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
870 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700871 {
872 if( verbose != 0 )
873 mbedtls_printf( "failed\n" );
874 goto exit;
875 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700876
Simon Butcher327398a2016-10-05 14:09:11 +0100877 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700878 {
879 if( verbose != 0 )
880 mbedtls_printf( "failed\n" );
881 goto exit;
882 }
883
Brian Murray9ce2e092016-05-24 22:46:43 -0700884 if( verbose != 0 )
885 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700886 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100887 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100888
Simon Butcher69283e52016-10-06 12:49:58 +0100889exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100890 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700891}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000892
Simon Butcher69283e52016-10-06 12:49:58 +0100893#if defined(MBEDTLS_AES_C)
894static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700895{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000896 int i;
897 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100898 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100899
Brian Murrayb0c3c432016-05-18 14:29:51 -0700900 for( i = 0; i < NB_PRF_TESTS; i++ )
901 {
Brian Murray0f6af732016-05-19 15:59:23 -0700902 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100903 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700904 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100905 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700906 {
Simon Butcher327398a2016-10-05 14:09:11 +0100907
Brian Murrayb0c3c432016-05-18 14:29:51 -0700908 if( verbose != 0 )
909 mbedtls_printf( "failed\n" );
910
Brian Murray0f6af732016-05-19 15:59:23 -0700911 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100912 }
913 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700914 {
915 mbedtls_printf( "passed\n" );
916 }
917 }
Brian Murray0f6af732016-05-19 15:59:23 -0700918 return( ret );
919}
920#endif /* MBEDTLS_AES_C */
921
922int mbedtls_cmac_self_test( int verbose )
923{
924 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100925
Simon Butcher69283e52016-10-06 12:49:58 +0100926#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100927 /* AES-128 */
928 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100929 "AES 128",
930 aes_128_key,
931 128,
932 (const unsigned char*)aes_128_subkeys,
933 MBEDTLS_CIPHER_AES_128_ECB,
934 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100935 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100936 {
937 return( ret );
938 }
939
Brian Murrayae1cb122016-05-23 15:01:59 -0700940 if( ( ret = cmac_test_wth_cipher( verbose,
941 "AES 128",
942 aes_128_key,
943 128,
944 test_message,
945 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100946 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100947 MBEDTLS_CIPHER_AES_128_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100948 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100949 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100950 {
951 return( ret );
952 }
953
954 /* AES-192 */
955 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100956 "AES 192",
957 aes_192_key,
958 192,
959 (const unsigned char*)aes_192_subkeys,
960 MBEDTLS_CIPHER_AES_192_ECB,
961 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100962 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700963 {
964 return( ret );
965 }
Brian Murray0f6af732016-05-19 15:59:23 -0700966
Brian Murrayae1cb122016-05-23 15:01:59 -0700967 if( ( ret = cmac_test_wth_cipher( verbose,
968 "AES 192",
969 aes_192_key,
970 192,
971 test_message,
972 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100973 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100974 MBEDTLS_CIPHER_AES_192_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100975 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100976 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100977 {
Simon Butcher327398a2016-10-05 14:09:11 +0100978 return( ret );
979 }
980
981 /* AES-256 */
982 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100983 "AES 256",
984 aes_256_key,
985 256,
986 (const unsigned char*)aes_256_subkeys,
987 MBEDTLS_CIPHER_AES_256_ECB,
988 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100989 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700990 {
991 return( ret );
992 }
Brian Murray0f6af732016-05-19 15:59:23 -0700993
Simon Butcher69283e52016-10-06 12:49:58 +0100994 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -0700995 "AES 256",
996 aes_256_key,
997 256,
998 test_message,
999 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001000 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001001 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001002 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001003 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001004 {
1005 return( ret );
1006 }
Brian Murray0f6af732016-05-19 15:59:23 -07001007#endif /* MBEDTLS_AES_C */
1008
Simon Butcher69283e52016-10-06 12:49:58 +01001009#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001010 /* 3DES 2 key */
1011 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001012 "3DES 2 key",
1013 des3_2key_key,
1014 192,
1015 (const unsigned char*)des3_2key_subkeys,
1016 MBEDTLS_CIPHER_DES_EDE3_ECB,
1017 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001018 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001019 {
1020 return( ret );
1021 }
1022
Brian Murrayae1cb122016-05-23 15:01:59 -07001023 if( ( ret = cmac_test_wth_cipher( verbose,
1024 "3DES 2 key",
1025 des3_2key_key,
1026 192,
1027 test_message,
1028 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001029 (const unsigned char*)des3_2key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001030 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001031 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001032 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001033 {
1034 return( ret );
1035 }
Brian Murray0f6af732016-05-19 15:59:23 -07001036
Simon Butcher327398a2016-10-05 14:09:11 +01001037 /* 3DES 3 key */
1038 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001039 "3DES 3 key",
1040 des3_3key_key,
1041 192,
1042 (const unsigned char*)des3_3key_subkeys,
1043 MBEDTLS_CIPHER_DES_EDE3_ECB,
1044 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001045 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001046 {
1047 return( ret );
1048 }
1049
Brian Murrayae1cb122016-05-23 15:01:59 -07001050 if( ( ret = cmac_test_wth_cipher( verbose,
1051 "3DES 3 key",
1052 des3_3key_key,
1053 192,
1054 test_message,
1055 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001056 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001057 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001058 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001059 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001060 {
1061 return( ret );
1062 }
Brian Murray0f6af732016-05-19 15:59:23 -07001063#endif /* MBEDTLS_DES_C */
1064
Simon Butcher69283e52016-10-06 12:49:58 +01001065#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001066 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001067 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001068#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001069
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001070 if( verbose != 0 )
1071 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001072
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001073 return( 0 );
1074}
1075
Brian Murray0f6af732016-05-19 15:59:23 -07001076#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001077
1078#endif /* MBEDTLS_CMAC_C */