blob: 5575d5c8d738c57033393b0f14f13f2b6632bb19 [file] [log] [blame]
Robert Cragie3d23b1d2015-12-15 07:38:11 +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"
52
53#include <string.h>
54
Brian Murray8b4111c2016-09-13 15:58:46 -070055
Robert Cragie3d23b1d2015-12-15 07:38:11 +000056#if defined(MBEDTLS_PLATFORM_C)
57#include "mbedtls/platform.h"
58#else
Brian Murray8b4111c2016-09-13 15:58:46 -070059#include <stdlib.h>
60#define mbedtls_calloc calloc
61#define mbedtls_free free
Simon Butcherd241f1c2016-10-06 10:39:49 +010062#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000063#include <stdio.h>
Brian Murray8b4111c2016-09-13 15:58:46 -070064#define mbedtls_printf printf
Brian J Murray2adecba2016-11-06 04:45:15 -080065#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +000066#endif /* MBEDTLS_PLATFORM_C */
Brian Murray8b4111c2016-09-13 15:58:46 -070067
Steven Cooreman63342772017-04-04 11:47:16 +020068#if !defined(MBEDTLS_CMAC_ALT)
69
Robert Cragie3d23b1d2015-12-15 07:38:11 +000070/* Implementation that should never be optimized out by the compiler */
71static void mbedtls_zeroize( void *v, size_t n ) {
Simon Butcher327398a2016-10-05 14:09:11 +010072 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000073}
74
75/*
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
Simon Butcher327398a2016-10-05 14:09:11 +0100147 mbedtls_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:
165 mbedtls_zeroize( L, sizeof( L ) );
166
167 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000168}
169
Simon Butcher69283e52016-10-06 12:49:58 +0100170static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
171 const unsigned char *input2,
172 const size_t block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000173{
Simon Butcher327398a2016-10-05 14:09:11 +0100174 size_t index;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000175
Simon Butcher327398a2016-10-05 14:09:11 +0100176 for( index = 0; index < block_size; index++ )
177 output[ index ] = input1[ index ] ^ input2[ index ];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000178}
179
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000180/*
181 * Create padded last block from (partial) last block.
182 *
183 * We can't use the padding option from the cipher layer, as it only works for
184 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
185 */
Simon Butcher69283e52016-10-06 12:49:58 +0100186static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
Brian Murray53e23b62016-09-13 14:00:15 -0700187 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000188 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700189 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000190{
191 size_t j;
192
Brian Murrayb0c3c432016-05-18 14:29:51 -0700193 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000194 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700195 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000196 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700197 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000198 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000199 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000200 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000201 }
202}
203
Simon Butcher327398a2016-10-05 14:09:11 +0100204int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
Simon Butcher94ffde72016-10-05 15:33:53 +0100205 const unsigned char *key, size_t keybits )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000206{
Simon Butcher327398a2016-10-05 14:09:11 +0100207 mbedtls_cipher_type_t type;
208 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100209 int retval;
210
211 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
212 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
213
Simon B3249cb72016-11-03 01:11:37 +0000214 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
Simon Butcher327398a2016-10-05 14:09:11 +0100215 MBEDTLS_ENCRYPT ) ) != 0 )
216 return( retval );
217
Simon Butcher327398a2016-10-05 14:09:11 +0100218 type = ctx->cipher_info->type;
219
220 switch( type )
221 {
222 case MBEDTLS_CIPHER_AES_128_ECB:
223 case MBEDTLS_CIPHER_AES_192_ECB:
224 case MBEDTLS_CIPHER_AES_256_ECB:
225 case MBEDTLS_CIPHER_DES_EDE3_ECB:
226 break;
227 default:
228 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
229 }
230
231 /* Allocated and initialise in the cipher context memory for the CMAC
232 * context */
233 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
234 if( cmac_ctx == NULL )
235 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
236
237 ctx->cmac_ctx = cmac_ctx;
238
239 mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100240
241 return 0;
242}
243
244int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
245 const unsigned char *input, size_t ilen )
246{
247 mbedtls_cmac_context_t* cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700248 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000249 int ret = 0;
250 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700251
Simon Butcher327398a2016-10-05 14:09:11 +0100252 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
253 ctx->cmac_ctx == NULL )
254 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700255
Simon Butcher327398a2016-10-05 14:09:11 +0100256 cmac_ctx = ctx->cmac_ctx;
257 block_size = ctx->cipher_info->block_size;
258 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000259
Simon Butcher6b0774a2016-10-10 21:37:42 +0100260 /* Is there data still to process from the last call, that's greater in
261 * size than a block? */
Simon Butcher327398a2016-10-05 14:09:11 +0100262 if( cmac_ctx->unprocessed_len > 0 &&
Andres AGa592dcc2016-10-06 15:23:39 +0100263 ilen > block_size - cmac_ctx->unprocessed_len )
Brian Murray57863ad2016-05-19 16:38:36 -0700264 {
Simon Butcher327398a2016-10-05 14:09:11 +0100265 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
266 input,
267 block_size - cmac_ctx->unprocessed_len );
268
269 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
270
271 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
272 &olen ) ) != 0 )
273 {
274 goto exit;
275 }
276
Simon Butcher6b0774a2016-10-10 21:37:42 +0100277 input += block_size - cmac_ctx->unprocessed_len;
278 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100279 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700280 }
281
Simon Butcher327398a2016-10-05 14:09:11 +0100282 /* n is the number of blocks including any final partial block */
283 n = ( ilen + block_size - 1 ) / block_size;
284
Simon B3249cb72016-11-03 01:11:37 +0000285 /* Iterate across the input data in block sized chunks, excluding any
286 * final partial or complete block */
287 for( j = 1; j < n; j++ )
Brian Murray57863ad2016-05-19 16:38:36 -0700288 {
Simon Butcher327398a2016-10-05 14:09:11 +0100289 cmac_xor_block( state, input, state, block_size );
290
291 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
292 &olen ) ) != 0 )
293 goto exit;
294
295 ilen -= block_size;
296 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700297 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000298
Simon Butcher327398a2016-10-05 14:09:11 +0100299 /* If there is data left over that wasn't aligned to a block */
300 if( ilen > 0 )
301 {
Simon Butcher6b0774a2016-10-10 21:37:42 +0100302 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
303 input,
304 ilen );
305 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100306 }
307
308exit:
309 return( ret );
310}
311
312int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
313 unsigned char *output )
314{
315 mbedtls_cmac_context_t* cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100316 unsigned char *state, *last_block;
317 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
318 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
319 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100320 int ret;
321 size_t olen, block_size;
322
323 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
324 output == NULL )
325 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
326
327 cmac_ctx = ctx->cmac_ctx;
328 block_size = ctx->cipher_info->block_size;
329 state = cmac_ctx->state;
330
Simon Butcher69283e52016-10-06 12:49:58 +0100331 mbedtls_zeroize( K1, sizeof( K1 ) );
332 mbedtls_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100333 cmac_generate_subkeys( ctx, K1, K2 );
334
Simon Butcher69283e52016-10-06 12:49:58 +0100335 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000336
337 /* Calculate last block */
Janos Follathe3d882a2016-10-11 10:49:26 +0100338 if( cmac_ctx->unprocessed_len < block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000339 {
Simon Butcher327398a2016-10-05 14:09:11 +0100340 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
341 cmac_xor_block( M_last, M_last, K2, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000342 }
343 else
344 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000345 /* Last block is complete block */
Simon Butcher327398a2016-10-05 14:09:11 +0100346 cmac_xor_block( M_last, last_block, K1, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000347 }
348
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000349
Simon Butcher327398a2016-10-05 14:09:11 +0100350 cmac_xor_block( state, M_last, state, block_size );
351 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
352 &olen ) ) != 0 )
353 {
354 goto exit;
355 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000356
Simon Butcher327398a2016-10-05 14:09:11 +0100357 memcpy( output, state, block_size );
358
359exit:
360 /* Wipe the generated keys on the stack, and any other transients to avoid
361 * side channel leakage */
Simon Butcher69283e52016-10-06 12:49:58 +0100362 mbedtls_zeroize( K1, sizeof( K1 ) );
363 mbedtls_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100364
365 cmac_ctx->unprocessed_len = 0;
366 mbedtls_zeroize( cmac_ctx->unprocessed_block,
Simon Butcher69283e52016-10-06 12:49:58 +0100367 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100368
Simon Butcher69283e52016-10-06 12:49:58 +0100369 mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
Simon Butcher327398a2016-10-05 14:09:11 +0100370 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000371}
372
Simon Butcher327398a2016-10-05 14:09:11 +0100373int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000374{
Simon Butcher327398a2016-10-05 14:09:11 +0100375 mbedtls_cmac_context_t* cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000376
Simon Butcher327398a2016-10-05 14:09:11 +0100377 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
378 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700379
Simon Butcher327398a2016-10-05 14:09:11 +0100380 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000381
Simon Butcher327398a2016-10-05 14:09:11 +0100382 /* Reset the internal state */
383 cmac_ctx->unprocessed_len = 0;
384 mbedtls_zeroize( cmac_ctx->unprocessed_block,
Andres AGa592dcc2016-10-06 15:23:39 +0100385 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcherd241f1c2016-10-06 10:39:49 +0100386 mbedtls_zeroize( cmac_ctx->state,
387 sizeof( cmac_ctx->state ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000388
Simon Butcher327398a2016-10-05 14:09:11 +0100389 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000390}
391
Simon Butcher327398a2016-10-05 14:09:11 +0100392int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
393 const unsigned char *key, size_t keylen,
394 const unsigned char *input, size_t ilen,
395 unsigned char *output )
396{
397 mbedtls_cipher_context_t ctx;
398 int ret;
399
400 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
401 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
402
403 mbedtls_cipher_init( &ctx );
404
405 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
406 goto exit;
407
408 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
Simon Butcher327398a2016-10-05 14:09:11 +0100409 if( ret != 0 )
410 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100411
412 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
413 if( ret != 0 )
414 goto exit;
415
Simon Butcher69283e52016-10-06 12:49:58 +0100416 ret = mbedtls_cipher_cmac_finish( &ctx, output );
Simon Butcher327398a2016-10-05 14:09:11 +0100417
418exit:
Simon Butcher69283e52016-10-06 12:49:58 +0100419 mbedtls_cipher_free( &ctx );
420
Simon Butcher327398a2016-10-05 14:09:11 +0100421 return( ret );
422}
Simon Butcher327398a2016-10-05 14:09:11 +0100423
Simon Butcher69283e52016-10-06 12:49:58 +0100424#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000425/*
Simon Butcher69283e52016-10-06 12:49:58 +0100426 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000427 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700428int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000429 const unsigned char *input, size_t in_len,
Simon Butcher327398a2016-10-05 14:09:11 +0100430 unsigned char *output )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000431{
432 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100433 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100434 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
435 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
436
437 if( key == NULL || input == NULL || output == NULL )
438 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000439
Simon Butcher327398a2016-10-05 14:09:11 +0100440 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
441 if( cipher_info == NULL )
442 {
443 /* Failing at this point must be due to a build issue */
444 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
445 goto exit;
446 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700447
Simon Butcher69283e52016-10-06 12:49:58 +0100448 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000449 {
450 /* Use key as is */
Simon Butcher69283e52016-10-06 12:49:58 +0100451 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000452 }
453 else
454 {
Simon Butcher69283e52016-10-06 12:49:58 +0100455 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000456
Simon Butcher327398a2016-10-05 14:09:11 +0100457 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
458 key_length, int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000459 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700460 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000461 }
462
Simon Butcher327398a2016-10-05 14:09:11 +0100463 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
464 output );
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000465
Simon Butcher327398a2016-10-05 14:09:11 +0100466exit:
467 mbedtls_zeroize( int_key, sizeof( int_key ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700468
Simon Butcher327398a2016-10-05 14:09:11 +0100469 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000470}
Brian Murrayb439d452016-05-19 16:02:42 -0700471#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000472
Steven Cooreman63342772017-04-04 11:47:16 +0200473#endif /* !MBEDTLS_CMAC_ALT */
474
Simon Butcher69283e52016-10-06 12:49:58 +0100475#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000476/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000477 * CMAC test data for SP800-38B
478 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
479 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700480 *
481 * AES-CMAC-PRF-128 test data from RFC 4615
482 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000483 */
484
Brian Murray0f6af732016-05-19 15:59:23 -0700485#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000486#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100487
Brian Murray0f6af732016-05-19 15:59:23 -0700488#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
489/* All CMAC test inputs are truncated from the same 64 byte buffer. */
490static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000491 /* PT */
492 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
493 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
494 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
495 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
496 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
497 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
498 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
499 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000500};
Simon Butcher69283e52016-10-06 12:49:58 +0100501#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700502
Simon Butcher69283e52016-10-06 12:49:58 +0100503#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700504/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700505static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000506 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700507 0,
508 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000509 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700510 64
511};
512
Janos Follathcd13bd22016-12-13 11:51:04 +0000513/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700514static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000515 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
516 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700517};
Simon Butcher69283e52016-10-06 12:49:58 +0100518static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700519 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000520 /* K1 */
521 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
522 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700523 },
524 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000525 /* K2 */
526 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
527 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700528 }
529};
Simon Butcher69283e52016-10-06 12:49:58 +0100530static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000531 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000532 /* Example #1 */
533 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
534 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000535 },
536 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000537 /* Example #2 */
538 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
539 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000540 },
541 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000542 /* Example #3 */
543 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
544 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000545 },
546 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000547 /* Example #4 */
548 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
549 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000550 }
551};
552
Janos Follathcd13bd22016-12-13 11:51:04 +0000553/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700554static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000555 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
556 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
557 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000558};
Simon Butcher69283e52016-10-06 12:49:58 +0100559static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700560 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000561 /* K1 */
562 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
563 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700564 },
565 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000566 /* K2 */
567 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
568 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700569 }
570};
Simon Butcher69283e52016-10-06 12:49:58 +0100571static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700572 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000573 /* Example #1 */
574 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
575 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700576 },
577 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000578 /* Example #2 */
579 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
580 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700581 },
582 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000583 /* Example #3 */
584 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
585 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700586 },
587 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000588 /* Example #4 */
589 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
590 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700591 }
592};
593
Janos Follathcd13bd22016-12-13 11:51:04 +0000594/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700595static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000596 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
597 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
598 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
599 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700600};
Simon Butcher69283e52016-10-06 12:49:58 +0100601static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700602 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000603 /* K1 */
604 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
605 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700606 },
607 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000608 /* K2 */
609 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
610 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700611 }
612};
Simon Butcher69283e52016-10-06 12:49:58 +0100613static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700614 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000615 /* Example #1 */
616 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
617 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700618 },
619 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000620 /* Example #2 */
621 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
622 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700623 },
624 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000625 /* Example #3 */
626 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
627 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700628 },
629 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000630 /* Example #4 */
631 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
632 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700633 }
634};
635#endif /* MBEDTLS_AES_C */
636
Simon Butcher69283e52016-10-06 12:49:58 +0100637#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700638/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700639static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700640 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000641 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700642 20,
643 32
644};
645
Janos Follathcd13bd22016-12-13 11:51:04 +0000646/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700647static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000648 /* Key1 */
649 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
650 /* Key2 */
651 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
652 /* Key3 */
653 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700654};
655static const unsigned char des3_2key_subkeys[2][8] = {
656 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000657 /* K1 */
658 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700659 },
660 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000661 /* K2 */
662 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700663 }
664};
Simon Butcher69283e52016-10-06 12:49:58 +0100665static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700666 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000667 /* Sample #1 */
668 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700669 },
670 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000671 /* Sample #2 */
672 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700673 },
674 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000675 /* Sample #3 */
676 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700677 },
678 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000679 /* Sample #4 */
680 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700681 }
682};
683
Janos Follathcd13bd22016-12-13 11:51:04 +0000684/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700685static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000686 /* Key1 */
687 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
688 /* Key2 */
689 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
690 /* Key3 */
691 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700692};
693static const unsigned char des3_3key_subkeys[2][8] = {
694 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000695 /* K1 */
696 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700697 },
698 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000699 /* K2 */
700 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700701 }
702};
Simon Butcher69283e52016-10-06 12:49:58 +0100703static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700704 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000705 /* Sample #1 */
706 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700707 },
708 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000709 /* Sample #2 */
710 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700711 },
712 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000713 /* Sample #3 */
714 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700715 },
716 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000717 /* Sample #4 */
718 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700719 }
720};
721
Brian Murray0f6af732016-05-19 15:59:23 -0700722#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700723
Simon Butcher69283e52016-10-06 12:49:58 +0100724#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700725/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000726static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000727 /* Key */
728 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
729 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000730 0xed, 0xcb
731};
732
733/* Sizes in bytes */
734static const size_t PRFKlen[NB_PRF_TESTS] = {
735 18,
736 16,
737 10
738};
739
Janos Follathcd13bd22016-12-13 11:51:04 +0000740/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000741static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000742 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
743 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000744 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000745};
746
747static const unsigned char PRFT[NB_PRF_TESTS][16] = {
748 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000749 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
750 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000751 },
752 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000753 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
754 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000755 },
756 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000757 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
758 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000759 }
760};
Brian Murray0f6af732016-05-19 15:59:23 -0700761#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000762
Simon Butcher327398a2016-10-05 14:09:11 +0100763static int cmac_test_subkeys( int verbose,
764 const char* testname,
765 const unsigned char* key,
766 int keybits,
767 const unsigned char* subkeys,
768 mbedtls_cipher_type_t cipher_type,
769 int block_size,
770 int num_tests )
771{
772 int i, ret;
773 mbedtls_cipher_context_t ctx;
774 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100775 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
776 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100777
778 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
779 if( cipher_info == NULL )
780 {
781 /* Failing at this point must be due to a build issue */
Simon Butcher69283e52016-10-06 12:49:58 +0100782 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Simon Butcher327398a2016-10-05 14:09:11 +0100783 }
784
785 for( i = 0; i < num_tests; i++ )
786 {
787 if( verbose != 0 )
Simon Butcher69283e52016-10-06 12:49:58 +0100788 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
Simon Butcher327398a2016-10-05 14:09:11 +0100789
Janos Follathd4443582016-10-12 10:00:42 +0100790 mbedtls_cipher_init( &ctx );
791
Simon Butcher327398a2016-10-05 14:09:11 +0100792 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
793 {
794 if( verbose != 0 )
795 mbedtls_printf( "test execution failed\n" );
796
Janos Follathd4443582016-10-12 10:00:42 +0100797 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100798 }
799
800 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
801 MBEDTLS_ENCRYPT ) ) != 0 )
802 {
803 if( verbose != 0 )
804 mbedtls_printf( "test execution failed\n" );
805
Janos Follathd4443582016-10-12 10:00:42 +0100806 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100807 }
808
809 ret = cmac_generate_subkeys( &ctx, K1, K2 );
810 if( ret != 0 )
811 {
812 if( verbose != 0 )
813 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100814
815 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100816 }
817
Simon Butcher420be4e2016-10-07 12:55:43 +0100818 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
819 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100820 {
821 if( verbose != 0 )
822 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100823
824 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100825 }
826
827 if( verbose != 0 )
828 mbedtls_printf( "passed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100829
830 mbedtls_cipher_free( &ctx );
Simon Butcher327398a2016-10-05 14:09:11 +0100831 }
832
Janos Follathd4443582016-10-12 10:00:42 +0100833 goto exit;
834
835cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100836 mbedtls_cipher_free( &ctx );
837
Janos Follathd4443582016-10-12 10:00:42 +0100838exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100839 return( ret );
840}
841
Simon Butcher69283e52016-10-06 12:49:58 +0100842static int cmac_test_wth_cipher( int verbose,
843 const char* testname,
844 const unsigned char* key,
845 int keybits,
846 const unsigned char* messages,
847 const unsigned int message_lengths[4],
848 const unsigned char* expected_result,
849 mbedtls_cipher_type_t cipher_type,
850 int block_size,
851 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700852{
Simon Butcher327398a2016-10-05 14:09:11 +0100853 const mbedtls_cipher_info_t *cipher_info;
Brian Murray00dc5f02016-05-19 14:23:50 -0700854 int i, ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100855 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700856
Simon Butcher327398a2016-10-05 14:09:11 +0100857 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
858 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700859 {
Simon Butcher327398a2016-10-05 14:09:11 +0100860 /* Failing at this point must be due to a build issue */
861 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700862 goto exit;
863 }
864
865 for( i = 0; i < num_tests; i++ )
866 {
867 if( verbose != 0 )
Andres AGa592dcc2016-10-06 15:23:39 +0100868 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700869
Simon Butcher327398a2016-10-05 14:09:11 +0100870 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
871 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700872 {
873 if( verbose != 0 )
874 mbedtls_printf( "failed\n" );
875 goto exit;
876 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700877
Simon Butcher327398a2016-10-05 14:09:11 +0100878 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700879 {
880 if( verbose != 0 )
881 mbedtls_printf( "failed\n" );
882 goto exit;
883 }
884
Brian Murray9ce2e092016-05-24 22:46:43 -0700885 if( verbose != 0 )
886 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700887 }
Simon Butcher327398a2016-10-05 14:09:11 +0100888
Simon Butcher69283e52016-10-06 12:49:58 +0100889exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100890 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700891}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000892
Simon Butcher69283e52016-10-06 12:49:58 +0100893#if defined(MBEDTLS_AES_C)
894static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700895{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000896 int i;
897 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100898 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100899
Brian Murrayb0c3c432016-05-18 14:29:51 -0700900 for( i = 0; i < NB_PRF_TESTS; i++ )
901 {
Brian Murray0f6af732016-05-19 15:59:23 -0700902 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100903 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700904 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100905 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700906 {
Simon Butcher327398a2016-10-05 14:09:11 +0100907
Brian Murrayb0c3c432016-05-18 14:29:51 -0700908 if( verbose != 0 )
909 mbedtls_printf( "failed\n" );
910
Brian Murray0f6af732016-05-19 15:59:23 -0700911 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100912 }
913 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700914 {
915 mbedtls_printf( "passed\n" );
916 }
917 }
Brian Murray0f6af732016-05-19 15:59:23 -0700918 return( ret );
919}
920#endif /* MBEDTLS_AES_C */
921
922int mbedtls_cmac_self_test( int verbose )
923{
924 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100925
Simon Butcher69283e52016-10-06 12:49:58 +0100926#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100927 /* AES-128 */
928 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100929 "AES 128",
930 aes_128_key,
931 128,
932 (const unsigned char*)aes_128_subkeys,
933 MBEDTLS_CIPHER_AES_128_ECB,
934 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100935 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100936 {
937 return( ret );
938 }
939
Brian Murrayae1cb122016-05-23 15:01:59 -0700940 if( ( ret = cmac_test_wth_cipher( verbose,
941 "AES 128",
942 aes_128_key,
943 128,
944 test_message,
945 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100946 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100947 MBEDTLS_CIPHER_AES_128_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100948 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100949 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100950 {
951 return( ret );
952 }
953
954 /* AES-192 */
955 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100956 "AES 192",
957 aes_192_key,
958 192,
959 (const unsigned char*)aes_192_subkeys,
960 MBEDTLS_CIPHER_AES_192_ECB,
961 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100962 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700963 {
964 return( ret );
965 }
Brian Murray0f6af732016-05-19 15:59:23 -0700966
Brian Murrayae1cb122016-05-23 15:01:59 -0700967 if( ( ret = cmac_test_wth_cipher( verbose,
968 "AES 192",
969 aes_192_key,
970 192,
971 test_message,
972 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100973 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100974 MBEDTLS_CIPHER_AES_192_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100975 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100976 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100977 {
Simon Butcher327398a2016-10-05 14:09:11 +0100978 return( ret );
979 }
980
981 /* AES-256 */
982 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100983 "AES 256",
984 aes_256_key,
985 256,
986 (const unsigned char*)aes_256_subkeys,
987 MBEDTLS_CIPHER_AES_256_ECB,
988 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100989 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700990 {
991 return( ret );
992 }
Brian Murray0f6af732016-05-19 15:59:23 -0700993
Simon Butcher69283e52016-10-06 12:49:58 +0100994 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -0700995 "AES 256",
996 aes_256_key,
997 256,
998 test_message,
999 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001000 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001001 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001002 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001003 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001004 {
1005 return( ret );
1006 }
Brian Murray0f6af732016-05-19 15:59:23 -07001007#endif /* MBEDTLS_AES_C */
1008
Simon Butcher69283e52016-10-06 12:49:58 +01001009#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001010 /* 3DES 2 key */
1011 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001012 "3DES 2 key",
1013 des3_2key_key,
1014 192,
1015 (const unsigned char*)des3_2key_subkeys,
1016 MBEDTLS_CIPHER_DES_EDE3_ECB,
1017 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001018 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001019 {
1020 return( ret );
1021 }
1022
Brian Murrayae1cb122016-05-23 15:01:59 -07001023 if( ( ret = cmac_test_wth_cipher( verbose,
1024 "3DES 2 key",
1025 des3_2key_key,
1026 192,
1027 test_message,
1028 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001029 (const unsigned char*)des3_2key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001030 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001031 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001032 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001033 {
1034 return( ret );
1035 }
Brian Murray0f6af732016-05-19 15:59:23 -07001036
Simon Butcher327398a2016-10-05 14:09:11 +01001037 /* 3DES 3 key */
1038 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001039 "3DES 3 key",
1040 des3_3key_key,
1041 192,
1042 (const unsigned char*)des3_3key_subkeys,
1043 MBEDTLS_CIPHER_DES_EDE3_ECB,
1044 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001045 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001046 {
1047 return( ret );
1048 }
1049
Brian Murrayae1cb122016-05-23 15:01:59 -07001050 if( ( ret = cmac_test_wth_cipher( verbose,
1051 "3DES 3 key",
1052 des3_3key_key,
1053 192,
1054 test_message,
1055 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001056 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001057 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001058 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001059 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001060 {
1061 return( ret );
1062 }
Brian Murray0f6af732016-05-19 15:59:23 -07001063#endif /* MBEDTLS_DES_C */
1064
Simon Butcher69283e52016-10-06 12:49:58 +01001065#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001066 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001067 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001068#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001069
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001070 if( verbose != 0 )
1071 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001072
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001073 return( 0 );
1074}
1075
Brian Murray0f6af732016-05-19 15:59:23 -07001076#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001077
1078#endif /* MBEDTLS_CMAC_C */