blob: ce0cd4b0550af50a6529045b37a789101803aa5f [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útif744bd72020-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útif744bd72020-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"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050079#include "mbedtls/platform_util.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000080
81#include <string.h>
82
Brian Murray8b4111c2016-09-13 15:58:46 -070083
Robert Cragie3d23b1d2015-12-15 07:38:11 +000084#if defined(MBEDTLS_PLATFORM_C)
85#include "mbedtls/platform.h"
86#else
Brian Murray8b4111c2016-09-13 15:58:46 -070087#include <stdlib.h>
88#define mbedtls_calloc calloc
89#define mbedtls_free free
Simon Butcherd241f1c2016-10-06 10:39:49 +010090#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000091#include <stdio.h>
Brian Murray8b4111c2016-09-13 15:58:46 -070092#define mbedtls_printf printf
Brian J Murray2adecba2016-11-06 04:45:15 -080093#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +000094#endif /* MBEDTLS_PLATFORM_C */
Brian Murray8b4111c2016-09-13 15:58:46 -070095
Ron Eldor621080d2017-12-21 10:57:43 +020096#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020097
Robert Cragie3d23b1d2015-12-15 07:38:11 +000098/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070099 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000100 *
Brian Murray72b69e32016-09-13 14:21:01 -0700101 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000102 *
Simon Butcher327398a2016-10-05 14:09:11 +0100103 * If MSB(p) = 0, then p = (p << 1)
104 * If MSB(p) = 1, then p = (p << 1) ^ R_n
105 * with R_64 = 0x1B and R_128 = 0x87
106 *
107 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -0800108 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000109 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700110static int cmac_multiply_by_u( unsigned char *output,
111 const unsigned char *input,
Brian Murray53e23b62016-09-13 14:00:15 -0700112 size_t blocksize )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000113{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700114 const unsigned char R_128 = 0x87;
115 const unsigned char R_64 = 0x1B;
116 unsigned char R_n, mask;
117 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +0100118 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700119
Simon Butcher69283e52016-10-06 12:49:58 +0100120 if( blocksize == MBEDTLS_AES_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700121 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700122 R_n = R_128;
Simon Butcher327398a2016-10-05 14:09:11 +0100123 }
Simon Butcher69283e52016-10-06 12:49:58 +0100124 else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700125 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700126 R_n = R_64;
Simon Butcher327398a2016-10-05 14:09:11 +0100127 }
128 else
Brian Murray6a3c0d22016-05-20 18:25:43 -0700129 {
Simon Butcher327398a2016-10-05 14:09:11 +0100130 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700131 }
132
Simon B3249cb72016-11-03 01:11:37 +0000133 for( i = (int)blocksize - 1; i >= 0; i-- )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000134 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000135 output[i] = input[i] << 1 | overflow;
136 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000137 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000138
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000139 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
140 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +0100141
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000142 /* MSVC has a warning about unary minus on unsigned, but this is
143 * well-defined and precisely what we want to do here */
144#if defined(_MSC_VER)
145#pragma warning( push )
146#pragma warning( disable : 4146 )
147#endif
148 mask = - ( input[0] >> 7 );
149#if defined(_MSC_VER)
150#pragma warning( pop )
151#endif
152
Simon Butcher327398a2016-10-05 14:09:11 +0100153 output[ blocksize - 1 ] ^= R_n & mask;
154
Brian Murrayb439d452016-05-19 16:02:42 -0700155 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000156}
157
158/*
159 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +0100160 *
161 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000162 */
Simon Butcher327398a2016-10-05 14:09:11 +0100163static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
164 unsigned char* K1, unsigned char* K2 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000165{
Brian Murray57863ad2016-05-19 16:38:36 -0700166 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100167 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700168 size_t olen, block_size;
169
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500170 mbedtls_platform_zeroize( L, sizeof( L ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700171
Simon Butcher327398a2016-10-05 14:09:11 +0100172 block_size = ctx->cipher_info->block_size;
173
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000174 /* Calculate Ek(0) */
Simon Butcher327398a2016-10-05 14:09:11 +0100175 if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700176 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000177
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000178 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000179 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000180 */
Simon Butcher327398a2016-10-05 14:09:11 +0100181 if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700182 goto exit;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000183
Simon Butcher327398a2016-10-05 14:09:11 +0100184 if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 )
185 goto exit;
186
187exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500188 mbedtls_platform_zeroize( L, sizeof( L ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100189
190 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000191}
Ron Eldor621080d2017-12-21 10:57:43 +0200192#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000193
Ron Eldor621080d2017-12-21 10:57:43 +0200194#if !defined(MBEDTLS_CMAC_ALT)
Simon Butcher69283e52016-10-06 12:49:58 +0100195static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
196 const unsigned char *input2,
197 const size_t block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000198{
Hanno Becker61937d42017-04-26 15:01:23 +0100199 size_t idx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000200
Hanno Becker61937d42017-04-26 15:01:23 +0100201 for( idx = 0; idx < block_size; idx++ )
202 output[ idx ] = input1[ idx ] ^ input2[ idx ];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000203}
204
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000205/*
206 * Create padded last block from (partial) last block.
207 *
208 * We can't use the padding option from the cipher layer, as it only works for
209 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
210 */
Simon Butcher69283e52016-10-06 12:49:58 +0100211static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
Brian Murray53e23b62016-09-13 14:00:15 -0700212 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000213 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700214 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000215{
216 size_t j;
217
Brian Murrayb0c3c432016-05-18 14:29:51 -0700218 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000219 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700220 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000221 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700222 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000223 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000224 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000225 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000226 }
227}
228
Simon Butcher327398a2016-10-05 14:09:11 +0100229int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
Simon Butcher94ffde72016-10-05 15:33:53 +0100230 const unsigned char *key, size_t keybits )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000231{
Simon Butcher327398a2016-10-05 14:09:11 +0100232 mbedtls_cipher_type_t type;
233 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100234 int retval;
235
236 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
237 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
238
Simon B3249cb72016-11-03 01:11:37 +0000239 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
Simon Butcher327398a2016-10-05 14:09:11 +0100240 MBEDTLS_ENCRYPT ) ) != 0 )
241 return( retval );
242
Simon Butcher327398a2016-10-05 14:09:11 +0100243 type = ctx->cipher_info->type;
244
245 switch( type )
246 {
247 case MBEDTLS_CIPHER_AES_128_ECB:
248 case MBEDTLS_CIPHER_AES_192_ECB:
249 case MBEDTLS_CIPHER_AES_256_ECB:
250 case MBEDTLS_CIPHER_DES_EDE3_ECB:
251 break;
252 default:
253 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
254 }
255
256 /* Allocated and initialise in the cipher context memory for the CMAC
257 * context */
258 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
259 if( cmac_ctx == NULL )
260 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
261
262 ctx->cmac_ctx = cmac_ctx;
263
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500264 mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100265
266 return 0;
267}
268
269int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
270 const unsigned char *input, size_t ilen )
271{
272 mbedtls_cmac_context_t* cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700273 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000274 int ret = 0;
275 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700276
Simon Butcher327398a2016-10-05 14:09:11 +0100277 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
278 ctx->cmac_ctx == NULL )
279 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700280
Simon Butcher327398a2016-10-05 14:09:11 +0100281 cmac_ctx = ctx->cmac_ctx;
282 block_size = ctx->cipher_info->block_size;
283 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000284
Simon Butcher6b0774a2016-10-10 21:37:42 +0100285 /* Is there data still to process from the last call, that's greater in
286 * size than a block? */
Simon Butcher327398a2016-10-05 14:09:11 +0100287 if( cmac_ctx->unprocessed_len > 0 &&
Andres AGa592dcc2016-10-06 15:23:39 +0100288 ilen > block_size - cmac_ctx->unprocessed_len )
Brian Murray57863ad2016-05-19 16:38:36 -0700289 {
Simon Butcher327398a2016-10-05 14:09:11 +0100290 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
291 input,
292 block_size - cmac_ctx->unprocessed_len );
293
294 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
295
296 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
297 &olen ) ) != 0 )
298 {
299 goto exit;
300 }
301
Simon Butcher6b0774a2016-10-10 21:37:42 +0100302 input += block_size - cmac_ctx->unprocessed_len;
303 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100304 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700305 }
306
Simon Butcher327398a2016-10-05 14:09:11 +0100307 /* n is the number of blocks including any final partial block */
308 n = ( ilen + block_size - 1 ) / block_size;
309
Simon B3249cb72016-11-03 01:11:37 +0000310 /* Iterate across the input data in block sized chunks, excluding any
311 * final partial or complete block */
312 for( j = 1; j < n; j++ )
Brian Murray57863ad2016-05-19 16:38:36 -0700313 {
Simon Butcher327398a2016-10-05 14:09:11 +0100314 cmac_xor_block( state, input, state, block_size );
315
316 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
317 &olen ) ) != 0 )
318 goto exit;
319
320 ilen -= block_size;
321 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700322 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000323
Simon Butcher327398a2016-10-05 14:09:11 +0100324 /* If there is data left over that wasn't aligned to a block */
325 if( ilen > 0 )
326 {
Simon Butcher6b0774a2016-10-10 21:37:42 +0100327 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
328 input,
329 ilen );
330 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100331 }
332
333exit:
334 return( ret );
335}
336
337int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
338 unsigned char *output )
339{
340 mbedtls_cmac_context_t* cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100341 unsigned char *state, *last_block;
342 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
343 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
344 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100345 int ret;
346 size_t olen, block_size;
347
348 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
349 output == NULL )
350 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
351
352 cmac_ctx = ctx->cmac_ctx;
353 block_size = ctx->cipher_info->block_size;
354 state = cmac_ctx->state;
355
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500356 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
357 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100358 cmac_generate_subkeys( ctx, K1, K2 );
359
Simon Butcher69283e52016-10-06 12:49:58 +0100360 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000361
362 /* Calculate last block */
Janos Follathe3d882a2016-10-11 10:49:26 +0100363 if( cmac_ctx->unprocessed_len < block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000364 {
Simon Butcher327398a2016-10-05 14:09:11 +0100365 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
366 cmac_xor_block( M_last, M_last, K2, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000367 }
368 else
369 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000370 /* Last block is complete block */
Simon Butcher327398a2016-10-05 14:09:11 +0100371 cmac_xor_block( M_last, last_block, K1, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000372 }
373
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000374
Simon Butcher327398a2016-10-05 14:09:11 +0100375 cmac_xor_block( state, M_last, state, block_size );
376 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
377 &olen ) ) != 0 )
378 {
379 goto exit;
380 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000381
Simon Butcher327398a2016-10-05 14:09:11 +0100382 memcpy( output, state, block_size );
383
384exit:
385 /* Wipe the generated keys on the stack, and any other transients to avoid
386 * side channel leakage */
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500387 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
388 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100389
390 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500391 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
392 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100393
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500394 mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
Simon Butcher327398a2016-10-05 14:09:11 +0100395 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000396}
397
Simon Butcher327398a2016-10-05 14:09:11 +0100398int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000399{
Simon Butcher327398a2016-10-05 14:09:11 +0100400 mbedtls_cmac_context_t* cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000401
Simon Butcher327398a2016-10-05 14:09:11 +0100402 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
403 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700404
Simon Butcher327398a2016-10-05 14:09:11 +0100405 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000406
Simon Butcher327398a2016-10-05 14:09:11 +0100407 /* Reset the internal state */
408 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500409 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
410 sizeof( cmac_ctx->unprocessed_block ) );
411 mbedtls_platform_zeroize( cmac_ctx->state,
412 sizeof( cmac_ctx->state ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000413
Simon Butcher327398a2016-10-05 14:09:11 +0100414 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000415}
416
Simon Butcher327398a2016-10-05 14:09:11 +0100417int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
418 const unsigned char *key, size_t keylen,
419 const unsigned char *input, size_t ilen,
420 unsigned char *output )
421{
422 mbedtls_cipher_context_t ctx;
423 int ret;
424
425 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
426 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
427
428 mbedtls_cipher_init( &ctx );
429
430 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
431 goto exit;
432
433 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
Simon Butcher327398a2016-10-05 14:09:11 +0100434 if( ret != 0 )
435 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100436
437 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
438 if( ret != 0 )
439 goto exit;
440
Simon Butcher69283e52016-10-06 12:49:58 +0100441 ret = mbedtls_cipher_cmac_finish( &ctx, output );
Simon Butcher327398a2016-10-05 14:09:11 +0100442
443exit:
Simon Butcher69283e52016-10-06 12:49:58 +0100444 mbedtls_cipher_free( &ctx );
445
Simon Butcher327398a2016-10-05 14:09:11 +0100446 return( ret );
447}
Simon Butcher327398a2016-10-05 14:09:11 +0100448
Simon Butcher69283e52016-10-06 12:49:58 +0100449#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000450/*
Simon Butcher69283e52016-10-06 12:49:58 +0100451 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000452 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700453int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000454 const unsigned char *input, size_t in_len,
Simon Butcher327398a2016-10-05 14:09:11 +0100455 unsigned char *output )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000456{
457 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100458 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100459 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
460 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
461
462 if( key == NULL || input == NULL || output == NULL )
463 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000464
Simon Butcher327398a2016-10-05 14:09:11 +0100465 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
466 if( cipher_info == NULL )
467 {
468 /* Failing at this point must be due to a build issue */
469 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
470 goto exit;
471 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700472
Simon Butcher69283e52016-10-06 12:49:58 +0100473 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000474 {
475 /* Use key as is */
Simon Butcher69283e52016-10-06 12:49:58 +0100476 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000477 }
478 else
479 {
Simon Butcher69283e52016-10-06 12:49:58 +0100480 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000481
Simon Butcher327398a2016-10-05 14:09:11 +0100482 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
483 key_length, int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000484 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700485 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000486 }
487
Simon Butcher327398a2016-10-05 14:09:11 +0100488 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
489 output );
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000490
Simon Butcher327398a2016-10-05 14:09:11 +0100491exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500492 mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700493
Simon Butcher327398a2016-10-05 14:09:11 +0100494 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000495}
Brian Murrayb439d452016-05-19 16:02:42 -0700496#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000497
Steven Cooreman63342772017-04-04 11:47:16 +0200498#endif /* !MBEDTLS_CMAC_ALT */
499
Simon Butcher69283e52016-10-06 12:49:58 +0100500#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000501/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000502 * CMAC test data for SP800-38B
503 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
504 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700505 *
506 * AES-CMAC-PRF-128 test data from RFC 4615
507 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000508 */
509
Brian Murray0f6af732016-05-19 15:59:23 -0700510#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000511#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100512
Brian Murray0f6af732016-05-19 15:59:23 -0700513#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
514/* All CMAC test inputs are truncated from the same 64 byte buffer. */
515static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000516 /* PT */
517 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
518 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
519 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
520 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
521 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
522 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
523 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
524 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000525};
Simon Butcher69283e52016-10-06 12:49:58 +0100526#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700527
Simon Butcher69283e52016-10-06 12:49:58 +0100528#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700529/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700530static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000531 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700532 0,
533 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000534 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700535 64
536};
537
Janos Follathcd13bd22016-12-13 11:51:04 +0000538/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700539static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000540 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
541 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700542};
Simon Butcher69283e52016-10-06 12:49:58 +0100543static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700544 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000545 /* K1 */
546 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
547 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700548 },
549 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000550 /* K2 */
551 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
552 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700553 }
554};
Simon Butcher69283e52016-10-06 12:49:58 +0100555static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000556 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000557 /* Example #1 */
558 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
559 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000560 },
561 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000562 /* Example #2 */
563 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
564 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000565 },
566 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000567 /* Example #3 */
568 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
569 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000570 },
571 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000572 /* Example #4 */
573 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
574 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000575 }
576};
577
Janos Follathcd13bd22016-12-13 11:51:04 +0000578/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700579static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000580 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
581 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
582 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000583};
Simon Butcher69283e52016-10-06 12:49:58 +0100584static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700585 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000586 /* K1 */
587 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
588 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700589 },
590 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000591 /* K2 */
592 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
593 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700594 }
595};
Simon Butcher69283e52016-10-06 12:49:58 +0100596static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700597 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000598 /* Example #1 */
599 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
600 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700601 },
602 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000603 /* Example #2 */
604 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
605 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700606 },
607 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000608 /* Example #3 */
609 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
610 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700611 },
612 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000613 /* Example #4 */
614 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
615 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700616 }
617};
618
Janos Follathcd13bd22016-12-13 11:51:04 +0000619/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700620static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000621 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
622 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
623 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
624 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700625};
Simon Butcher69283e52016-10-06 12:49:58 +0100626static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700627 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000628 /* K1 */
629 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
630 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700631 },
632 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000633 /* K2 */
634 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
635 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700636 }
637};
Simon Butcher69283e52016-10-06 12:49:58 +0100638static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700639 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000640 /* Example #1 */
641 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
642 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700643 },
644 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000645 /* Example #2 */
646 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
647 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700648 },
649 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000650 /* Example #3 */
651 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
652 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700653 },
654 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000655 /* Example #4 */
656 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
657 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700658 }
659};
660#endif /* MBEDTLS_AES_C */
661
Simon Butcher69283e52016-10-06 12:49:58 +0100662#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700663/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700664static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700665 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000666 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700667 20,
668 32
669};
670
Janos Follathcd13bd22016-12-13 11:51:04 +0000671/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700672static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000673 /* Key1 */
674 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
675 /* Key2 */
676 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
677 /* Key3 */
678 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700679};
680static const unsigned char des3_2key_subkeys[2][8] = {
681 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000682 /* K1 */
683 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700684 },
685 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000686 /* K2 */
687 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700688 }
689};
Simon Butcher69283e52016-10-06 12:49:58 +0100690static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700691 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000692 /* Sample #1 */
693 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700694 },
695 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000696 /* Sample #2 */
697 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700698 },
699 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000700 /* Sample #3 */
701 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700702 },
703 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000704 /* Sample #4 */
705 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700706 }
707};
708
Janos Follathcd13bd22016-12-13 11:51:04 +0000709/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700710static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000711 /* Key1 */
712 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
713 /* Key2 */
714 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
715 /* Key3 */
716 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700717};
718static const unsigned char des3_3key_subkeys[2][8] = {
719 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000720 /* K1 */
721 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700722 },
723 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000724 /* K2 */
725 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700726 }
727};
Simon Butcher69283e52016-10-06 12:49:58 +0100728static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700729 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000730 /* Sample #1 */
731 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700732 },
733 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000734 /* Sample #2 */
735 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700736 },
737 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000738 /* Sample #3 */
739 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700740 },
741 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000742 /* Sample #4 */
743 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700744 }
745};
746
Brian Murray0f6af732016-05-19 15:59:23 -0700747#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700748
Simon Butcher69283e52016-10-06 12:49:58 +0100749#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700750/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000751static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000752 /* Key */
753 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
754 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000755 0xed, 0xcb
756};
757
758/* Sizes in bytes */
759static const size_t PRFKlen[NB_PRF_TESTS] = {
760 18,
761 16,
762 10
763};
764
Janos Follathcd13bd22016-12-13 11:51:04 +0000765/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000766static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000767 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
768 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000769 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000770};
771
772static const unsigned char PRFT[NB_PRF_TESTS][16] = {
773 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000774 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
775 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000776 },
777 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000778 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
779 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000780 },
781 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000782 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
783 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000784 }
785};
Brian Murray0f6af732016-05-19 15:59:23 -0700786#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000787
Simon Butcher327398a2016-10-05 14:09:11 +0100788static int cmac_test_subkeys( int verbose,
789 const char* testname,
790 const unsigned char* key,
791 int keybits,
792 const unsigned char* subkeys,
793 mbedtls_cipher_type_t cipher_type,
794 int block_size,
795 int num_tests )
796{
Brian Murray2fab5c92016-12-15 18:51:13 -0800797 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100798 mbedtls_cipher_context_t ctx;
799 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100800 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
801 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100802
803 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
804 if( cipher_info == NULL )
805 {
806 /* Failing at this point must be due to a build issue */
Simon Butcher69283e52016-10-06 12:49:58 +0100807 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Simon Butcher327398a2016-10-05 14:09:11 +0100808 }
809
810 for( i = 0; i < num_tests; i++ )
811 {
812 if( verbose != 0 )
Simon Butcher69283e52016-10-06 12:49:58 +0100813 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
Simon Butcher327398a2016-10-05 14:09:11 +0100814
Janos Follathd4443582016-10-12 10:00:42 +0100815 mbedtls_cipher_init( &ctx );
816
Simon Butcher327398a2016-10-05 14:09:11 +0100817 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
818 {
819 if( verbose != 0 )
820 mbedtls_printf( "test execution failed\n" );
821
Janos Follathd4443582016-10-12 10:00:42 +0100822 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100823 }
824
825 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
826 MBEDTLS_ENCRYPT ) ) != 0 )
827 {
828 if( verbose != 0 )
829 mbedtls_printf( "test execution failed\n" );
830
Janos Follathd4443582016-10-12 10:00:42 +0100831 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100832 }
833
834 ret = cmac_generate_subkeys( &ctx, K1, K2 );
835 if( ret != 0 )
836 {
837 if( verbose != 0 )
838 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100839
840 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100841 }
842
Simon Butcher420be4e2016-10-07 12:55:43 +0100843 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
844 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100845 {
846 if( verbose != 0 )
847 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100848
849 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100850 }
851
852 if( verbose != 0 )
853 mbedtls_printf( "passed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100854
855 mbedtls_cipher_free( &ctx );
Simon Butcher327398a2016-10-05 14:09:11 +0100856 }
857
Gilles Peskinedf761d52018-03-01 22:18:14 +0100858 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100859 goto exit;
860
861cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100862 mbedtls_cipher_free( &ctx );
863
Janos Follathd4443582016-10-12 10:00:42 +0100864exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100865 return( ret );
866}
867
Simon Butcher69283e52016-10-06 12:49:58 +0100868static int cmac_test_wth_cipher( int verbose,
869 const char* testname,
870 const unsigned char* key,
871 int keybits,
872 const unsigned char* messages,
873 const unsigned int message_lengths[4],
874 const unsigned char* expected_result,
875 mbedtls_cipher_type_t cipher_type,
876 int block_size,
877 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700878{
Simon Butcher327398a2016-10-05 14:09:11 +0100879 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800880 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100881 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700882
Simon Butcher327398a2016-10-05 14:09:11 +0100883 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
884 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700885 {
Simon Butcher327398a2016-10-05 14:09:11 +0100886 /* Failing at this point must be due to a build issue */
887 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700888 goto exit;
889 }
890
891 for( i = 0; i < num_tests; i++ )
892 {
893 if( verbose != 0 )
Andres AGa592dcc2016-10-06 15:23:39 +0100894 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700895
Simon Butcher327398a2016-10-05 14:09:11 +0100896 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
897 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700898 {
899 if( verbose != 0 )
900 mbedtls_printf( "failed\n" );
901 goto exit;
902 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700903
Simon Butcher327398a2016-10-05 14:09:11 +0100904 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700905 {
906 if( verbose != 0 )
907 mbedtls_printf( "failed\n" );
908 goto exit;
909 }
910
Brian Murray9ce2e092016-05-24 22:46:43 -0700911 if( verbose != 0 )
912 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700913 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100914 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100915
Simon Butcher69283e52016-10-06 12:49:58 +0100916exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100917 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700918}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000919
Simon Butcher69283e52016-10-06 12:49:58 +0100920#if defined(MBEDTLS_AES_C)
921static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700922{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000923 int i;
924 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100925 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100926
Brian Murrayb0c3c432016-05-18 14:29:51 -0700927 for( i = 0; i < NB_PRF_TESTS; i++ )
928 {
Brian Murray0f6af732016-05-19 15:59:23 -0700929 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100930 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700931 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100932 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700933 {
Simon Butcher327398a2016-10-05 14:09:11 +0100934
Brian Murrayb0c3c432016-05-18 14:29:51 -0700935 if( verbose != 0 )
936 mbedtls_printf( "failed\n" );
937
Brian Murray0f6af732016-05-19 15:59:23 -0700938 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100939 }
940 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700941 {
942 mbedtls_printf( "passed\n" );
943 }
944 }
Brian Murray0f6af732016-05-19 15:59:23 -0700945 return( ret );
946}
947#endif /* MBEDTLS_AES_C */
948
949int mbedtls_cmac_self_test( int verbose )
950{
951 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100952
Simon Butcher69283e52016-10-06 12:49:58 +0100953#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100954 /* AES-128 */
955 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100956 "AES 128",
957 aes_128_key,
958 128,
959 (const unsigned char*)aes_128_subkeys,
960 MBEDTLS_CIPHER_AES_128_ECB,
961 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100962 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100963 {
964 return( ret );
965 }
966
Brian Murrayae1cb122016-05-23 15:01:59 -0700967 if( ( ret = cmac_test_wth_cipher( verbose,
968 "AES 128",
969 aes_128_key,
970 128,
971 test_message,
972 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100973 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100974 MBEDTLS_CIPHER_AES_128_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 {
978 return( ret );
979 }
980
981 /* AES-192 */
982 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100983 "AES 192",
984 aes_192_key,
985 192,
986 (const unsigned char*)aes_192_subkeys,
987 MBEDTLS_CIPHER_AES_192_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
Brian Murrayae1cb122016-05-23 15:01:59 -0700994 if( ( ret = cmac_test_wth_cipher( verbose,
995 "AES 192",
996 aes_192_key,
997 192,
998 test_message,
999 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001000 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001001 MBEDTLS_CIPHER_AES_192_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 )
Simon Butcher327398a2016-10-05 14:09:11 +01001004 {
Simon Butcher327398a2016-10-05 14:09:11 +01001005 return( ret );
1006 }
1007
1008 /* AES-256 */
1009 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001010 "AES 256",
1011 aes_256_key,
1012 256,
1013 (const unsigned char*)aes_256_subkeys,
1014 MBEDTLS_CIPHER_AES_256_ECB,
1015 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001016 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001017 {
1018 return( ret );
1019 }
Brian Murray0f6af732016-05-19 15:59:23 -07001020
Simon Butcher69283e52016-10-06 12:49:58 +01001021 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -07001022 "AES 256",
1023 aes_256_key,
1024 256,
1025 test_message,
1026 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001027 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001028 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001029 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001030 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001031 {
1032 return( ret );
1033 }
Brian Murray0f6af732016-05-19 15:59:23 -07001034#endif /* MBEDTLS_AES_C */
1035
Simon Butcher69283e52016-10-06 12:49:58 +01001036#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001037 /* 3DES 2 key */
1038 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001039 "3DES 2 key",
1040 des3_2key_key,
1041 192,
1042 (const unsigned char*)des3_2key_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 2 key",
1052 des3_2key_key,
1053 192,
1054 test_message,
1055 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001056 (const unsigned char*)des3_2key_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
Simon Butcher327398a2016-10-05 14:09:11 +01001064 /* 3DES 3 key */
1065 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001066 "3DES 3 key",
1067 des3_3key_key,
1068 192,
1069 (const unsigned char*)des3_3key_subkeys,
1070 MBEDTLS_CIPHER_DES_EDE3_ECB,
1071 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001072 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001073 {
1074 return( ret );
1075 }
1076
Brian Murrayae1cb122016-05-23 15:01:59 -07001077 if( ( ret = cmac_test_wth_cipher( verbose,
1078 "3DES 3 key",
1079 des3_3key_key,
1080 192,
1081 test_message,
1082 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001083 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001084 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001085 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001086 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001087 {
1088 return( ret );
1089 }
Brian Murray0f6af732016-05-19 15:59:23 -07001090#endif /* MBEDTLS_DES_C */
1091
Simon Butcher69283e52016-10-06 12:49:58 +01001092#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001093 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001094 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001095#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001096
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001097 if( verbose != 0 )
1098 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001099
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001100 return( 0 );
1101}
1102
Brian Murray0f6af732016-05-19 15:59:23 -07001103#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001104
1105#endif /* MBEDTLS_CMAC_C */