blob: 0b769ff047aec63eab9fd94c2966881fff609f31 [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
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
8 *
9 * This file is provided under the Apache License 2.0, or the
10 * GNU General Public License v2.0 or later.
11 *
12 * **********
13 * Apache License 2.0:
Robert Cragie3d23b1d2015-12-15 07:38:11 +000014 *
15 * Licensed under the Apache License, Version 2.0 (the "License"); you may
16 * not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
23 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020027 * **********
28 *
29 * **********
30 * GNU General Public License v2.0 or later:
31 *
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation; either version 2 of the License, or
35 * (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License along
43 * with this program; if not, write to the Free Software Foundation, Inc.,
44 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
45 *
46 * **********
47 *
Robert Cragie3d23b1d2015-12-15 07:38:11 +000048 * This file is part of mbed TLS (https://tls.mbed.org)
49 */
50
51/*
Brian Murray53e23b62016-09-13 14:00:15 -070052 * References:
Simon Butcher327398a2016-10-05 14:09:11 +010053 *
54 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
55 * CMAC Mode for Authentication
Janos Follathcd13bd22016-12-13 11:51:04 +000056 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
Simon Butcher327398a2016-10-05 14:09:11 +010057 *
58 * - RFC 4493 - The AES-CMAC Algorithm
59 * https://tools.ietf.org/html/rfc4493
60 *
61 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
62 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
63 * Algorithm for the Internet Key Exchange Protocol (IKE)
64 * https://tools.ietf.org/html/rfc4615
65 *
66 * Additional test vectors: ISO/IEC 9797-1
67 *
Robert Cragie3d23b1d2015-12-15 07:38:11 +000068 */
69
70#if !defined(MBEDTLS_CONFIG_FILE)
71#include "mbedtls/config.h"
72#else
73#include MBEDTLS_CONFIG_FILE
74#endif
75
76#if defined(MBEDTLS_CMAC_C)
77
78#include "mbedtls/cmac.h"
79
80#include <string.h>
81
Brian Murray8b4111c2016-09-13 15:58:46 -070082
Robert Cragie3d23b1d2015-12-15 07:38:11 +000083#if defined(MBEDTLS_PLATFORM_C)
84#include "mbedtls/platform.h"
85#else
Brian Murray8b4111c2016-09-13 15:58:46 -070086#include <stdlib.h>
87#define mbedtls_calloc calloc
88#define mbedtls_free free
Simon Butcherd241f1c2016-10-06 10:39:49 +010089#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000090#include <stdio.h>
Brian Murray8b4111c2016-09-13 15:58:46 -070091#define mbedtls_printf printf
Brian J Murray2adecba2016-11-06 04:45:15 -080092#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +000093#endif /* MBEDTLS_PLATFORM_C */
Brian Murray8b4111c2016-09-13 15:58:46 -070094
Ron Eldor621080d2017-12-21 10:57:43 +020095#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020096
Robert Cragie3d23b1d2015-12-15 07:38:11 +000097/* Implementation that should never be optimized out by the compiler */
98static void mbedtls_zeroize( void *v, size_t n ) {
Simon Butcher327398a2016-10-05 14:09:11 +010099 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000100}
101
102/*
Brian Murrayb0c3c432016-05-18 14:29:51 -0700103 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000104 *
Brian Murray72b69e32016-09-13 14:21:01 -0700105 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000106 *
Simon Butcher327398a2016-10-05 14:09:11 +0100107 * If MSB(p) = 0, then p = (p << 1)
108 * If MSB(p) = 1, then p = (p << 1) ^ R_n
109 * with R_64 = 0x1B and R_128 = 0x87
110 *
111 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -0800112 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000113 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700114static int cmac_multiply_by_u( unsigned char *output,
115 const unsigned char *input,
Brian Murray53e23b62016-09-13 14:00:15 -0700116 size_t blocksize )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000117{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700118 const unsigned char R_128 = 0x87;
119 const unsigned char R_64 = 0x1B;
120 unsigned char R_n, mask;
121 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +0100122 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700123
Simon Butcher69283e52016-10-06 12:49:58 +0100124 if( blocksize == MBEDTLS_AES_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700125 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700126 R_n = R_128;
Simon Butcher327398a2016-10-05 14:09:11 +0100127 }
Simon Butcher69283e52016-10-06 12:49:58 +0100128 else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700129 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700130 R_n = R_64;
Simon Butcher327398a2016-10-05 14:09:11 +0100131 }
132 else
Brian Murray6a3c0d22016-05-20 18:25:43 -0700133 {
Simon Butcher327398a2016-10-05 14:09:11 +0100134 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700135 }
136
Simon B3249cb72016-11-03 01:11:37 +0000137 for( i = (int)blocksize - 1; i >= 0; i-- )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000138 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000139 output[i] = input[i] << 1 | overflow;
140 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000141 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000142
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000143 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
144 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +0100145
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000146 /* MSVC has a warning about unary minus on unsigned, but this is
147 * well-defined and precisely what we want to do here */
148#if defined(_MSC_VER)
149#pragma warning( push )
150#pragma warning( disable : 4146 )
151#endif
152 mask = - ( input[0] >> 7 );
153#if defined(_MSC_VER)
154#pragma warning( pop )
155#endif
156
Simon Butcher327398a2016-10-05 14:09:11 +0100157 output[ blocksize - 1 ] ^= R_n & mask;
158
Brian Murrayb439d452016-05-19 16:02:42 -0700159 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000160}
161
162/*
163 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +0100164 *
165 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000166 */
Simon Butcher327398a2016-10-05 14:09:11 +0100167static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
168 unsigned char* K1, unsigned char* K2 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000169{
Brian Murray57863ad2016-05-19 16:38:36 -0700170 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100171 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700172 size_t olen, block_size;
173
Simon Butcher327398a2016-10-05 14:09:11 +0100174 mbedtls_zeroize( L, sizeof( L ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700175
Simon Butcher327398a2016-10-05 14:09:11 +0100176 block_size = ctx->cipher_info->block_size;
177
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000178 /* Calculate Ek(0) */
Simon Butcher327398a2016-10-05 14:09:11 +0100179 if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700180 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000181
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000182 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000183 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000184 */
Simon Butcher327398a2016-10-05 14:09:11 +0100185 if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700186 goto exit;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000187
Simon Butcher327398a2016-10-05 14:09:11 +0100188 if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 )
189 goto exit;
190
191exit:
192 mbedtls_zeroize( L, sizeof( L ) );
193
194 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000195}
Ron Eldor621080d2017-12-21 10:57:43 +0200196#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000197
Ron Eldor621080d2017-12-21 10:57:43 +0200198#if !defined(MBEDTLS_CMAC_ALT)
Simon Butcher69283e52016-10-06 12:49:58 +0100199static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
200 const unsigned char *input2,
201 const size_t block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000202{
Hanno Becker61937d42017-04-26 15:01:23 +0100203 size_t idx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000204
Hanno Becker61937d42017-04-26 15:01:23 +0100205 for( idx = 0; idx < block_size; idx++ )
206 output[ idx ] = input1[ idx ] ^ input2[ idx ];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000207}
208
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000209/*
210 * Create padded last block from (partial) last block.
211 *
212 * We can't use the padding option from the cipher layer, as it only works for
213 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
214 */
Simon Butcher69283e52016-10-06 12:49:58 +0100215static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
Brian Murray53e23b62016-09-13 14:00:15 -0700216 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000217 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700218 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000219{
220 size_t j;
221
Brian Murrayb0c3c432016-05-18 14:29:51 -0700222 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000223 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700224 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000225 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700226 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000227 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000228 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000229 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000230 }
231}
232
Simon Butcher327398a2016-10-05 14:09:11 +0100233int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
Simon Butcher94ffde72016-10-05 15:33:53 +0100234 const unsigned char *key, size_t keybits )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000235{
Simon Butcher327398a2016-10-05 14:09:11 +0100236 mbedtls_cipher_type_t type;
237 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100238 int retval;
239
240 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
241 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
242
Simon B3249cb72016-11-03 01:11:37 +0000243 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
Simon Butcher327398a2016-10-05 14:09:11 +0100244 MBEDTLS_ENCRYPT ) ) != 0 )
245 return( retval );
246
Simon Butcher327398a2016-10-05 14:09:11 +0100247 type = ctx->cipher_info->type;
248
249 switch( type )
250 {
251 case MBEDTLS_CIPHER_AES_128_ECB:
252 case MBEDTLS_CIPHER_AES_192_ECB:
253 case MBEDTLS_CIPHER_AES_256_ECB:
254 case MBEDTLS_CIPHER_DES_EDE3_ECB:
255 break;
256 default:
257 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
258 }
259
260 /* Allocated and initialise in the cipher context memory for the CMAC
261 * context */
262 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
263 if( cmac_ctx == NULL )
264 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
265
266 ctx->cmac_ctx = cmac_ctx;
267
268 mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100269
270 return 0;
271}
272
273int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
274 const unsigned char *input, size_t ilen )
275{
276 mbedtls_cmac_context_t* cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700277 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000278 int ret = 0;
279 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700280
Simon Butcher327398a2016-10-05 14:09:11 +0100281 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
282 ctx->cmac_ctx == NULL )
283 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700284
Simon Butcher327398a2016-10-05 14:09:11 +0100285 cmac_ctx = ctx->cmac_ctx;
286 block_size = ctx->cipher_info->block_size;
287 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000288
Simon Butcher6b0774a2016-10-10 21:37:42 +0100289 /* Is there data still to process from the last call, that's greater in
290 * size than a block? */
Simon Butcher327398a2016-10-05 14:09:11 +0100291 if( cmac_ctx->unprocessed_len > 0 &&
Andres AGa592dcc2016-10-06 15:23:39 +0100292 ilen > block_size - cmac_ctx->unprocessed_len )
Brian Murray57863ad2016-05-19 16:38:36 -0700293 {
Simon Butcher327398a2016-10-05 14:09:11 +0100294 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
295 input,
296 block_size - cmac_ctx->unprocessed_len );
297
298 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
299
300 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
301 &olen ) ) != 0 )
302 {
303 goto exit;
304 }
305
Simon Butcher6b0774a2016-10-10 21:37:42 +0100306 input += block_size - cmac_ctx->unprocessed_len;
307 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100308 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700309 }
310
Simon Butcher327398a2016-10-05 14:09:11 +0100311 /* n is the number of blocks including any final partial block */
312 n = ( ilen + block_size - 1 ) / block_size;
313
Simon B3249cb72016-11-03 01:11:37 +0000314 /* Iterate across the input data in block sized chunks, excluding any
315 * final partial or complete block */
316 for( j = 1; j < n; j++ )
Brian Murray57863ad2016-05-19 16:38:36 -0700317 {
Simon Butcher327398a2016-10-05 14:09:11 +0100318 cmac_xor_block( state, input, state, block_size );
319
320 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
321 &olen ) ) != 0 )
322 goto exit;
323
324 ilen -= block_size;
325 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700326 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000327
Simon Butcher327398a2016-10-05 14:09:11 +0100328 /* If there is data left over that wasn't aligned to a block */
329 if( ilen > 0 )
330 {
Simon Butcher6b0774a2016-10-10 21:37:42 +0100331 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
332 input,
333 ilen );
334 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100335 }
336
337exit:
338 return( ret );
339}
340
341int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
342 unsigned char *output )
343{
344 mbedtls_cmac_context_t* cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100345 unsigned char *state, *last_block;
346 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
347 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
348 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100349 int ret;
350 size_t olen, block_size;
351
352 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
353 output == NULL )
354 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
355
356 cmac_ctx = ctx->cmac_ctx;
357 block_size = ctx->cipher_info->block_size;
358 state = cmac_ctx->state;
359
Simon Butcher69283e52016-10-06 12:49:58 +0100360 mbedtls_zeroize( K1, sizeof( K1 ) );
361 mbedtls_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100362 cmac_generate_subkeys( ctx, K1, K2 );
363
Simon Butcher69283e52016-10-06 12:49:58 +0100364 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000365
366 /* Calculate last block */
Janos Follathe3d882a2016-10-11 10:49:26 +0100367 if( cmac_ctx->unprocessed_len < block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000368 {
Simon Butcher327398a2016-10-05 14:09:11 +0100369 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
370 cmac_xor_block( M_last, M_last, K2, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000371 }
372 else
373 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000374 /* Last block is complete block */
Simon Butcher327398a2016-10-05 14:09:11 +0100375 cmac_xor_block( M_last, last_block, K1, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000376 }
377
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000378
Simon Butcher327398a2016-10-05 14:09:11 +0100379 cmac_xor_block( state, M_last, state, block_size );
380 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
381 &olen ) ) != 0 )
382 {
383 goto exit;
384 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000385
Simon Butcher327398a2016-10-05 14:09:11 +0100386 memcpy( output, state, block_size );
387
388exit:
389 /* Wipe the generated keys on the stack, and any other transients to avoid
390 * side channel leakage */
Simon Butcher69283e52016-10-06 12:49:58 +0100391 mbedtls_zeroize( K1, sizeof( K1 ) );
392 mbedtls_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100393
394 cmac_ctx->unprocessed_len = 0;
395 mbedtls_zeroize( cmac_ctx->unprocessed_block,
Simon Butcher69283e52016-10-06 12:49:58 +0100396 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100397
Simon Butcher69283e52016-10-06 12:49:58 +0100398 mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
Simon Butcher327398a2016-10-05 14:09:11 +0100399 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000400}
401
Simon Butcher327398a2016-10-05 14:09:11 +0100402int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000403{
Simon Butcher327398a2016-10-05 14:09:11 +0100404 mbedtls_cmac_context_t* cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000405
Simon Butcher327398a2016-10-05 14:09:11 +0100406 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
407 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700408
Simon Butcher327398a2016-10-05 14:09:11 +0100409 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000410
Simon Butcher327398a2016-10-05 14:09:11 +0100411 /* Reset the internal state */
412 cmac_ctx->unprocessed_len = 0;
413 mbedtls_zeroize( cmac_ctx->unprocessed_block,
Andres AGa592dcc2016-10-06 15:23:39 +0100414 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcherd241f1c2016-10-06 10:39:49 +0100415 mbedtls_zeroize( cmac_ctx->state,
416 sizeof( cmac_ctx->state ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000417
Simon Butcher327398a2016-10-05 14:09:11 +0100418 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000419}
420
Simon Butcher327398a2016-10-05 14:09:11 +0100421int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
422 const unsigned char *key, size_t keylen,
423 const unsigned char *input, size_t ilen,
424 unsigned char *output )
425{
426 mbedtls_cipher_context_t ctx;
427 int ret;
428
429 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
430 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
431
432 mbedtls_cipher_init( &ctx );
433
434 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
435 goto exit;
436
437 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
Simon Butcher327398a2016-10-05 14:09:11 +0100438 if( ret != 0 )
439 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100440
441 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
442 if( ret != 0 )
443 goto exit;
444
Simon Butcher69283e52016-10-06 12:49:58 +0100445 ret = mbedtls_cipher_cmac_finish( &ctx, output );
Simon Butcher327398a2016-10-05 14:09:11 +0100446
447exit:
Simon Butcher69283e52016-10-06 12:49:58 +0100448 mbedtls_cipher_free( &ctx );
449
Simon Butcher327398a2016-10-05 14:09:11 +0100450 return( ret );
451}
Simon Butcher327398a2016-10-05 14:09:11 +0100452
Simon Butcher69283e52016-10-06 12:49:58 +0100453#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000454/*
Simon Butcher69283e52016-10-06 12:49:58 +0100455 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000456 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700457int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000458 const unsigned char *input, size_t in_len,
Simon Butcher327398a2016-10-05 14:09:11 +0100459 unsigned char *output )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000460{
461 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100462 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100463 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
464 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
465
466 if( key == NULL || input == NULL || output == NULL )
467 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000468
Simon Butcher327398a2016-10-05 14:09:11 +0100469 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
470 if( cipher_info == NULL )
471 {
472 /* Failing at this point must be due to a build issue */
473 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
474 goto exit;
475 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700476
Simon Butcher69283e52016-10-06 12:49:58 +0100477 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000478 {
479 /* Use key as is */
Simon Butcher69283e52016-10-06 12:49:58 +0100480 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000481 }
482 else
483 {
Simon Butcher69283e52016-10-06 12:49:58 +0100484 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000485
Simon Butcher327398a2016-10-05 14:09:11 +0100486 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
487 key_length, int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000488 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700489 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000490 }
491
Simon Butcher327398a2016-10-05 14:09:11 +0100492 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
493 output );
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000494
Simon Butcher327398a2016-10-05 14:09:11 +0100495exit:
496 mbedtls_zeroize( int_key, sizeof( int_key ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700497
Simon Butcher327398a2016-10-05 14:09:11 +0100498 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000499}
Brian Murrayb439d452016-05-19 16:02:42 -0700500#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000501
Steven Cooreman63342772017-04-04 11:47:16 +0200502#endif /* !MBEDTLS_CMAC_ALT */
503
Simon Butcher69283e52016-10-06 12:49:58 +0100504#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000505/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000506 * CMAC test data for SP800-38B
507 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
508 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700509 *
510 * AES-CMAC-PRF-128 test data from RFC 4615
511 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000512 */
513
Brian Murray0f6af732016-05-19 15:59:23 -0700514#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000515#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100516
Brian Murray0f6af732016-05-19 15:59:23 -0700517#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
518/* All CMAC test inputs are truncated from the same 64 byte buffer. */
519static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000520 /* PT */
521 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
522 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
523 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
524 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
525 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
526 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
527 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
528 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000529};
Simon Butcher69283e52016-10-06 12:49:58 +0100530#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700531
Simon Butcher69283e52016-10-06 12:49:58 +0100532#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700533/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700534static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000535 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700536 0,
537 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000538 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700539 64
540};
541
Janos Follathcd13bd22016-12-13 11:51:04 +0000542/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700543static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000544 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
545 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700546};
Simon Butcher69283e52016-10-06 12:49:58 +0100547static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700548 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000549 /* K1 */
550 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
551 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700552 },
553 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000554 /* K2 */
555 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
556 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700557 }
558};
Simon Butcher69283e52016-10-06 12:49:58 +0100559static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000560 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000561 /* Example #1 */
562 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
563 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000564 },
565 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000566 /* Example #2 */
567 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
568 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000569 },
570 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000571 /* Example #3 */
572 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
573 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000574 },
575 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000576 /* Example #4 */
577 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
578 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000579 }
580};
581
Janos Follathcd13bd22016-12-13 11:51:04 +0000582/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700583static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000584 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
585 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
586 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000587};
Simon Butcher69283e52016-10-06 12:49:58 +0100588static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700589 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000590 /* K1 */
591 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
592 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700593 },
594 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000595 /* K2 */
596 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
597 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700598 }
599};
Simon Butcher69283e52016-10-06 12:49:58 +0100600static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700601 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000602 /* Example #1 */
603 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
604 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700605 },
606 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000607 /* Example #2 */
608 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
609 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700610 },
611 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000612 /* Example #3 */
613 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
614 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700615 },
616 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000617 /* Example #4 */
618 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
619 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700620 }
621};
622
Janos Follathcd13bd22016-12-13 11:51:04 +0000623/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700624static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000625 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
626 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
627 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
628 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700629};
Simon Butcher69283e52016-10-06 12:49:58 +0100630static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700631 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000632 /* K1 */
633 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
634 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700635 },
636 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000637 /* K2 */
638 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
639 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700640 }
641};
Simon Butcher69283e52016-10-06 12:49:58 +0100642static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700643 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000644 /* Example #1 */
645 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
646 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700647 },
648 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000649 /* Example #2 */
650 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
651 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700652 },
653 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000654 /* Example #3 */
655 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
656 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700657 },
658 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000659 /* Example #4 */
660 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
661 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700662 }
663};
664#endif /* MBEDTLS_AES_C */
665
Simon Butcher69283e52016-10-06 12:49:58 +0100666#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700667/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700668static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700669 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000670 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700671 20,
672 32
673};
674
Janos Follathcd13bd22016-12-13 11:51:04 +0000675/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700676static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000677 /* Key1 */
678 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
679 /* Key2 */
680 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
681 /* Key3 */
682 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700683};
684static const unsigned char des3_2key_subkeys[2][8] = {
685 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000686 /* K1 */
687 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700688 },
689 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000690 /* K2 */
691 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700692 }
693};
Simon Butcher69283e52016-10-06 12:49:58 +0100694static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700695 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000696 /* Sample #1 */
697 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700698 },
699 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000700 /* Sample #2 */
701 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700702 },
703 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000704 /* Sample #3 */
705 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700706 },
707 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000708 /* Sample #4 */
709 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700710 }
711};
712
Janos Follathcd13bd22016-12-13 11:51:04 +0000713/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700714static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000715 /* Key1 */
716 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
717 /* Key2 */
718 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
719 /* Key3 */
720 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700721};
722static const unsigned char des3_3key_subkeys[2][8] = {
723 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000724 /* K1 */
725 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700726 },
727 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000728 /* K2 */
729 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700730 }
731};
Simon Butcher69283e52016-10-06 12:49:58 +0100732static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700733 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000734 /* Sample #1 */
735 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700736 },
737 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000738 /* Sample #2 */
739 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700740 },
741 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000742 /* Sample #3 */
743 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700744 },
745 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000746 /* Sample #4 */
747 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700748 }
749};
750
Brian Murray0f6af732016-05-19 15:59:23 -0700751#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700752
Simon Butcher69283e52016-10-06 12:49:58 +0100753#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700754/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000755static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000756 /* Key */
757 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
758 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000759 0xed, 0xcb
760};
761
762/* Sizes in bytes */
763static const size_t PRFKlen[NB_PRF_TESTS] = {
764 18,
765 16,
766 10
767};
768
Janos Follathcd13bd22016-12-13 11:51:04 +0000769/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000770static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000771 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
772 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000773 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000774};
775
776static const unsigned char PRFT[NB_PRF_TESTS][16] = {
777 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000778 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
779 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000780 },
781 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000782 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
783 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000784 },
785 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000786 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
787 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000788 }
789};
Brian Murray0f6af732016-05-19 15:59:23 -0700790#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000791
Simon Butcher327398a2016-10-05 14:09:11 +0100792static int cmac_test_subkeys( int verbose,
793 const char* testname,
794 const unsigned char* key,
795 int keybits,
796 const unsigned char* subkeys,
797 mbedtls_cipher_type_t cipher_type,
798 int block_size,
799 int num_tests )
800{
Brian Murray2fab5c92016-12-15 18:51:13 -0800801 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100802 mbedtls_cipher_context_t ctx;
803 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100804 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
805 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100806
807 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
808 if( cipher_info == NULL )
809 {
810 /* Failing at this point must be due to a build issue */
Simon Butcher69283e52016-10-06 12:49:58 +0100811 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Simon Butcher327398a2016-10-05 14:09:11 +0100812 }
813
814 for( i = 0; i < num_tests; i++ )
815 {
816 if( verbose != 0 )
Simon Butcher69283e52016-10-06 12:49:58 +0100817 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
Simon Butcher327398a2016-10-05 14:09:11 +0100818
Janos Follathd4443582016-10-12 10:00:42 +0100819 mbedtls_cipher_init( &ctx );
820
Simon Butcher327398a2016-10-05 14:09:11 +0100821 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
822 {
823 if( verbose != 0 )
824 mbedtls_printf( "test execution failed\n" );
825
Janos Follathd4443582016-10-12 10:00:42 +0100826 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100827 }
828
829 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
830 MBEDTLS_ENCRYPT ) ) != 0 )
831 {
832 if( verbose != 0 )
833 mbedtls_printf( "test execution failed\n" );
834
Janos Follathd4443582016-10-12 10:00:42 +0100835 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100836 }
837
838 ret = cmac_generate_subkeys( &ctx, K1, K2 );
839 if( ret != 0 )
840 {
841 if( verbose != 0 )
842 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100843
844 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100845 }
846
Simon Butcher420be4e2016-10-07 12:55:43 +0100847 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
848 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100849 {
850 if( verbose != 0 )
851 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100852
853 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100854 }
855
856 if( verbose != 0 )
857 mbedtls_printf( "passed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100858
859 mbedtls_cipher_free( &ctx );
Simon Butcher327398a2016-10-05 14:09:11 +0100860 }
861
Gilles Peskinedf761d52018-03-01 22:18:14 +0100862 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100863 goto exit;
864
865cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100866 mbedtls_cipher_free( &ctx );
867
Janos Follathd4443582016-10-12 10:00:42 +0100868exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100869 return( ret );
870}
871
Simon Butcher69283e52016-10-06 12:49:58 +0100872static int cmac_test_wth_cipher( int verbose,
873 const char* testname,
874 const unsigned char* key,
875 int keybits,
876 const unsigned char* messages,
877 const unsigned int message_lengths[4],
878 const unsigned char* expected_result,
879 mbedtls_cipher_type_t cipher_type,
880 int block_size,
881 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700882{
Simon Butcher327398a2016-10-05 14:09:11 +0100883 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800884 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100885 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700886
Simon Butcher327398a2016-10-05 14:09:11 +0100887 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
888 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700889 {
Simon Butcher327398a2016-10-05 14:09:11 +0100890 /* Failing at this point must be due to a build issue */
891 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700892 goto exit;
893 }
894
895 for( i = 0; i < num_tests; i++ )
896 {
897 if( verbose != 0 )
Andres AGa592dcc2016-10-06 15:23:39 +0100898 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700899
Simon Butcher327398a2016-10-05 14:09:11 +0100900 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
901 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700902 {
903 if( verbose != 0 )
904 mbedtls_printf( "failed\n" );
905 goto exit;
906 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700907
Simon Butcher327398a2016-10-05 14:09:11 +0100908 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700909 {
910 if( verbose != 0 )
911 mbedtls_printf( "failed\n" );
912 goto exit;
913 }
914
Brian Murray9ce2e092016-05-24 22:46:43 -0700915 if( verbose != 0 )
916 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700917 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100918 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100919
Simon Butcher69283e52016-10-06 12:49:58 +0100920exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100921 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700922}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000923
Simon Butcher69283e52016-10-06 12:49:58 +0100924#if defined(MBEDTLS_AES_C)
925static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700926{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000927 int i;
928 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100929 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100930
Brian Murrayb0c3c432016-05-18 14:29:51 -0700931 for( i = 0; i < NB_PRF_TESTS; i++ )
932 {
Brian Murray0f6af732016-05-19 15:59:23 -0700933 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100934 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700935 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100936 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700937 {
Simon Butcher327398a2016-10-05 14:09:11 +0100938
Brian Murrayb0c3c432016-05-18 14:29:51 -0700939 if( verbose != 0 )
940 mbedtls_printf( "failed\n" );
941
Brian Murray0f6af732016-05-19 15:59:23 -0700942 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100943 }
944 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700945 {
946 mbedtls_printf( "passed\n" );
947 }
948 }
Brian Murray0f6af732016-05-19 15:59:23 -0700949 return( ret );
950}
951#endif /* MBEDTLS_AES_C */
952
953int mbedtls_cmac_self_test( int verbose )
954{
955 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100956
Simon Butcher69283e52016-10-06 12:49:58 +0100957#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100958 /* AES-128 */
959 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100960 "AES 128",
961 aes_128_key,
962 128,
963 (const unsigned char*)aes_128_subkeys,
964 MBEDTLS_CIPHER_AES_128_ECB,
965 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100966 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100967 {
968 return( ret );
969 }
970
Brian Murrayae1cb122016-05-23 15:01:59 -0700971 if( ( ret = cmac_test_wth_cipher( verbose,
972 "AES 128",
973 aes_128_key,
974 128,
975 test_message,
976 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100977 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100978 MBEDTLS_CIPHER_AES_128_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100979 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100980 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100981 {
982 return( ret );
983 }
984
985 /* AES-192 */
986 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100987 "AES 192",
988 aes_192_key,
989 192,
990 (const unsigned char*)aes_192_subkeys,
991 MBEDTLS_CIPHER_AES_192_ECB,
992 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100993 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700994 {
995 return( ret );
996 }
Brian Murray0f6af732016-05-19 15:59:23 -0700997
Brian Murrayae1cb122016-05-23 15:01:59 -0700998 if( ( ret = cmac_test_wth_cipher( verbose,
999 "AES 192",
1000 aes_192_key,
1001 192,
1002 test_message,
1003 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001004 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001005 MBEDTLS_CIPHER_AES_192_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001006 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001007 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001008 {
Simon Butcher327398a2016-10-05 14:09:11 +01001009 return( ret );
1010 }
1011
1012 /* AES-256 */
1013 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001014 "AES 256",
1015 aes_256_key,
1016 256,
1017 (const unsigned char*)aes_256_subkeys,
1018 MBEDTLS_CIPHER_AES_256_ECB,
1019 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001020 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001021 {
1022 return( ret );
1023 }
Brian Murray0f6af732016-05-19 15:59:23 -07001024
Simon Butcher69283e52016-10-06 12:49:58 +01001025 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -07001026 "AES 256",
1027 aes_256_key,
1028 256,
1029 test_message,
1030 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001031 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001032 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001033 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001034 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001035 {
1036 return( ret );
1037 }
Brian Murray0f6af732016-05-19 15:59:23 -07001038#endif /* MBEDTLS_AES_C */
1039
Simon Butcher69283e52016-10-06 12:49:58 +01001040#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001041 /* 3DES 2 key */
1042 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001043 "3DES 2 key",
1044 des3_2key_key,
1045 192,
1046 (const unsigned char*)des3_2key_subkeys,
1047 MBEDTLS_CIPHER_DES_EDE3_ECB,
1048 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001049 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001050 {
1051 return( ret );
1052 }
1053
Brian Murrayae1cb122016-05-23 15:01:59 -07001054 if( ( ret = cmac_test_wth_cipher( verbose,
1055 "3DES 2 key",
1056 des3_2key_key,
1057 192,
1058 test_message,
1059 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001060 (const unsigned char*)des3_2key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001061 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001062 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001063 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001064 {
1065 return( ret );
1066 }
Brian Murray0f6af732016-05-19 15:59:23 -07001067
Simon Butcher327398a2016-10-05 14:09:11 +01001068 /* 3DES 3 key */
1069 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001070 "3DES 3 key",
1071 des3_3key_key,
1072 192,
1073 (const unsigned char*)des3_3key_subkeys,
1074 MBEDTLS_CIPHER_DES_EDE3_ECB,
1075 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001076 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001077 {
1078 return( ret );
1079 }
1080
Brian Murrayae1cb122016-05-23 15:01:59 -07001081 if( ( ret = cmac_test_wth_cipher( verbose,
1082 "3DES 3 key",
1083 des3_3key_key,
1084 192,
1085 test_message,
1086 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001087 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001088 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001089 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001090 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001091 {
1092 return( ret );
1093 }
Brian Murray0f6af732016-05-19 15:59:23 -07001094#endif /* MBEDTLS_DES_C */
1095
Simon Butcher69283e52016-10-06 12:49:58 +01001096#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001097 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001098 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001099#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001100
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001101 if( verbose != 0 )
1102 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001103
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001104 return( 0 );
1105}
1106
Brian Murray0f6af732016-05-19 15:59:23 -07001107#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001108
1109#endif /* MBEDTLS_CMAC_C */