blob: 477e35f98780ee4a430628534275222d3dab2f7a [file] [log] [blame]
Robert Cragie9bf1e5d2015-12-15 07:38:11 +00001/*
2 * NIST SP800-38B compliant CMAC implementation
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
23 * Definition of CMAC:
24 * http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf
25 * RFC 4493 "The AES-CMAC Algorithm"
26 */
27
28#if !defined(MBEDTLS_CONFIG_FILE)
29#include "mbedtls/config.h"
30#else
31#include MBEDTLS_CONFIG_FILE
32#endif
33
34#if defined(MBEDTLS_CMAC_C)
35
36#include "mbedtls/cmac.h"
37
38#include <string.h>
39
40#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
41#if defined(MBEDTLS_PLATFORM_C)
42#include "mbedtls/platform.h"
43#else
44#include <stdio.h>
45#define mbedtls_printf printf
46#endif /* MBEDTLS_PLATFORM_C */
47#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
48
Robert Cragie9bf1e5d2015-12-15 07:38:11 +000049/* Implementation that should never be optimized out by the compiler */
50static void mbedtls_zeroize( void *v, size_t n ) {
51 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
52}
53
54/*
55 * Initialize context
56 */
57void mbedtls_cmac_init( mbedtls_cmac_context *ctx )
58{
59 memset( ctx, 0, sizeof( mbedtls_cmac_context ) );
60}
61
Brian Murray3c0412a2016-05-19 14:23:50 -070062
Robert Cragie9bf1e5d2015-12-15 07:38:11 +000063/*
Brian Murray7c6476c2016-05-18 14:29:51 -070064 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnard756bcf72016-01-13 11:28:16 +000065 *
Brian Murray7c6476c2016-05-18 14:29:51 -070066 * As explained in the paper, this can computed:
Manuel Pégourié-Gonnard756bcf72016-01-13 11:28:16 +000067 * If MSB(p) = 0, then p = (p << 1)
Brian Murray7c6476c2016-05-18 14:29:51 -070068 * If MSB(p) = 1, then p = (p << 1) ^ R_n
69 * with R_64 = 0x1B and R_128 = 0x87
Manuel Pégourié-Gonnard756bcf72016-01-13 11:28:16 +000070 *
71 * Input and output MUST not point to the same buffer
Brian Murray7c6476c2016-05-18 14:29:51 -070072 * Block size must be 8 byes or 16 bytes.
Robert Cragie9bf1e5d2015-12-15 07:38:11 +000073 */
Brian Murray7c6476c2016-05-18 14:29:51 -070074static int cmac_multiply_by_u( unsigned char *output,
75 const unsigned char *input,
Brian Murrayafdb60f2016-05-19 16:02:42 -070076 size_t blocksize )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +000077{
Robert Cragie9bf1e5d2015-12-15 07:38:11 +000078
Brian Murray7c6476c2016-05-18 14:29:51 -070079 const unsigned char R_128 = 0x87;
80 const unsigned char R_64 = 0x1B;
81 unsigned char R_n, mask;
82 unsigned char overflow = 0x00;
83 int i, starting_index;
84
85 starting_index = blocksize -1;
86
Brian Murrayafdb60f2016-05-19 16:02:42 -070087 if( blocksize == 16 ){
Brian Murray7c6476c2016-05-18 14:29:51 -070088 R_n = R_128;
Brian Murrayafdb60f2016-05-19 16:02:42 -070089 } else if( blocksize == 8 ) {
Brian Murray7c6476c2016-05-18 14:29:51 -070090 R_n = R_64;
91 } else {
Brian Murrayafdb60f2016-05-19 16:02:42 -070092 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
Brian Murray7c6476c2016-05-18 14:29:51 -070093 }
94
95
96 for( i = starting_index; i >= 0; i-- )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +000097 {
Manuel Pégourié-Gonnard756bcf72016-01-13 11:28:16 +000098 output[i] = input[i] << 1 | overflow;
99 overflow = input[i] >> 7;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000100 }
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000101
Manuel Pégourié-Gonnard89b8d832016-01-13 13:05:03 +0000102 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
103 * using bit operations to avoid branches */
104 /* MSVC has a warning about unary minus on unsigned, but this is
105 * well-defined and precisely what we want to do here */
106#if defined(_MSC_VER)
107#pragma warning( push )
108#pragma warning( disable : 4146 )
109#endif
110 mask = - ( input[0] >> 7 );
111#if defined(_MSC_VER)
112#pragma warning( pop )
113#endif
114
Brian Murray7c6476c2016-05-18 14:29:51 -0700115 output[starting_index] ^= R_n & mask;
Brian Murrayafdb60f2016-05-19 16:02:42 -0700116 return( 0 );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000117}
118
119/*
120 * Generate subkeys
121 */
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000122static int cmac_generate_subkeys( mbedtls_cmac_context *ctx )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000123{
Brian Murray7c6476c2016-05-18 14:29:51 -0700124 int ret, keybytes;
125 unsigned char *L;
126 size_t olen, block_size;
127
128 ret = 0;
129 block_size = ctx->cipher_ctx.cipher_info->block_size;
130
Brian Murrayafdb60f2016-05-19 16:02:42 -0700131 L = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000132
133 /* Calculate Ek(0) */
Brian Murray7c6476c2016-05-18 14:29:51 -0700134 memset( L, 0, block_size );
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000135 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx,
Brian Murray7c6476c2016-05-18 14:29:51 -0700136 L, block_size, L, &olen ) ) != 0 )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000137 {
Brian Murray7c6476c2016-05-18 14:29:51 -0700138 goto exit;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000139 }
140
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000141 /*
Manuel Pégourié-Gonnard756bcf72016-01-13 11:28:16 +0000142 * Generate K1 and K2
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000143 */
Brian Murrayafdb60f2016-05-19 16:02:42 -0700144 if( ( ret = cmac_multiply_by_u( ctx->K1, L , block_size ) ) != 0 )
Brian Murray7c6476c2016-05-18 14:29:51 -0700145 goto exit;
Brian Murrayafdb60f2016-05-19 16:02:42 -0700146 if( ( cmac_multiply_by_u( ctx->K2, ctx->K1 , block_size ) ) != 0 )
Brian Murray7c6476c2016-05-18 14:29:51 -0700147 goto exit;
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000148
Brian Murray7c6476c2016-05-18 14:29:51 -0700149 exit:
150 mbedtls_zeroize( L, sizeof( L ) );
Brian Murrayafdb60f2016-05-19 16:02:42 -0700151 free( L );
152 return( ret );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000153}
154
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000155/*
156 * Set key and prepare context for use
157 */
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000158int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx,
159 mbedtls_cipher_id_t cipher,
160 const unsigned char *key,
161 unsigned int keybits )
162{
Brian Murray7c6476c2016-05-18 14:29:51 -0700163 int ret, blocksize;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000164 const mbedtls_cipher_info_t *cipher_info;
165
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000166 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
167 MBEDTLS_MODE_ECB );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000168 if( cipher_info == NULL )
169 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
170
Brian Murray7c6476c2016-05-18 14:29:51 -0700171 ctx->K1 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) );
172 ctx->K2 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000173
174 mbedtls_cipher_free( &ctx->cipher_ctx );
175
176 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
177 return( ret );
178
179 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000180 MBEDTLS_ENCRYPT ) ) != 0 )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000181 {
182 return( ret );
183 }
184
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000185 return( cmac_generate_subkeys( ctx ) );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000186}
187
188/*
189 * Free context
190 */
191void mbedtls_cmac_free( mbedtls_cmac_context *ctx )
192{
Brian Murray7c6476c2016-05-18 14:29:51 -0700193 int block_size;
194 block_size = ctx->cipher_ctx.cipher_info->block_size;
195
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000196 mbedtls_cipher_free( &ctx->cipher_ctx );
Brian Murray7c6476c2016-05-18 14:29:51 -0700197
Brian Murrayafdb60f2016-05-19 16:02:42 -0700198 mbedtls_zeroize( ctx->K1, block_size * sizeof( unsigned char ) );
199 mbedtls_zeroize( ctx->K2, block_size * sizeof( unsigned char ) );
Brian Murray7c6476c2016-05-18 14:29:51 -0700200 mbedtls_free( ctx->K1 );
201 mbedtls_free( ctx->K2 );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000202}
203
Manuel Pégourié-Gonnardda8724f2016-01-13 13:14:04 +0000204/*
205 * Create padded last block from (partial) last block.
206 *
207 * We can't use the padding option from the cipher layer, as it only works for
208 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
209 */
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000210static void cmac_pad( unsigned char padded_block[16],
Brian Murray7c6476c2016-05-18 14:29:51 -0700211 size_t padded_block_len,
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000212 const unsigned char *last_block,
Brian Murray7c6476c2016-05-18 14:29:51 -0700213 size_t last_block_len )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000214{
215 size_t j;
216
Brian Murray7c6476c2016-05-18 14:29:51 -0700217 for( j = 0; j < padded_block_len; j++ )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000218 {
Brian Murray7c6476c2016-05-18 14:29:51 -0700219 if( j < last_block_len )
Manuel Pégourié-Gonnardda8724f2016-01-13 13:14:04 +0000220 padded_block[j] = last_block[j];
Brian Murray7c6476c2016-05-18 14:29:51 -0700221 else if( j == last_block_len )
Manuel Pégourié-Gonnardda8724f2016-01-13 13:14:04 +0000222 padded_block[j] = 0x80;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000223 else
Manuel Pégourié-Gonnardda8724f2016-01-13 13:14:04 +0000224 padded_block[j] = 0x00;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000225 }
226}
227
228/*
Brian Murray7c6476c2016-05-18 14:29:51 -0700229 * XOR Block
Manuel Pégourié-Gonnard5f8639f2016-01-13 15:03:05 +0000230 * Here, macro results in smaller compiled code than static inline function
231 */
Brian Murray7c6476c2016-05-18 14:29:51 -0700232#define XOR_BLOCK( o, i1, i2 ) \
233 for( i = 0; i < block_size; i++ ) \
Manuel Pégourié-Gonnard5f8639f2016-01-13 15:03:05 +0000234 ( o )[i] = ( i1 )[i] ^ ( i2 )[i];
235
236/*
237 * Update the CMAC state using an input block x
238 */
239#define UPDATE_CMAC( x ) \
240do { \
Brian Murray7c6476c2016-05-18 14:29:51 -0700241 XOR_BLOCK( state, ( x ), state ); \
Manuel Pégourié-Gonnard5f8639f2016-01-13 15:03:05 +0000242 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, \
Brian Murray7c6476c2016-05-18 14:29:51 -0700243 state, block_size, \
244 state, &olen ) ) != 0 ) \
Manuel Pégourié-Gonnard5f8639f2016-01-13 15:03:05 +0000245 return( ret ); \
246} while( 0 )
247
248/*
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000249 * Generate tag on complete message
250 */
Manuel Pégourié-Gonnarda878d3b2016-01-13 15:05:57 +0000251int mbedtls_cmac_generate( mbedtls_cmac_context *ctx,
252 const unsigned char *input, size_t in_len,
253 unsigned char *tag, size_t tag_len )
254
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000255{
Brian Murray7c6476c2016-05-18 14:29:51 -0700256
257 unsigned char *state;
258 unsigned char *M_last;
Manuel Pégourié-Gonnard59ae4ba2016-01-13 14:27:55 +0000259 int n, i, j, ret, needs_padding;
Brian Murray7c6476c2016-05-18 14:29:51 -0700260 size_t olen, block_size;
261
262
263 ret = 0;
264 block_size = ctx->cipher_ctx.cipher_info->block_size;
265
Brian Murrayafdb60f2016-05-19 16:02:42 -0700266 state = mbedtls_calloc( block_size, sizeof( unsigned char ) );
267 M_last = mbedtls_calloc( block_size, sizeof( unsigned char ) );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000268
269 /*
Manuel Pégourié-Gonnard9c83eeb2016-01-13 10:48:02 +0000270 * Check in_len requirements: SP800-38B A
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000271 * 4 is a worst case bottom limit
272 */
Brian Murray7c6476c2016-05-18 14:29:51 -0700273 if( tag_len < 4 || tag_len > block_size || tag_len % 2 != 0 )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000274 return( MBEDTLS_ERR_CMAC_BAD_INPUT );
275
Manuel Pégourié-Gonnard59ae4ba2016-01-13 14:27:55 +0000276 if( in_len == 0 )
277 needs_padding = 1;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000278 else
Brian Murray7c6476c2016-05-18 14:29:51 -0700279 needs_padding = in_len % block_size != 0;
Manuel Pégourié-Gonnard59ae4ba2016-01-13 14:27:55 +0000280
Brian Murray7c6476c2016-05-18 14:29:51 -0700281 n = in_len / block_size + needs_padding;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000282
283 /* Calculate last block */
Manuel Pégourié-Gonnard59ae4ba2016-01-13 14:27:55 +0000284 if( needs_padding )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000285 {
Brian Murray7c6476c2016-05-18 14:29:51 -0700286 cmac_pad( M_last, block_size, input + block_size * ( n - 1 ), in_len % block_size );
287 XOR_BLOCK( M_last, M_last, ctx->K2 );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000288 }
289 else
290 {
Manuel Pégourié-Gonnard59ae4ba2016-01-13 14:27:55 +0000291 /* Last block is complete block */
Brian Murray7c6476c2016-05-18 14:29:51 -0700292 XOR_BLOCK( M_last, input + block_size * ( n - 1 ), ctx->K1 );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000293 }
294
Brian Murray7c6476c2016-05-18 14:29:51 -0700295 memset( state, 0, block_size );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000296
297 for( j = 0; j < n - 1; j++ )
Brian Murray7c6476c2016-05-18 14:29:51 -0700298 UPDATE_CMAC( input + block_size * j );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000299
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000300 UPDATE_CMAC( M_last );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000301
Brian Murray3c0412a2016-05-19 14:23:50 -0700302 memcpy( tag, state, tag_len );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000303
Brian Murray7c6476c2016-05-18 14:29:51 -0700304 exit:
Brian Murrayafdb60f2016-05-19 16:02:42 -0700305 free( state );
306 free( M_last );
Brian Murray7c6476c2016-05-18 14:29:51 -0700307 return( ret );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000308}
309
Brian Murray7c6476c2016-05-18 14:29:51 -0700310#undef XOR_BLOCK
Manuel Pégourié-Gonnard5f8639f2016-01-13 15:03:05 +0000311#undef UPDATE_CMAC
312
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000313/*
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000314 * Verify tag on complete message
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000315 */
Manuel Pégourié-Gonnard9c83eeb2016-01-13 10:48:02 +0000316int mbedtls_cmac_verify( mbedtls_cmac_context *ctx,
317 const unsigned char *input, size_t in_len,
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000318 const unsigned char *tag, size_t tag_len )
319{
320 int ret;
Brian Murray7c6476c2016-05-18 14:29:51 -0700321 unsigned char *check_tag;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000322 unsigned char i;
323 int diff;
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000324
Brian Murrayafdb60f2016-05-19 16:02:42 -0700325 check_tag = mbedtls_calloc( ctx->cipher_ctx.cipher_info->block_size,
326 sizeof( unsigned char ) );
Brian Murray7c6476c2016-05-18 14:29:51 -0700327
Manuel Pégourié-Gonnarda878d3b2016-01-13 15:05:57 +0000328 if( ( ret = mbedtls_cmac_generate( ctx, input, in_len,
329 check_tag, tag_len ) ) != 0 )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000330 {
Brian Murray7c6476c2016-05-18 14:29:51 -0700331 goto exit;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000332 }
333
334 /* Check tag in "constant-time" */
335 for( diff = 0, i = 0; i < tag_len; i++ )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000336 diff |= tag[i] ^ check_tag[i];
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000337
338 if( diff != 0 )
Brian Murray7c6476c2016-05-18 14:29:51 -0700339 ret = MBEDTLS_ERR_CMAC_VERIFY_FAILED;
340 goto exit;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000341
Brian Murray7c6476c2016-05-18 14:29:51 -0700342 exit:
Brian Murrayafdb60f2016-05-19 16:02:42 -0700343 free( check_tag );
344 return( ret );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000345}
346
Brian Murrayafdb60f2016-05-19 16:02:42 -0700347#ifdef MBEDTLS_AES_C
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000348/*
349 * PRF based on CMAC with AES-128
Brian Murray7c6476c2016-05-18 14:29:51 -0700350 * See RFC 4615
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000351 */
Brian Murray7c6476c2016-05-18 14:29:51 -0700352int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard9c83eeb2016-01-13 10:48:02 +0000353 const unsigned char *input, size_t in_len,
Brian Murrayafdb60f2016-05-19 16:02:42 -0700354 unsigned char tag[16] )
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000355{
356 int ret;
Brian Murray7c6476c2016-05-18 14:29:51 -0700357 mbedtls_cmac_context ctx;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000358 unsigned char zero_key[16];
359 unsigned char int_key[16];
360
Brian Murrayafdb60f2016-05-19 16:02:42 -0700361 mbedtls_cmac_init(&ctx );
Brian Murray7c6476c2016-05-18 14:29:51 -0700362
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000363 if( key_length == 16 )
364 {
365 /* Use key as is */
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000366 memcpy( int_key, key, 16 );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000367 }
368 else
369 {
370 mbedtls_cmac_context zero_ctx;
371
Brian Murrayafdb60f2016-05-19 16:02:42 -0700372 /* Key is AES_CMAC( 0, key ) */
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000373 mbedtls_cmac_init( &zero_ctx );
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000374 memset( zero_key, 0, 16 );
375 ret = mbedtls_cmac_setkey( &zero_ctx, MBEDTLS_CIPHER_ID_AES,
376 zero_key, 8 * sizeof zero_key );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000377 if( ret != 0 )
Brian Murray7c6476c2016-05-18 14:29:51 -0700378 goto exit;
Manuel Pégourié-Gonnard2b0e21f2016-01-13 15:09:09 +0000379
Manuel Pégourié-Gonnard9c83eeb2016-01-13 10:48:02 +0000380 ret = mbedtls_cmac_generate( &zero_ctx, key, key_length, int_key, 16 );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000381 if( ret != 0 )
Brian Murray7c6476c2016-05-18 14:29:51 -0700382 goto exit;
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000383 }
384
Brian Murray7c6476c2016-05-18 14:29:51 -0700385 ret = mbedtls_cmac_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000386 int_key, 8 * sizeof int_key );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000387 if( ret != 0 )
Brian Murray7c6476c2016-05-18 14:29:51 -0700388 goto exit;
Manuel Pégourié-Gonnard28ea7912016-01-13 11:30:00 +0000389
390 mbedtls_zeroize( int_key, sizeof( int_key ) );
391
Brian Murray7c6476c2016-05-18 14:29:51 -0700392 ret = mbedtls_cmac_generate( &ctx, input, in_len, tag, 16 );
393
394 exit:
Brian Murrayafdb60f2016-05-19 16:02:42 -0700395 mbedtls_cmac_free( &ctx );
Brian Murray7c6476c2016-05-18 14:29:51 -0700396 return( ret );
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000397}
Brian Murrayafdb60f2016-05-19 16:02:42 -0700398#endif /* MBEDTLS_AES_C */
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000399
Brian Murrayd666eb52016-05-19 15:59:23 -0700400#ifdef MBEDTLS_SELF_TEST
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000401/*
Brian Murrayd666eb52016-05-19 15:59:23 -0700402 * CMAC test data from SP800-38B Appendix D.1 (corrected)
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000403 * http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
Brian Murrayd666eb52016-05-19 15:59:23 -0700404 *
405 * AES-CMAC-PRF-128 test data from RFC 4615
406 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000407 */
408
Brian Murrayd666eb52016-05-19 15:59:23 -0700409#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000410#define NB_PRF_TESTS 3
Brian Murrayd666eb52016-05-19 15:59:23 -0700411#define AES_BLOCK_SIZE 16
412#define DES3_BLOCK_SIZE 8
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000413
Brian Murrayd666eb52016-05-19 15:59:23 -0700414#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
415/* All CMAC test inputs are truncated from the same 64 byte buffer. */
416static const unsigned char test_message[] = {
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000417 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
418 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
419 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
420 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
421 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
422 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
423 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
424 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
425};
Brian Murrayd666eb52016-05-19 15:59:23 -0700426#endif /* defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) */
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000427
Brian Murrayd666eb52016-05-19 15:59:23 -0700428#ifdef MBEDTLS_AES_C
429/* Truncation point of message for AES CMAC tests */
430static const size_t aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
431 0,
432 16,
433 40,
434 64
435};
436
437/* AES 128 CMAC Test Data */
438static const unsigned char aes_128_key[] = {
439 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
440 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
441};
442static const unsigned char aes_128_subkeys[2][AES_BLOCK_SIZE] = {
443 {
444 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
445 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
446 },
447 {
448 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
449 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
450 }
451};
452static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000453 {
454 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
455 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
456 },
457 {
458 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
459 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
460 },
461 {
462 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
463 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
464 },
465 {
466 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
467 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
468 }
469};
470
Brian Murrayd666eb52016-05-19 15:59:23 -0700471/* AES 192 CMAC Test Data */
472static const unsigned char aes_192_key[] = {
473 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
474 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
475 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000476};
Brian Murrayd666eb52016-05-19 15:59:23 -0700477static const unsigned char aes_192_subkeys[2][AES_BLOCK_SIZE] = {
Brian Murray7c6476c2016-05-18 14:29:51 -0700478 {
Brian Murrayd666eb52016-05-19 15:59:23 -0700479 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
480 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murray7c6476c2016-05-18 14:29:51 -0700481 },
482 {
Brian Murrayd666eb52016-05-19 15:59:23 -0700483 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
484 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murray7c6476c2016-05-18 14:29:51 -0700485 }
486};
Brian Murrayd666eb52016-05-19 15:59:23 -0700487static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
Brian Murray7c6476c2016-05-18 14:29:51 -0700488 {
489 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
490 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
491 },
492 {
493 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
494 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
495 },
496 {
497 0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad,
498 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e
499 },
500 {
501 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
502 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
503 }
504};
505
Brian Murrayd666eb52016-05-19 15:59:23 -0700506/* AES 256 CMAC Test Data */
507static const unsigned char aes_256_key[] = {
508 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
509 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
510 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
511 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
512};
513static const unsigned char aes_256_subkeys[2][AES_BLOCK_SIZE] = {
514 {
515 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
516 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
517 },
518 {
519 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
520 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
521 }
522};
523static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BLOCK_SIZE] = {
524 {
525 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
526 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
527 },
528 {
529 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
530 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
531 },
532 {
533 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
534 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6
535 },
536 {
537 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
538 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
539 }
540};
541#endif /* MBEDTLS_AES_C */
542
543#ifdef MBEDTLS_DES_C
544/* Truncation point of message for 3DES CMAC tests */
545static const size_t des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
546 0,
547 8,
548 20,
549 32
550};
551
552/* 3DES 2 Key CMAC Test Data */
553static const unsigned char des3_2key_key[] = {
554 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5,
555 0x8a, 0x3d, 0x10, 0xba, 0x80, 0x57, 0x0d, 0x38,
556 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5
557};
558static const unsigned char des3_2key_subkeys[2][8] = {
559 {
560 0x8e, 0xcf, 0x37, 0x3e, 0xd7, 0x1a, 0xfa, 0xef
561 },
562 {
563 0x1d, 0x9e, 0x6e, 0x7d, 0xae, 0x35, 0xf5, 0xc5
564 }
565};
566static const unsigned char T_3des_2key[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murray7c6476c2016-05-18 14:29:51 -0700567 {
568 0xbd, 0x2e, 0xbf, 0x9a, 0x3b, 0xa0, 0x03, 0x61
569 },
570 {
571 0x4f, 0xf2, 0xab, 0x81, 0x3c, 0x53, 0xce, 0x83
572 },
573 {
574 0x62, 0xdd, 0x1b, 0x47, 0x19, 0x02, 0xbd, 0x4e
575 },
576 {
577 0x31, 0xb1, 0xe4, 0x31, 0xda, 0xbc, 0x4e, 0xb8
578 }
579};
580
Brian Murrayd666eb52016-05-19 15:59:23 -0700581/* 3DES 3 Key CMAC Test Data */
582static const unsigned char des3_3key_key[] = {
583 0x8a, 0xa8, 0x3b, 0xf8, 0xcb, 0xda, 0x10, 0x62,
584 0x0b, 0xc1, 0xbf, 0x19, 0xfb, 0xb6, 0xcd, 0x58,
585 0xbc, 0x31, 0x3d, 0x4a, 0x37, 0x1c, 0xa8, 0xb5
586};
587static const unsigned char des3_3key_subkeys[2][8] = {
588 {
589 0x91, 0x98, 0xe9, 0xd3, 0x14, 0xe6, 0x53, 0x5f
590 },
591 {
592 0x23, 0x31, 0xd3, 0xa6, 0x29, 0xcc, 0xa6, 0xa5
593 }
594};
595static const unsigned char T_3des_3key[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = {
Brian Murray7c6476c2016-05-18 14:29:51 -0700596 {
597 0xb7, 0xa6, 0x88, 0xe1, 0x22, 0xff, 0xaf, 0x95
598 },
599 {
600 0x8e, 0x8f, 0x29, 0x31, 0x36, 0x28, 0x37, 0x97
601 },
602 {
603 0x74, 0x3d, 0xdb, 0xe0, 0xce, 0x2d, 0xc2, 0xed
604 },
605 {
606 0x33, 0xe6, 0xb1, 0x09, 0x24, 0x00, 0xea, 0xe5
607 }
608};
609
Brian Murrayd666eb52016-05-19 15:59:23 -0700610#endif /* MBEDTLS_DES_C */
Brian Murray7c6476c2016-05-18 14:29:51 -0700611
Brian Murrayd666eb52016-05-19 15:59:23 -0700612#ifdef MBEDTLS_AES_C
613/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000614static const unsigned char PRFK[] = {
615 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
616 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
617 0xed, 0xcb
618};
619
620/* Sizes in bytes */
621static const size_t PRFKlen[NB_PRF_TESTS] = {
622 18,
623 16,
624 10
625};
626
627/* PRF M */
628static const unsigned char PRFM[] = {
629 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
630 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnarda4dfa052016-01-13 11:00:47 +0000631 0x10, 0x11, 0x12, 0x13
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000632};
633
634static const unsigned char PRFT[NB_PRF_TESTS][16] = {
635 {
636 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
637 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
638 },
639 {
640 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
641 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
642 },
643 {
644 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
645 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
646 }
647};
Brian Murrayd666eb52016-05-19 15:59:23 -0700648#endif /* MBEDTLS_AES_C */
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000649
Brian Murrayafdb60f2016-05-19 16:02:42 -0700650int test_cmac_with_cipher( int verbose,
Brian Murray3c0412a2016-05-19 14:23:50 -0700651 const unsigned char* testname,
652 const unsigned char* key,
653 int keybits,
654 const unsigned char* messages,
655 size_t message_lengths[4],
656 const unsigned char* subkeys,
657 const unsigned char* expected_result,
658 mbedtls_cipher_id_t cipher_id,
Brian Murrayafdb60f2016-05-19 16:02:42 -0700659 int block_size )
Brian Murray3c0412a2016-05-19 14:23:50 -0700660{
661 const int num_tests = 4;
662 mbedtls_cmac_context ctx;
663 int i, ret;
664 unsigned char* tag;
665
666 tag = mbedtls_calloc( block_size, sizeof( unsigned char ) );
667 mbedtls_cmac_init( &ctx );
668
669 if( ( ret = mbedtls_cmac_setkey( &ctx, cipher_id, key, keybits ) ) != 0 )
670 {
671 if( verbose != 0 )
672 mbedtls_printf( " CMAC: setup failed\n" );
673 goto exit;
674 }
675
676 if( ( ret = memcmp( ctx.K1, subkeys, block_size ) != 0 ) ||
677 ( ret = memcmp( ctx.K2, &subkeys[block_size], block_size ) != 0 ) )
678 {
679 if( verbose != 0 )
680 mbedtls_printf( " CMAC: subkey generation failed\n" );
681 goto exit;
682 }
683
684 for( i = 0; i < num_tests; i++ )
685 {
686 if( verbose != 0 )
687 mbedtls_printf( " %s CMAC #%u: ", testname, i +1 );
688
689 if( ( ret = mbedtls_cmac_generate( &ctx, messages, message_lengths[i], tag, block_size ) ) != 0 )
690 {
691 if( verbose != 0 )
692 mbedtls_printf( "failed\n" );
693 goto exit;
694 }
695 if( ( ret = memcmp( tag, &expected_result[i * block_size], block_size ) ) != 0 )
696 {
697 if( verbose != 0 )
698 mbedtls_printf( "failed\n" );
699 goto exit;
700 }
701
702 if( ( ret = mbedtls_cmac_verify( &ctx, messages, message_lengths[i], &expected_result[i * block_size], block_size ) != 0 ) )
703 {
704 if( verbose != 0 )
705 mbedtls_printf( "failed\n" );
706 goto exit;
707 }
708 mbedtls_printf( "passed\n" );
709 }
710 exit:
711 free( tag );
712 mbedtls_cmac_free( &ctx );
713 return( ret );
714}
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000715
Brian Murrayd666eb52016-05-19 15:59:23 -0700716#ifdef MBEDTLS_AES_C
717int test_aes128_cmac_prf( verbose ) {
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000718 int i;
719 int ret;
Brian Murrayd666eb52016-05-19 15:59:23 -0700720 unsigned char tag[16];
Brian Murray7c6476c2016-05-18 14:29:51 -0700721 for( i = 0; i < NB_PRF_TESTS; i++ )
722 {
Brian Murrayd666eb52016-05-19 15:59:23 -0700723 mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
724 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, tag );
Brian Murray7c6476c2016-05-18 14:29:51 -0700725 if( ret != 0 ||
726 memcmp( tag, PRFT[i], 16 ) != 0 )
727 {
728 if( verbose != 0 )
729 mbedtls_printf( "failed\n" );
730
Brian Murrayd666eb52016-05-19 15:59:23 -0700731 return( ret );
Brian Murray7c6476c2016-05-18 14:29:51 -0700732 } else if( verbose != 0 )
733 {
734 mbedtls_printf( "passed\n" );
735 }
736 }
Brian Murrayd666eb52016-05-19 15:59:23 -0700737 return( ret );
738}
739#endif /* MBEDTLS_AES_C */
740
741int mbedtls_cmac_self_test( int verbose )
742{
743 int ret;
744
745#ifdef MBEDTLS_AES_C
Brian Murray3d3c9b82016-05-19 16:36:56 -0700746 if( ( ret = test_cmac_with_cipher( verbose,
747 "AES 128",
748 aes_128_key,
749 128,
750 test_message,
751 aes_message_lengths,
752 aes_128_subkeys,
753 aes_128_expected_result,
754 MBEDTLS_CIPHER_ID_AES,
755 AES_BLOCK_SIZE ) !=0 ) )
756 {
757 return( ret );
758 }
Brian Murrayd666eb52016-05-19 15:59:23 -0700759
Brian Murray3d3c9b82016-05-19 16:36:56 -0700760 if( ( ret = test_cmac_with_cipher( verbose,
761 "AES 192",
762 aes_192_key,
763 192,
764 test_message,
765 aes_message_lengths,
766 aes_192_subkeys,
767 aes_192_expected_result,
768 MBEDTLS_CIPHER_ID_AES,
769 AES_BLOCK_SIZE ) !=0 ) )
770 {
771 return( ret );
772 }
Brian Murrayd666eb52016-05-19 15:59:23 -0700773
Brian Murray3d3c9b82016-05-19 16:36:56 -0700774 if( ( ret = test_cmac_with_cipher ( verbose,
775 "AES 256",
776 aes_256_key,
777 256,
778 test_message,
779 aes_message_lengths,
780 aes_256_subkeys,
781 aes_256_expected_result,
782 MBEDTLS_CIPHER_ID_AES,
783 AES_BLOCK_SIZE ) !=0 ) )
784 {
785 return( ret );
786 }
Brian Murrayd666eb52016-05-19 15:59:23 -0700787#endif /* MBEDTLS_AES_C */
788
789#ifdef MBEDTLS_DES_C
Brian Murray3d3c9b82016-05-19 16:36:56 -0700790 if( ( ret = test_cmac_with_cipher( verbose,
791 "3DES 2 key",
792 des3_2key_key,
793 192,
794 test_message,
795 des3_message_lengths,
796 des3_2key_subkeys,
797 T_3des_2key,
798 MBEDTLS_CIPHER_ID_3DES,
799 DES3_BLOCK_SIZE ) !=0 ) )
800 {
801 return( ret );
802 }
Brian Murrayd666eb52016-05-19 15:59:23 -0700803
Brian Murray3d3c9b82016-05-19 16:36:56 -0700804 if( ( ret = test_cmac_with_cipher( verbose,
805 "3DES 3 key",
806 des3_3key_key,
807 192,
808 test_message,
809 des3_message_lengths,
810 des3_3key_subkeys,
811 T_3des_3key,
812 MBEDTLS_CIPHER_ID_3DES,
813 DES3_BLOCK_SIZE ) !=0 ) )
814 {
815 return( ret );
816 }
Brian Murrayd666eb52016-05-19 15:59:23 -0700817#endif /* MBEDTLS_DES_C */
818
819#ifdef MBEDTLS_AES_C
Brian Murray3d3c9b82016-05-19 16:36:56 -0700820 if( ( ret = test_aes128_cmac_prf( verbose ) != 0 ) )
821 return( ret );
822
Brian Murrayd666eb52016-05-19 15:59:23 -0700823#endif /* MBEDTLS_AES_C */
Brian Murray7c6476c2016-05-18 14:29:51 -0700824
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000825 if( verbose != 0 )
826 mbedtls_printf( "\n" );
Brian Murrayd666eb52016-05-19 15:59:23 -0700827
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000828 return( 0 );
829}
830
Brian Murrayd666eb52016-05-19 15:59:23 -0700831#endif /* MBEDTLS_SELF_TEST */
Robert Cragie9bf1e5d2015-12-15 07:38:11 +0000832
833#endif /* MBEDTLS_CMAC_C */