blob: 9b7e8bf6b3dd7ca4ac27527fde38f18c08450ab6 [file] [log] [blame]
Andres Amaya Garciaaf610a02016-12-14 10:13:43 +00001/**
Brian Murray53e23b62016-09-13 14:00:15 -07002 * \file cmac.c
Simon Butcher327398a2016-10-05 14:09:11 +01003 *
Simon Butcher69283e52016-10-06 12:49:58 +01004 * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
Robert Cragie3d23b1d2015-12-15 07:38:11 +00005 *
Brian Murray53e23b62016-09-13 14:00:15 -07006 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
Robert Cragie3d23b1d2015-12-15 07:38:11 +00007 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
10 * not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23
24/*
Brian Murray53e23b62016-09-13 14:00:15 -070025 * References:
Simon Butcher327398a2016-10-05 14:09:11 +010026 *
27 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
28 * CMAC Mode for Authentication
Janos Follathcd13bd22016-12-13 11:51:04 +000029 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
Simon Butcher327398a2016-10-05 14:09:11 +010030 *
31 * - RFC 4493 - The AES-CMAC Algorithm
32 * https://tools.ietf.org/html/rfc4493
33 *
34 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
35 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
36 * Algorithm for the Internet Key Exchange Protocol (IKE)
37 * https://tools.ietf.org/html/rfc4615
38 *
39 * Additional test vectors: ISO/IEC 9797-1
40 *
Robert Cragie3d23b1d2015-12-15 07:38:11 +000041 */
42
43#if !defined(MBEDTLS_CONFIG_FILE)
44#include "mbedtls/config.h"
45#else
46#include MBEDTLS_CONFIG_FILE
47#endif
48
49#if defined(MBEDTLS_CMAC_C)
50
51#include "mbedtls/cmac.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050052#include "mbedtls/platform_util.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000053
54#include <string.h>
55
Brian Murray8b4111c2016-09-13 15:58:46 -070056
Robert Cragie3d23b1d2015-12-15 07:38:11 +000057#if defined(MBEDTLS_PLATFORM_C)
58#include "mbedtls/platform.h"
59#else
Brian Murray8b4111c2016-09-13 15:58:46 -070060#include <stdlib.h>
61#define mbedtls_calloc calloc
62#define mbedtls_free free
Simon Butcherd241f1c2016-10-06 10:39:49 +010063#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000064#include <stdio.h>
Brian Murray8b4111c2016-09-13 15:58:46 -070065#define mbedtls_printf printf
Brian J Murray2adecba2016-11-06 04:45:15 -080066#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +000067#endif /* MBEDTLS_PLATFORM_C */
Brian Murray8b4111c2016-09-13 15:58:46 -070068
Ron Eldor621080d2017-12-21 10:57:43 +020069#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020070
Unknown1ad679e2018-12-14 05:37:29 -050071#define MBEDTLS_CMAC_VALIDATE_RET(cond) \
72 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
73#define MBEDTLS_CMAC_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
74
Robert Cragie3d23b1d2015-12-15 07:38:11 +000075/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070076 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000077 *
Brian Murray72b69e32016-09-13 14:21:01 -070078 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000079 *
Simon Butcher327398a2016-10-05 14:09:11 +010080 * If MSB(p) = 0, then p = (p << 1)
81 * If MSB(p) = 1, then p = (p << 1) ^ R_n
82 * with R_64 = 0x1B and R_128 = 0x87
83 *
84 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -080085 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000086 */
Brian Murrayb0c3c432016-05-18 14:29:51 -070087static int cmac_multiply_by_u( unsigned char *output,
88 const unsigned char *input,
Brian Murray53e23b62016-09-13 14:00:15 -070089 size_t blocksize )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000090{
Brian Murrayb0c3c432016-05-18 14:29:51 -070091 const unsigned char R_128 = 0x87;
92 const unsigned char R_64 = 0x1B;
93 unsigned char R_n, mask;
94 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010095 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070096
Simon Butcher69283e52016-10-06 12:49:58 +010097 if( blocksize == MBEDTLS_AES_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -070098 {
Brian Murrayb0c3c432016-05-18 14:29:51 -070099 R_n = R_128;
Simon Butcher327398a2016-10-05 14:09:11 +0100100 }
Simon Butcher69283e52016-10-06 12:49:58 +0100101 else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700102 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700103 R_n = R_64;
Simon Butcher327398a2016-10-05 14:09:11 +0100104 }
105 else
Brian Murray6a3c0d22016-05-20 18:25:43 -0700106 {
Simon Butcher327398a2016-10-05 14:09:11 +0100107 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700108 }
109
Simon B3249cb72016-11-03 01:11:37 +0000110 for( i = (int)blocksize - 1; i >= 0; i-- )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000111 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000112 output[i] = input[i] << 1 | overflow;
113 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000114 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000115
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000116 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
117 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +0100118
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +0000119 /* MSVC has a warning about unary minus on unsigned, but this is
120 * well-defined and precisely what we want to do here */
121#if defined(_MSC_VER)
122#pragma warning( push )
123#pragma warning( disable : 4146 )
124#endif
125 mask = - ( input[0] >> 7 );
126#if defined(_MSC_VER)
127#pragma warning( pop )
128#endif
129
Simon Butcher327398a2016-10-05 14:09:11 +0100130 output[ blocksize - 1 ] ^= R_n & mask;
131
Brian Murrayb439d452016-05-19 16:02:42 -0700132 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000133}
134
135/*
136 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +0100137 *
138 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000139 */
Simon Butcher327398a2016-10-05 14:09:11 +0100140static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
141 unsigned char* K1, unsigned char* K2 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000142{
Brian Murray57863ad2016-05-19 16:38:36 -0700143 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100144 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700145 size_t olen, block_size;
146
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500147 mbedtls_platform_zeroize( L, sizeof( L ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700148
Simon Butcher327398a2016-10-05 14:09:11 +0100149 block_size = ctx->cipher_info->block_size;
150
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000151 /* Calculate Ek(0) */
Simon Butcher327398a2016-10-05 14:09:11 +0100152 if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700153 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000154
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000155 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000156 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000157 */
Simon Butcher327398a2016-10-05 14:09:11 +0100158 if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700159 goto exit;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000160
Simon Butcher327398a2016-10-05 14:09:11 +0100161 if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 )
162 goto exit;
163
164exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500165 mbedtls_platform_zeroize( L, sizeof( L ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100166
167 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000168}
Ron Eldor621080d2017-12-21 10:57:43 +0200169#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000170
Ron Eldor621080d2017-12-21 10:57:43 +0200171#if !defined(MBEDTLS_CMAC_ALT)
Simon Butcher69283e52016-10-06 12:49:58 +0100172static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
173 const unsigned char *input2,
174 const size_t block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000175{
Hanno Becker61937d42017-04-26 15:01:23 +0100176 size_t idx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000177
Hanno Becker61937d42017-04-26 15:01:23 +0100178 for( idx = 0; idx < block_size; idx++ )
179 output[ idx ] = input1[ idx ] ^ input2[ idx ];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000180}
181
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000182/*
183 * Create padded last block from (partial) last block.
184 *
185 * We can't use the padding option from the cipher layer, as it only works for
186 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
187 */
Simon Butcher69283e52016-10-06 12:49:58 +0100188static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
Brian Murray53e23b62016-09-13 14:00:15 -0700189 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000190 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700191 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000192{
193 size_t j;
194
Brian Murrayb0c3c432016-05-18 14:29:51 -0700195 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000196 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700197 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000198 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700199 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000200 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000201 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000202 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000203 }
204}
205
Simon Butcher327398a2016-10-05 14:09:11 +0100206int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
Simon Butcher94ffde72016-10-05 15:33:53 +0100207 const unsigned char *key, size_t keybits )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000208{
Simon Butcher327398a2016-10-05 14:09:11 +0100209 mbedtls_cipher_type_t type;
210 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100211 int retval;
212
Unknown1ad679e2018-12-14 05:37:29 -0500213 MBEDTLS_CMAC_VALIDATE_RET( ctx != NULL );
214 MBEDTLS_CMAC_VALIDATE_RET( ctx->cipher_info != NULL );
215 MBEDTLS_CMAC_VALIDATE_RET( key != NULL );
Simon Butcher327398a2016-10-05 14:09:11 +0100216
Simon B3249cb72016-11-03 01:11:37 +0000217 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
Simon Butcher327398a2016-10-05 14:09:11 +0100218 MBEDTLS_ENCRYPT ) ) != 0 )
219 return( retval );
220
Simon Butcher327398a2016-10-05 14:09:11 +0100221 type = ctx->cipher_info->type;
222
223 switch( type )
224 {
225 case MBEDTLS_CIPHER_AES_128_ECB:
226 case MBEDTLS_CIPHER_AES_192_ECB:
227 case MBEDTLS_CIPHER_AES_256_ECB:
228 case MBEDTLS_CIPHER_DES_EDE3_ECB:
229 break;
230 default:
231 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
232 }
233
234 /* Allocated and initialise in the cipher context memory for the CMAC
235 * context */
236 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
237 if( cmac_ctx == NULL )
238 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
239
240 ctx->cmac_ctx = cmac_ctx;
241
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500242 mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100243
244 return 0;
245}
246
247int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
248 const unsigned char *input, size_t ilen )
249{
250 mbedtls_cmac_context_t* cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700251 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000252 int ret = 0;
253 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700254
Unknown1ad679e2018-12-14 05:37:29 -0500255 MBEDTLS_CMAC_VALIDATE_RET( ctx != NULL );
256 MBEDTLS_CMAC_VALIDATE_RET( ctx->cipher_info != NULL );
257 MBEDTLS_CMAC_VALIDATE_RET( input != NULL );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700258
Simon Butcher327398a2016-10-05 14:09:11 +0100259 cmac_ctx = ctx->cmac_ctx;
260 block_size = ctx->cipher_info->block_size;
261 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000262
Simon Butcher6b0774a2016-10-10 21:37:42 +0100263 /* Is there data still to process from the last call, that's greater in
264 * size than a block? */
Simon Butcher327398a2016-10-05 14:09:11 +0100265 if( cmac_ctx->unprocessed_len > 0 &&
Andres AGa592dcc2016-10-06 15:23:39 +0100266 ilen > block_size - cmac_ctx->unprocessed_len )
Brian Murray57863ad2016-05-19 16:38:36 -0700267 {
Simon Butcher327398a2016-10-05 14:09:11 +0100268 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
269 input,
270 block_size - cmac_ctx->unprocessed_len );
271
272 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
273
274 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
275 &olen ) ) != 0 )
276 {
277 goto exit;
278 }
279
Simon Butcher6b0774a2016-10-10 21:37:42 +0100280 input += block_size - cmac_ctx->unprocessed_len;
281 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100282 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700283 }
284
Simon Butcher327398a2016-10-05 14:09:11 +0100285 /* n is the number of blocks including any final partial block */
286 n = ( ilen + block_size - 1 ) / block_size;
287
Simon B3249cb72016-11-03 01:11:37 +0000288 /* Iterate across the input data in block sized chunks, excluding any
289 * final partial or complete block */
290 for( j = 1; j < n; j++ )
Brian Murray57863ad2016-05-19 16:38:36 -0700291 {
Simon Butcher327398a2016-10-05 14:09:11 +0100292 cmac_xor_block( state, input, state, block_size );
293
294 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
295 &olen ) ) != 0 )
296 goto exit;
297
298 ilen -= block_size;
299 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700300 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000301
Simon Butcher327398a2016-10-05 14:09:11 +0100302 /* If there is data left over that wasn't aligned to a block */
303 if( ilen > 0 )
304 {
Simon Butcher6b0774a2016-10-10 21:37:42 +0100305 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
306 input,
307 ilen );
308 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100309 }
310
311exit:
312 return( ret );
313}
314
315int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
316 unsigned char *output )
317{
318 mbedtls_cmac_context_t* cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100319 unsigned char *state, *last_block;
320 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
321 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
322 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100323 int ret;
324 size_t olen, block_size;
325
Unknown1ad679e2018-12-14 05:37:29 -0500326 MBEDTLS_CMAC_VALIDATE_RET( ctx != NULL );
327 MBEDTLS_CMAC_VALIDATE_RET( ctx->cipher_info != NULL );
328 MBEDTLS_CMAC_VALIDATE_RET( ctx->cmac_ctx != NULL );
Simon Butcher327398a2016-10-05 14:09:11 +0100329
330 cmac_ctx = ctx->cmac_ctx;
331 block_size = ctx->cipher_info->block_size;
332 state = cmac_ctx->state;
333
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500334 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
335 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100336 cmac_generate_subkeys( ctx, K1, K2 );
337
Simon Butcher69283e52016-10-06 12:49:58 +0100338 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000339
340 /* Calculate last block */
Janos Follathe3d882a2016-10-11 10:49:26 +0100341 if( cmac_ctx->unprocessed_len < block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000342 {
Simon Butcher327398a2016-10-05 14:09:11 +0100343 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
344 cmac_xor_block( M_last, M_last, K2, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000345 }
346 else
347 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000348 /* Last block is complete block */
Simon Butcher327398a2016-10-05 14:09:11 +0100349 cmac_xor_block( M_last, last_block, K1, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000350 }
351
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000352
Simon Butcher327398a2016-10-05 14:09:11 +0100353 cmac_xor_block( state, M_last, state, block_size );
354 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
355 &olen ) ) != 0 )
356 {
357 goto exit;
358 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000359
Simon Butcher327398a2016-10-05 14:09:11 +0100360 memcpy( output, state, block_size );
361
362exit:
363 /* Wipe the generated keys on the stack, and any other transients to avoid
364 * side channel leakage */
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500365 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
366 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100367
368 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500369 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
370 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100371
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500372 mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
Simon Butcher327398a2016-10-05 14:09:11 +0100373 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000374}
375
Simon Butcher327398a2016-10-05 14:09:11 +0100376int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000377{
Simon Butcher327398a2016-10-05 14:09:11 +0100378 mbedtls_cmac_context_t* cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000379
Unknown1ad679e2018-12-14 05:37:29 -0500380 MBEDTLS_CMAC_VALIDATE_RET( ctx != NULL );
381 MBEDTLS_CMAC_VALIDATE_RET( ctx->cipher_info != NULL );
382 MBEDTLS_CMAC_VALIDATE_RET( ctx->cmac_ctx != NULL );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700383
Simon Butcher327398a2016-10-05 14:09:11 +0100384 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000385
Simon Butcher327398a2016-10-05 14:09:11 +0100386 /* Reset the internal state */
387 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500388 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
389 sizeof( cmac_ctx->unprocessed_block ) );
390 mbedtls_platform_zeroize( cmac_ctx->state,
391 sizeof( cmac_ctx->state ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000392
Simon Butcher327398a2016-10-05 14:09:11 +0100393 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000394}
395
Simon Butcher327398a2016-10-05 14:09:11 +0100396int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
397 const unsigned char *key, size_t keylen,
398 const unsigned char *input, size_t ilen,
399 unsigned char *output )
400{
401 mbedtls_cipher_context_t ctx;
402 int ret;
403
Unknown1ad679e2018-12-14 05:37:29 -0500404 MBEDTLS_CMAC_VALIDATE_RET( cipher_info != NULL );
405 MBEDTLS_CMAC_VALIDATE_RET( key != NULL );
406 MBEDTLS_CMAC_VALIDATE_RET( input != NULL );
407 MBEDTLS_CMAC_VALIDATE_RET( output != NULL );
Simon Butcher327398a2016-10-05 14:09:11 +0100408
409 mbedtls_cipher_init( &ctx );
410
411 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
412 goto exit;
413
414 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
Simon Butcher327398a2016-10-05 14:09:11 +0100415 if( ret != 0 )
416 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100417
418 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
419 if( ret != 0 )
420 goto exit;
421
Simon Butcher69283e52016-10-06 12:49:58 +0100422 ret = mbedtls_cipher_cmac_finish( &ctx, output );
Simon Butcher327398a2016-10-05 14:09:11 +0100423
424exit:
Simon Butcher69283e52016-10-06 12:49:58 +0100425 mbedtls_cipher_free( &ctx );
426
Simon Butcher327398a2016-10-05 14:09:11 +0100427 return( ret );
428}
Simon Butcher327398a2016-10-05 14:09:11 +0100429
Simon Butcher69283e52016-10-06 12:49:58 +0100430#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000431/*
Simon Butcher69283e52016-10-06 12:49:58 +0100432 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000433 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700434int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000435 const unsigned char *input, size_t in_len,
Simon Butcher327398a2016-10-05 14:09:11 +0100436 unsigned char *output )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000437{
438 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100439 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100440 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
441 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
442
Unknown1ad679e2018-12-14 05:37:29 -0500443 MBEDTLS_CMAC_VALIDATE_RET( key != NULL );
444 MBEDTLS_CMAC_VALIDATE_RET( input != NULL );
445 MBEDTLS_CMAC_VALIDATE_RET( output != NULL );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000446
Simon Butcher327398a2016-10-05 14:09:11 +0100447 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
448 if( cipher_info == NULL )
449 {
450 /* Failing at this point must be due to a build issue */
451 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
452 goto exit;
453 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700454
Simon Butcher69283e52016-10-06 12:49:58 +0100455 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000456 {
457 /* Use key as is */
Simon Butcher69283e52016-10-06 12:49:58 +0100458 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000459 }
460 else
461 {
Simon Butcher69283e52016-10-06 12:49:58 +0100462 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000463
Simon Butcher327398a2016-10-05 14:09:11 +0100464 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
465 key_length, int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000466 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700467 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000468 }
469
Simon Butcher327398a2016-10-05 14:09:11 +0100470 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
471 output );
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000472
Simon Butcher327398a2016-10-05 14:09:11 +0100473exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500474 mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700475
Simon Butcher327398a2016-10-05 14:09:11 +0100476 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000477}
Brian Murrayb439d452016-05-19 16:02:42 -0700478#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000479
Steven Cooreman63342772017-04-04 11:47:16 +0200480#endif /* !MBEDTLS_CMAC_ALT */
481
Simon Butcher69283e52016-10-06 12:49:58 +0100482#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000483/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000484 * CMAC test data for SP800-38B
485 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
486 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700487 *
488 * AES-CMAC-PRF-128 test data from RFC 4615
489 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000490 */
491
Brian Murray0f6af732016-05-19 15:59:23 -0700492#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000493#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100494
Brian Murray0f6af732016-05-19 15:59:23 -0700495#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
496/* All CMAC test inputs are truncated from the same 64 byte buffer. */
497static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000498 /* PT */
499 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
500 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
501 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
502 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
503 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
504 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
505 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
506 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000507};
Simon Butcher69283e52016-10-06 12:49:58 +0100508#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700509
Simon Butcher69283e52016-10-06 12:49:58 +0100510#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700511/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700512static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000513 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700514 0,
515 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000516 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700517 64
518};
519
Janos Follathcd13bd22016-12-13 11:51:04 +0000520/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700521static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000522 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
523 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700524};
Simon Butcher69283e52016-10-06 12:49:58 +0100525static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700526 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000527 /* K1 */
528 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
529 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700530 },
531 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000532 /* K2 */
533 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
534 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700535 }
536};
Simon Butcher69283e52016-10-06 12:49:58 +0100537static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000538 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000539 /* Example #1 */
540 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
541 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000542 },
543 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000544 /* Example #2 */
545 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
546 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000547 },
548 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000549 /* Example #3 */
550 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
551 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000552 },
553 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000554 /* Example #4 */
555 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
556 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000557 }
558};
559
Janos Follathcd13bd22016-12-13 11:51:04 +0000560/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700561static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000562 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
563 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
564 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000565};
Simon Butcher69283e52016-10-06 12:49:58 +0100566static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700567 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000568 /* K1 */
569 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
570 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700571 },
572 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000573 /* K2 */
574 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
575 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700576 }
577};
Simon Butcher69283e52016-10-06 12:49:58 +0100578static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700579 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000580 /* Example #1 */
581 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
582 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700583 },
584 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000585 /* Example #2 */
586 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
587 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700588 },
589 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000590 /* Example #3 */
591 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
592 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700593 },
594 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000595 /* Example #4 */
596 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
597 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700598 }
599};
600
Janos Follathcd13bd22016-12-13 11:51:04 +0000601/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700602static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000603 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
604 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
605 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
606 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700607};
Simon Butcher69283e52016-10-06 12:49:58 +0100608static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700609 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000610 /* K1 */
611 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
612 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700613 },
614 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000615 /* K2 */
616 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
617 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700618 }
619};
Simon Butcher69283e52016-10-06 12:49:58 +0100620static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700621 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000622 /* Example #1 */
623 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
624 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700625 },
626 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000627 /* Example #2 */
628 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
629 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700630 },
631 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000632 /* Example #3 */
633 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
634 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700635 },
636 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000637 /* Example #4 */
638 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
639 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700640 }
641};
642#endif /* MBEDTLS_AES_C */
643
Simon Butcher69283e52016-10-06 12:49:58 +0100644#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700645/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700646static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700647 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000648 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700649 20,
650 32
651};
652
Janos Follathcd13bd22016-12-13 11:51:04 +0000653/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700654static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000655 /* Key1 */
656 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
657 /* Key2 */
658 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
659 /* Key3 */
660 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700661};
662static const unsigned char des3_2key_subkeys[2][8] = {
663 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000664 /* K1 */
665 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700666 },
667 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000668 /* K2 */
669 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700670 }
671};
Simon Butcher69283e52016-10-06 12:49:58 +0100672static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700673 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000674 /* Sample #1 */
675 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700676 },
677 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000678 /* Sample #2 */
679 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700680 },
681 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000682 /* Sample #3 */
683 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700684 },
685 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000686 /* Sample #4 */
687 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700688 }
689};
690
Janos Follathcd13bd22016-12-13 11:51:04 +0000691/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700692static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000693 /* Key1 */
694 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
695 /* Key2 */
696 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
697 /* Key3 */
698 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700699};
700static const unsigned char des3_3key_subkeys[2][8] = {
701 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000702 /* K1 */
703 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700704 },
705 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000706 /* K2 */
707 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700708 }
709};
Simon Butcher69283e52016-10-06 12:49:58 +0100710static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700711 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000712 /* Sample #1 */
713 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700714 },
715 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000716 /* Sample #2 */
717 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700718 },
719 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000720 /* Sample #3 */
721 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700722 },
723 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000724 /* Sample #4 */
725 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700726 }
727};
728
Brian Murray0f6af732016-05-19 15:59:23 -0700729#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700730
Simon Butcher69283e52016-10-06 12:49:58 +0100731#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700732/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000733static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000734 /* Key */
735 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
736 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000737 0xed, 0xcb
738};
739
740/* Sizes in bytes */
741static const size_t PRFKlen[NB_PRF_TESTS] = {
742 18,
743 16,
744 10
745};
746
Janos Follathcd13bd22016-12-13 11:51:04 +0000747/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000748static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000749 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
750 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000751 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000752};
753
754static const unsigned char PRFT[NB_PRF_TESTS][16] = {
755 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000756 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
757 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000758 },
759 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000760 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
761 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000762 },
763 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000764 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
765 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000766 }
767};
Brian Murray0f6af732016-05-19 15:59:23 -0700768#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000769
Simon Butcher327398a2016-10-05 14:09:11 +0100770static int cmac_test_subkeys( int verbose,
771 const char* testname,
772 const unsigned char* key,
773 int keybits,
774 const unsigned char* subkeys,
775 mbedtls_cipher_type_t cipher_type,
776 int block_size,
777 int num_tests )
778{
Brian Murray2fab5c92016-12-15 18:51:13 -0800779 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100780 mbedtls_cipher_context_t ctx;
781 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100782 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
783 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100784
785 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
786 if( cipher_info == NULL )
787 {
788 /* Failing at this point must be due to a build issue */
Simon Butcher69283e52016-10-06 12:49:58 +0100789 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Simon Butcher327398a2016-10-05 14:09:11 +0100790 }
791
792 for( i = 0; i < num_tests; i++ )
793 {
794 if( verbose != 0 )
Simon Butcher69283e52016-10-06 12:49:58 +0100795 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
Simon Butcher327398a2016-10-05 14:09:11 +0100796
Janos Follathd4443582016-10-12 10:00:42 +0100797 mbedtls_cipher_init( &ctx );
798
Simon Butcher327398a2016-10-05 14:09:11 +0100799 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
800 {
801 if( verbose != 0 )
802 mbedtls_printf( "test execution failed\n" );
803
Janos Follathd4443582016-10-12 10:00:42 +0100804 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100805 }
806
807 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
808 MBEDTLS_ENCRYPT ) ) != 0 )
809 {
810 if( verbose != 0 )
811 mbedtls_printf( "test execution failed\n" );
812
Janos Follathd4443582016-10-12 10:00:42 +0100813 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100814 }
815
816 ret = cmac_generate_subkeys( &ctx, K1, K2 );
817 if( ret != 0 )
818 {
819 if( verbose != 0 )
820 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100821
822 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100823 }
824
Simon Butcher420be4e2016-10-07 12:55:43 +0100825 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
826 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100827 {
828 if( verbose != 0 )
829 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100830
831 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100832 }
833
834 if( verbose != 0 )
835 mbedtls_printf( "passed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100836
837 mbedtls_cipher_free( &ctx );
Simon Butcher327398a2016-10-05 14:09:11 +0100838 }
839
Gilles Peskinedf761d52018-03-01 22:18:14 +0100840 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100841 goto exit;
842
843cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100844 mbedtls_cipher_free( &ctx );
845
Janos Follathd4443582016-10-12 10:00:42 +0100846exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100847 return( ret );
848}
849
Simon Butcher69283e52016-10-06 12:49:58 +0100850static int cmac_test_wth_cipher( int verbose,
851 const char* testname,
852 const unsigned char* key,
853 int keybits,
854 const unsigned char* messages,
855 const unsigned int message_lengths[4],
856 const unsigned char* expected_result,
857 mbedtls_cipher_type_t cipher_type,
858 int block_size,
859 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700860{
Simon Butcher327398a2016-10-05 14:09:11 +0100861 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800862 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100863 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700864
Simon Butcher327398a2016-10-05 14:09:11 +0100865 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
866 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700867 {
Simon Butcher327398a2016-10-05 14:09:11 +0100868 /* Failing at this point must be due to a build issue */
869 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700870 goto exit;
871 }
872
873 for( i = 0; i < num_tests; i++ )
874 {
875 if( verbose != 0 )
Andres AGa592dcc2016-10-06 15:23:39 +0100876 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700877
Simon Butcher327398a2016-10-05 14:09:11 +0100878 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
879 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700880 {
881 if( verbose != 0 )
882 mbedtls_printf( "failed\n" );
883 goto exit;
884 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700885
Simon Butcher327398a2016-10-05 14:09:11 +0100886 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700887 {
888 if( verbose != 0 )
889 mbedtls_printf( "failed\n" );
890 goto exit;
891 }
892
Brian Murray9ce2e092016-05-24 22:46:43 -0700893 if( verbose != 0 )
894 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700895 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100896 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100897
Simon Butcher69283e52016-10-06 12:49:58 +0100898exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100899 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700900}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000901
Simon Butcher69283e52016-10-06 12:49:58 +0100902#if defined(MBEDTLS_AES_C)
903static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700904{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000905 int i;
906 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100907 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100908
Brian Murrayb0c3c432016-05-18 14:29:51 -0700909 for( i = 0; i < NB_PRF_TESTS; i++ )
910 {
Brian Murray0f6af732016-05-19 15:59:23 -0700911 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100912 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700913 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100914 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700915 {
Simon Butcher327398a2016-10-05 14:09:11 +0100916
Brian Murrayb0c3c432016-05-18 14:29:51 -0700917 if( verbose != 0 )
918 mbedtls_printf( "failed\n" );
919
Brian Murray0f6af732016-05-19 15:59:23 -0700920 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100921 }
922 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700923 {
924 mbedtls_printf( "passed\n" );
925 }
926 }
Brian Murray0f6af732016-05-19 15:59:23 -0700927 return( ret );
928}
929#endif /* MBEDTLS_AES_C */
930
931int mbedtls_cmac_self_test( int verbose )
932{
933 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100934
Simon Butcher69283e52016-10-06 12:49:58 +0100935#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100936 /* AES-128 */
937 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100938 "AES 128",
939 aes_128_key,
940 128,
941 (const unsigned char*)aes_128_subkeys,
942 MBEDTLS_CIPHER_AES_128_ECB,
943 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100944 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100945 {
946 return( ret );
947 }
948
Brian Murrayae1cb122016-05-23 15:01:59 -0700949 if( ( ret = cmac_test_wth_cipher( verbose,
950 "AES 128",
951 aes_128_key,
952 128,
953 test_message,
954 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100955 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100956 MBEDTLS_CIPHER_AES_128_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100957 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100958 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100959 {
960 return( ret );
961 }
962
963 /* AES-192 */
964 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100965 "AES 192",
966 aes_192_key,
967 192,
968 (const unsigned char*)aes_192_subkeys,
969 MBEDTLS_CIPHER_AES_192_ECB,
970 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100971 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700972 {
973 return( ret );
974 }
Brian Murray0f6af732016-05-19 15:59:23 -0700975
Brian Murrayae1cb122016-05-23 15:01:59 -0700976 if( ( ret = cmac_test_wth_cipher( verbose,
977 "AES 192",
978 aes_192_key,
979 192,
980 test_message,
981 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100982 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100983 MBEDTLS_CIPHER_AES_192_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100984 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100985 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100986 {
Simon Butcher327398a2016-10-05 14:09:11 +0100987 return( ret );
988 }
989
990 /* AES-256 */
991 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100992 "AES 256",
993 aes_256_key,
994 256,
995 (const unsigned char*)aes_256_subkeys,
996 MBEDTLS_CIPHER_AES_256_ECB,
997 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100998 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700999 {
1000 return( ret );
1001 }
Brian Murray0f6af732016-05-19 15:59:23 -07001002
Simon Butcher69283e52016-10-06 12:49:58 +01001003 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -07001004 "AES 256",
1005 aes_256_key,
1006 256,
1007 test_message,
1008 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001009 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001010 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001011 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001012 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001013 {
1014 return( ret );
1015 }
Brian Murray0f6af732016-05-19 15:59:23 -07001016#endif /* MBEDTLS_AES_C */
1017
Simon Butcher69283e52016-10-06 12:49:58 +01001018#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001019 /* 3DES 2 key */
1020 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001021 "3DES 2 key",
1022 des3_2key_key,
1023 192,
1024 (const unsigned char*)des3_2key_subkeys,
1025 MBEDTLS_CIPHER_DES_EDE3_ECB,
1026 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001027 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001028 {
1029 return( ret );
1030 }
1031
Brian Murrayae1cb122016-05-23 15:01:59 -07001032 if( ( ret = cmac_test_wth_cipher( verbose,
1033 "3DES 2 key",
1034 des3_2key_key,
1035 192,
1036 test_message,
1037 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001038 (const unsigned char*)des3_2key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001039 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001040 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001041 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001042 {
1043 return( ret );
1044 }
Brian Murray0f6af732016-05-19 15:59:23 -07001045
Simon Butcher327398a2016-10-05 14:09:11 +01001046 /* 3DES 3 key */
1047 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001048 "3DES 3 key",
1049 des3_3key_key,
1050 192,
1051 (const unsigned char*)des3_3key_subkeys,
1052 MBEDTLS_CIPHER_DES_EDE3_ECB,
1053 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001054 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001055 {
1056 return( ret );
1057 }
1058
Brian Murrayae1cb122016-05-23 15:01:59 -07001059 if( ( ret = cmac_test_wth_cipher( verbose,
1060 "3DES 3 key",
1061 des3_3key_key,
1062 192,
1063 test_message,
1064 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001065 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001066 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001067 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001068 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001069 {
1070 return( ret );
1071 }
Brian Murray0f6af732016-05-19 15:59:23 -07001072#endif /* MBEDTLS_DES_C */
1073
Simon Butcher69283e52016-10-06 12:49:58 +01001074#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001075 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001076 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001077#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001078
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001079 if( verbose != 0 )
1080 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001081
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001082 return( 0 );
1083}
1084
Brian Murray0f6af732016-05-19 15:59:23 -07001085#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001086
1087#endif /* MBEDTLS_CMAC_C */