blob: 9a73faa6d5c522c9e84c14c6bc9abc066c185a19 [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"
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
Ron Eldor621080d2017-12-21 10:57:43 +020068#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020069
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}
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
213 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
214 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
215
Simon B3249cb72016-11-03 01:11:37 +0000216 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
Simon Butcher327398a2016-10-05 14:09:11 +0100217 MBEDTLS_ENCRYPT ) ) != 0 )
218 return( retval );
219
Simon Butcher327398a2016-10-05 14:09:11 +0100220 type = ctx->cipher_info->type;
221
222 switch( type )
223 {
224 case MBEDTLS_CIPHER_AES_128_ECB:
225 case MBEDTLS_CIPHER_AES_192_ECB:
226 case MBEDTLS_CIPHER_AES_256_ECB:
227 case MBEDTLS_CIPHER_DES_EDE3_ECB:
228 break;
229 default:
230 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
231 }
232
233 /* Allocated and initialise in the cipher context memory for the CMAC
234 * context */
235 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
236 if( cmac_ctx == NULL )
237 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
238
239 ctx->cmac_ctx = cmac_ctx;
240
241 mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100242
243 return 0;
244}
245
246int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
247 const unsigned char *input, size_t ilen )
248{
249 mbedtls_cmac_context_t* cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700250 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000251 int ret = 0;
252 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700253
Simon Butcher327398a2016-10-05 14:09:11 +0100254 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
255 ctx->cmac_ctx == NULL )
256 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700257
Simon Butcher327398a2016-10-05 14:09:11 +0100258 cmac_ctx = ctx->cmac_ctx;
259 block_size = ctx->cipher_info->block_size;
260 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000261
Simon Butcher6b0774a2016-10-10 21:37:42 +0100262 /* Is there data still to process from the last call, that's greater in
263 * size than a block? */
Simon Butcher327398a2016-10-05 14:09:11 +0100264 if( cmac_ctx->unprocessed_len > 0 &&
Andres AGa592dcc2016-10-06 15:23:39 +0100265 ilen > block_size - cmac_ctx->unprocessed_len )
Brian Murray57863ad2016-05-19 16:38:36 -0700266 {
Simon Butcher327398a2016-10-05 14:09:11 +0100267 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
268 input,
269 block_size - cmac_ctx->unprocessed_len );
270
271 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
272
273 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
274 &olen ) ) != 0 )
275 {
276 goto exit;
277 }
278
Simon Butcher6b0774a2016-10-10 21:37:42 +0100279 input += block_size - cmac_ctx->unprocessed_len;
280 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100281 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700282 }
283
Simon Butcher327398a2016-10-05 14:09:11 +0100284 /* n is the number of blocks including any final partial block */
285 n = ( ilen + block_size - 1 ) / block_size;
286
Simon B3249cb72016-11-03 01:11:37 +0000287 /* Iterate across the input data in block sized chunks, excluding any
288 * final partial or complete block */
289 for( j = 1; j < n; j++ )
Brian Murray57863ad2016-05-19 16:38:36 -0700290 {
Simon Butcher327398a2016-10-05 14:09:11 +0100291 cmac_xor_block( state, input, state, block_size );
292
293 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
294 &olen ) ) != 0 )
295 goto exit;
296
297 ilen -= block_size;
298 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700299 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000300
Simon Butcher327398a2016-10-05 14:09:11 +0100301 /* If there is data left over that wasn't aligned to a block */
302 if( ilen > 0 )
303 {
Simon Butcher6b0774a2016-10-10 21:37:42 +0100304 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
305 input,
306 ilen );
307 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100308 }
309
310exit:
311 return( ret );
312}
313
314int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
315 unsigned char *output )
316{
317 mbedtls_cmac_context_t* cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100318 unsigned char *state, *last_block;
319 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
320 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
321 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100322 int ret;
323 size_t olen, block_size;
324
325 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
326 output == NULL )
327 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
328
329 cmac_ctx = ctx->cmac_ctx;
330 block_size = ctx->cipher_info->block_size;
331 state = cmac_ctx->state;
332
Simon Butcher69283e52016-10-06 12:49:58 +0100333 mbedtls_zeroize( K1, sizeof( K1 ) );
334 mbedtls_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100335 cmac_generate_subkeys( ctx, K1, K2 );
336
Simon Butcher69283e52016-10-06 12:49:58 +0100337 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000338
339 /* Calculate last block */
Janos Follathe3d882a2016-10-11 10:49:26 +0100340 if( cmac_ctx->unprocessed_len < block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000341 {
Simon Butcher327398a2016-10-05 14:09:11 +0100342 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
343 cmac_xor_block( M_last, M_last, K2, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000344 }
345 else
346 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000347 /* Last block is complete block */
Simon Butcher327398a2016-10-05 14:09:11 +0100348 cmac_xor_block( M_last, last_block, K1, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000349 }
350
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000351
Simon Butcher327398a2016-10-05 14:09:11 +0100352 cmac_xor_block( state, M_last, state, block_size );
353 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
354 &olen ) ) != 0 )
355 {
356 goto exit;
357 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000358
Simon Butcher327398a2016-10-05 14:09:11 +0100359 memcpy( output, state, block_size );
360
361exit:
362 /* Wipe the generated keys on the stack, and any other transients to avoid
363 * side channel leakage */
Simon Butcher69283e52016-10-06 12:49:58 +0100364 mbedtls_zeroize( K1, sizeof( K1 ) );
365 mbedtls_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100366
367 cmac_ctx->unprocessed_len = 0;
368 mbedtls_zeroize( cmac_ctx->unprocessed_block,
Simon Butcher69283e52016-10-06 12:49:58 +0100369 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100370
Simon Butcher69283e52016-10-06 12:49:58 +0100371 mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
Simon Butcher327398a2016-10-05 14:09:11 +0100372 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000373}
374
Simon Butcher327398a2016-10-05 14:09:11 +0100375int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000376{
Simon Butcher327398a2016-10-05 14:09:11 +0100377 mbedtls_cmac_context_t* cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000378
Simon Butcher327398a2016-10-05 14:09:11 +0100379 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
380 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700381
Simon Butcher327398a2016-10-05 14:09:11 +0100382 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000383
Simon Butcher327398a2016-10-05 14:09:11 +0100384 /* Reset the internal state */
385 cmac_ctx->unprocessed_len = 0;
386 mbedtls_zeroize( cmac_ctx->unprocessed_block,
Andres AGa592dcc2016-10-06 15:23:39 +0100387 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcherd241f1c2016-10-06 10:39:49 +0100388 mbedtls_zeroize( cmac_ctx->state,
389 sizeof( cmac_ctx->state ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000390
Simon Butcher327398a2016-10-05 14:09:11 +0100391 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000392}
393
Simon Butcher327398a2016-10-05 14:09:11 +0100394int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
395 const unsigned char *key, size_t keylen,
396 const unsigned char *input, size_t ilen,
397 unsigned char *output )
398{
399 mbedtls_cipher_context_t ctx;
400 int ret;
401
402 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
403 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
404
405 mbedtls_cipher_init( &ctx );
406
407 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
408 goto exit;
409
410 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
Simon Butcher327398a2016-10-05 14:09:11 +0100411 if( ret != 0 )
412 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100413
414 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
415 if( ret != 0 )
416 goto exit;
417
Simon Butcher69283e52016-10-06 12:49:58 +0100418 ret = mbedtls_cipher_cmac_finish( &ctx, output );
Simon Butcher327398a2016-10-05 14:09:11 +0100419
420exit:
Simon Butcher69283e52016-10-06 12:49:58 +0100421 mbedtls_cipher_free( &ctx );
422
Simon Butcher327398a2016-10-05 14:09:11 +0100423 return( ret );
424}
Simon Butcher327398a2016-10-05 14:09:11 +0100425
Simon Butcher69283e52016-10-06 12:49:58 +0100426#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000427/*
Simon Butcher69283e52016-10-06 12:49:58 +0100428 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000429 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700430int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000431 const unsigned char *input, size_t in_len,
Simon Butcher327398a2016-10-05 14:09:11 +0100432 unsigned char *output )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000433{
434 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100435 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100436 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
437 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
438
439 if( key == NULL || input == NULL || output == NULL )
440 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000441
Simon Butcher327398a2016-10-05 14:09:11 +0100442 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
443 if( cipher_info == NULL )
444 {
445 /* Failing at this point must be due to a build issue */
446 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
447 goto exit;
448 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700449
Simon Butcher69283e52016-10-06 12:49:58 +0100450 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000451 {
452 /* Use key as is */
Simon Butcher69283e52016-10-06 12:49:58 +0100453 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000454 }
455 else
456 {
Simon Butcher69283e52016-10-06 12:49:58 +0100457 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000458
Simon Butcher327398a2016-10-05 14:09:11 +0100459 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
460 key_length, int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000461 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700462 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000463 }
464
Simon Butcher327398a2016-10-05 14:09:11 +0100465 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
466 output );
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000467
Simon Butcher327398a2016-10-05 14:09:11 +0100468exit:
469 mbedtls_zeroize( int_key, sizeof( int_key ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700470
Simon Butcher327398a2016-10-05 14:09:11 +0100471 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000472}
Brian Murrayb439d452016-05-19 16:02:42 -0700473#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000474
Steven Cooreman63342772017-04-04 11:47:16 +0200475#endif /* !MBEDTLS_CMAC_ALT */
476
Simon Butcher69283e52016-10-06 12:49:58 +0100477#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000478/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000479 * CMAC test data for SP800-38B
480 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
481 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700482 *
483 * AES-CMAC-PRF-128 test data from RFC 4615
484 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000485 */
486
Brian Murray0f6af732016-05-19 15:59:23 -0700487#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000488#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100489
Brian Murray0f6af732016-05-19 15:59:23 -0700490#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
491/* All CMAC test inputs are truncated from the same 64 byte buffer. */
492static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000493 /* PT */
494 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
495 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
496 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
497 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
498 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
499 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
500 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
501 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000502};
Simon Butcher69283e52016-10-06 12:49:58 +0100503#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700504
Simon Butcher69283e52016-10-06 12:49:58 +0100505#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700506/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700507static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000508 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700509 0,
510 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000511 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700512 64
513};
514
Janos Follathcd13bd22016-12-13 11:51:04 +0000515/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700516static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000517 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
518 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700519};
Simon Butcher69283e52016-10-06 12:49:58 +0100520static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700521 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000522 /* K1 */
523 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
524 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700525 },
526 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000527 /* K2 */
528 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
529 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700530 }
531};
Simon Butcher69283e52016-10-06 12:49:58 +0100532static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000533 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000534 /* Example #1 */
535 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
536 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000537 },
538 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000539 /* Example #2 */
540 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
541 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000542 },
543 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000544 /* Example #3 */
545 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
546 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000547 },
548 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000549 /* Example #4 */
550 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
551 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000552 }
553};
554
Janos Follathcd13bd22016-12-13 11:51:04 +0000555/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700556static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000557 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
558 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
559 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000560};
Simon Butcher69283e52016-10-06 12:49:58 +0100561static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700562 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000563 /* K1 */
564 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
565 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700566 },
567 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000568 /* K2 */
569 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
570 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700571 }
572};
Simon Butcher69283e52016-10-06 12:49:58 +0100573static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700574 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000575 /* Example #1 */
576 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
577 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700578 },
579 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000580 /* Example #2 */
581 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
582 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700583 },
584 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000585 /* Example #3 */
586 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
587 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700588 },
589 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000590 /* Example #4 */
591 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
592 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700593 }
594};
595
Janos Follathcd13bd22016-12-13 11:51:04 +0000596/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700597static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000598 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
599 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
600 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
601 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700602};
Simon Butcher69283e52016-10-06 12:49:58 +0100603static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700604 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000605 /* K1 */
606 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
607 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700608 },
609 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000610 /* K2 */
611 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
612 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700613 }
614};
Simon Butcher69283e52016-10-06 12:49:58 +0100615static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700616 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000617 /* Example #1 */
618 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
619 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700620 },
621 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000622 /* Example #2 */
623 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
624 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700625 },
626 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000627 /* Example #3 */
628 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
629 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700630 },
631 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000632 /* Example #4 */
633 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
634 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700635 }
636};
637#endif /* MBEDTLS_AES_C */
638
Simon Butcher69283e52016-10-06 12:49:58 +0100639#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700640/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700641static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700642 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000643 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700644 20,
645 32
646};
647
Janos Follathcd13bd22016-12-13 11:51:04 +0000648/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700649static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000650 /* Key1 */
651 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
652 /* Key2 */
653 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
654 /* Key3 */
655 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700656};
657static const unsigned char des3_2key_subkeys[2][8] = {
658 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000659 /* K1 */
660 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700661 },
662 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000663 /* K2 */
664 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700665 }
666};
Simon Butcher69283e52016-10-06 12:49:58 +0100667static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700668 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000669 /* Sample #1 */
670 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700671 },
672 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000673 /* Sample #2 */
674 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700675 },
676 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000677 /* Sample #3 */
678 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700679 },
680 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000681 /* Sample #4 */
682 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700683 }
684};
685
Janos Follathcd13bd22016-12-13 11:51:04 +0000686/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700687static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000688 /* Key1 */
689 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
690 /* Key2 */
691 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
692 /* Key3 */
693 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700694};
695static const unsigned char des3_3key_subkeys[2][8] = {
696 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000697 /* K1 */
698 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700699 },
700 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000701 /* K2 */
702 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700703 }
704};
Simon Butcher69283e52016-10-06 12:49:58 +0100705static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700706 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000707 /* Sample #1 */
708 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700709 },
710 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000711 /* Sample #2 */
712 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700713 },
714 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000715 /* Sample #3 */
716 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700717 },
718 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000719 /* Sample #4 */
720 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700721 }
722};
723
Brian Murray0f6af732016-05-19 15:59:23 -0700724#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700725
Simon Butcher69283e52016-10-06 12:49:58 +0100726#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700727/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000728static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000729 /* Key */
730 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
731 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000732 0xed, 0xcb
733};
734
735/* Sizes in bytes */
736static const size_t PRFKlen[NB_PRF_TESTS] = {
737 18,
738 16,
739 10
740};
741
Janos Follathcd13bd22016-12-13 11:51:04 +0000742/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000743static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000744 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
745 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000746 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000747};
748
749static const unsigned char PRFT[NB_PRF_TESTS][16] = {
750 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000751 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
752 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000753 },
754 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000755 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
756 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000757 },
758 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000759 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
760 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000761 }
762};
Brian Murray0f6af732016-05-19 15:59:23 -0700763#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000764
Simon Butcher327398a2016-10-05 14:09:11 +0100765static int cmac_test_subkeys( int verbose,
766 const char* testname,
767 const unsigned char* key,
768 int keybits,
769 const unsigned char* subkeys,
770 mbedtls_cipher_type_t cipher_type,
771 int block_size,
772 int num_tests )
773{
Brian Murray2fab5c92016-12-15 18:51:13 -0800774 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100775 mbedtls_cipher_context_t ctx;
776 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100777 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
778 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100779
780 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
781 if( cipher_info == NULL )
782 {
783 /* Failing at this point must be due to a build issue */
Simon Butcher69283e52016-10-06 12:49:58 +0100784 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Simon Butcher327398a2016-10-05 14:09:11 +0100785 }
786
787 for( i = 0; i < num_tests; i++ )
788 {
789 if( verbose != 0 )
Simon Butcher69283e52016-10-06 12:49:58 +0100790 mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
Simon Butcher327398a2016-10-05 14:09:11 +0100791
Janos Follathd4443582016-10-12 10:00:42 +0100792 mbedtls_cipher_init( &ctx );
793
Simon Butcher327398a2016-10-05 14:09:11 +0100794 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
795 {
796 if( verbose != 0 )
797 mbedtls_printf( "test execution failed\n" );
798
Janos Follathd4443582016-10-12 10:00:42 +0100799 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100800 }
801
802 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
803 MBEDTLS_ENCRYPT ) ) != 0 )
804 {
805 if( verbose != 0 )
806 mbedtls_printf( "test execution failed\n" );
807
Janos Follathd4443582016-10-12 10:00:42 +0100808 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100809 }
810
811 ret = cmac_generate_subkeys( &ctx, K1, K2 );
812 if( ret != 0 )
813 {
814 if( verbose != 0 )
815 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100816
817 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100818 }
819
Simon Butcher420be4e2016-10-07 12:55:43 +0100820 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
821 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100822 {
823 if( verbose != 0 )
824 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100825
826 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100827 }
828
829 if( verbose != 0 )
830 mbedtls_printf( "passed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100831
832 mbedtls_cipher_free( &ctx );
Simon Butcher327398a2016-10-05 14:09:11 +0100833 }
834
Gilles Peskinedf761d52018-03-01 22:18:14 +0100835 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100836 goto exit;
837
838cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100839 mbedtls_cipher_free( &ctx );
840
Janos Follathd4443582016-10-12 10:00:42 +0100841exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100842 return( ret );
843}
844
Simon Butcher69283e52016-10-06 12:49:58 +0100845static int cmac_test_wth_cipher( int verbose,
846 const char* testname,
847 const unsigned char* key,
848 int keybits,
849 const unsigned char* messages,
850 const unsigned int message_lengths[4],
851 const unsigned char* expected_result,
852 mbedtls_cipher_type_t cipher_type,
853 int block_size,
854 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700855{
Simon Butcher327398a2016-10-05 14:09:11 +0100856 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800857 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100858 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700859
Simon Butcher327398a2016-10-05 14:09:11 +0100860 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
861 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700862 {
Simon Butcher327398a2016-10-05 14:09:11 +0100863 /* Failing at this point must be due to a build issue */
864 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700865 goto exit;
866 }
867
868 for( i = 0; i < num_tests; i++ )
869 {
870 if( verbose != 0 )
Andres AGa592dcc2016-10-06 15:23:39 +0100871 mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700872
Simon Butcher327398a2016-10-05 14:09:11 +0100873 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
874 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700875 {
876 if( verbose != 0 )
877 mbedtls_printf( "failed\n" );
878 goto exit;
879 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700880
Simon Butcher327398a2016-10-05 14:09:11 +0100881 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700882 {
883 if( verbose != 0 )
884 mbedtls_printf( "failed\n" );
885 goto exit;
886 }
887
Brian Murray9ce2e092016-05-24 22:46:43 -0700888 if( verbose != 0 )
889 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700890 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100891 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100892
Simon Butcher69283e52016-10-06 12:49:58 +0100893exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100894 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700895}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000896
Simon Butcher69283e52016-10-06 12:49:58 +0100897#if defined(MBEDTLS_AES_C)
898static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700899{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000900 int i;
901 int ret;
Simon Butcher69283e52016-10-06 12:49:58 +0100902 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100903
Brian Murrayb0c3c432016-05-18 14:29:51 -0700904 for( i = 0; i < NB_PRF_TESTS; i++ )
905 {
Brian Murray0f6af732016-05-19 15:59:23 -0700906 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100907 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700908 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100909 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700910 {
Simon Butcher327398a2016-10-05 14:09:11 +0100911
Brian Murrayb0c3c432016-05-18 14:29:51 -0700912 if( verbose != 0 )
913 mbedtls_printf( "failed\n" );
914
Brian Murray0f6af732016-05-19 15:59:23 -0700915 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100916 }
917 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700918 {
919 mbedtls_printf( "passed\n" );
920 }
921 }
Brian Murray0f6af732016-05-19 15:59:23 -0700922 return( ret );
923}
924#endif /* MBEDTLS_AES_C */
925
926int mbedtls_cmac_self_test( int verbose )
927{
928 int ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100929
Simon Butcher69283e52016-10-06 12:49:58 +0100930#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100931 /* AES-128 */
932 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100933 "AES 128",
934 aes_128_key,
935 128,
936 (const unsigned char*)aes_128_subkeys,
937 MBEDTLS_CIPHER_AES_128_ECB,
938 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100939 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100940 {
941 return( ret );
942 }
943
Brian Murrayae1cb122016-05-23 15:01:59 -0700944 if( ( ret = cmac_test_wth_cipher( verbose,
945 "AES 128",
946 aes_128_key,
947 128,
948 test_message,
949 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100950 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100951 MBEDTLS_CIPHER_AES_128_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100952 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100953 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100954 {
955 return( ret );
956 }
957
958 /* AES-192 */
959 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100960 "AES 192",
961 aes_192_key,
962 192,
963 (const unsigned char*)aes_192_subkeys,
964 MBEDTLS_CIPHER_AES_192_ECB,
965 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100966 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700967 {
968 return( ret );
969 }
Brian Murray0f6af732016-05-19 15:59:23 -0700970
Brian Murrayae1cb122016-05-23 15:01:59 -0700971 if( ( ret = cmac_test_wth_cipher( verbose,
972 "AES 192",
973 aes_192_key,
974 192,
975 test_message,
976 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100977 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100978 MBEDTLS_CIPHER_AES_192_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100979 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100980 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100981 {
Simon Butcher327398a2016-10-05 14:09:11 +0100982 return( ret );
983 }
984
985 /* AES-256 */
986 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100987 "AES 256",
988 aes_256_key,
989 256,
990 (const unsigned char*)aes_256_subkeys,
991 MBEDTLS_CIPHER_AES_256_ECB,
992 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100993 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700994 {
995 return( ret );
996 }
Brian Murray0f6af732016-05-19 15:59:23 -0700997
Simon Butcher69283e52016-10-06 12:49:58 +0100998 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -0700999 "AES 256",
1000 aes_256_key,
1001 256,
1002 test_message,
1003 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001004 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001005 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001006 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001007 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001008 {
1009 return( ret );
1010 }
Brian Murray0f6af732016-05-19 15:59:23 -07001011#endif /* MBEDTLS_AES_C */
1012
Simon Butcher69283e52016-10-06 12:49:58 +01001013#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001014 /* 3DES 2 key */
1015 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001016 "3DES 2 key",
1017 des3_2key_key,
1018 192,
1019 (const unsigned char*)des3_2key_subkeys,
1020 MBEDTLS_CIPHER_DES_EDE3_ECB,
1021 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001022 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001023 {
1024 return( ret );
1025 }
1026
Brian Murrayae1cb122016-05-23 15:01:59 -07001027 if( ( ret = cmac_test_wth_cipher( verbose,
1028 "3DES 2 key",
1029 des3_2key_key,
1030 192,
1031 test_message,
1032 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001033 (const unsigned char*)des3_2key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001034 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001035 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001036 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001037 {
1038 return( ret );
1039 }
Brian Murray0f6af732016-05-19 15:59:23 -07001040
Simon Butcher327398a2016-10-05 14:09:11 +01001041 /* 3DES 3 key */
1042 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001043 "3DES 3 key",
1044 des3_3key_key,
1045 192,
1046 (const unsigned char*)des3_3key_subkeys,
1047 MBEDTLS_CIPHER_DES_EDE3_ECB,
1048 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001049 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001050 {
1051 return( ret );
1052 }
1053
Brian Murrayae1cb122016-05-23 15:01:59 -07001054 if( ( ret = cmac_test_wth_cipher( verbose,
1055 "3DES 3 key",
1056 des3_3key_key,
1057 192,
1058 test_message,
1059 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001060 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001061 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001062 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001063 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001064 {
1065 return( ret );
1066 }
Brian Murray0f6af732016-05-19 15:59:23 -07001067#endif /* MBEDTLS_DES_C */
1068
Simon Butcher69283e52016-10-06 12:49:58 +01001069#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001070 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001071 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001072#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001073
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001074 if( verbose != 0 )
1075 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001076
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001077 return( 0 );
1078}
1079
Brian Murray0f6af732016-05-19 15:59:23 -07001080#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001081
1082#endif /* MBEDTLS_CMAC_C */