blob: 3cc49d10cc22c1c5b7e11741cdf2558fe5e9d01b [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 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02006 * Copyright The Mbed TLS Contributors
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.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000020 */
21
22/*
Brian Murray53e23b62016-09-13 14:00:15 -070023 * References:
Simon Butcher327398a2016-10-05 14:09:11 +010024 *
25 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
26 * CMAC Mode for Authentication
Janos Follathcd13bd22016-12-13 11:51:04 +000027 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
Simon Butcher327398a2016-10-05 14:09:11 +010028 *
29 * - RFC 4493 - The AES-CMAC Algorithm
30 * https://tools.ietf.org/html/rfc4493
31 *
32 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
33 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
34 * Algorithm for the Internet Key Exchange Protocol (IKE)
35 * https://tools.ietf.org/html/rfc4615
36 *
37 * Additional test vectors: ISO/IEC 9797-1
38 *
Robert Cragie3d23b1d2015-12-15 07:38:11 +000039 */
40
Gilles Peskinedb09ef62020-06-03 01:43:33 +020041#include "common.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000042
43#if defined(MBEDTLS_CMAC_C)
44
45#include "mbedtls/cmac.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050046#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000047#include "mbedtls/error.h"
Steven Cooreman655b0122021-01-11 14:34:51 +010048#include "mbedtls/platform.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000049
50#include <string.h>
51
Ron Eldor621080d2017-12-21 10:57:43 +020052#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020053
Robert Cragie3d23b1d2015-12-15 07:38:11 +000054/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070055 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000056 *
Brian Murray72b69e32016-09-13 14:21:01 -070057 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000058 *
Simon Butcher327398a2016-10-05 14:09:11 +010059 * If MSB(p) = 0, then p = (p << 1)
60 * If MSB(p) = 1, then p = (p << 1) ^ R_n
61 * with R_64 = 0x1B and R_128 = 0x87
62 *
63 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -080064 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000065 */
Brian Murrayb0c3c432016-05-18 14:29:51 -070066static int cmac_multiply_by_u( unsigned char *output,
67 const unsigned char *input,
Brian Murray53e23b62016-09-13 14:00:15 -070068 size_t blocksize )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000069{
Brian Murrayb0c3c432016-05-18 14:29:51 -070070 const unsigned char R_128 = 0x87;
71 const unsigned char R_64 = 0x1B;
72 unsigned char R_n, mask;
73 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010074 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070075
Simon Butcher69283e52016-10-06 12:49:58 +010076 if( blocksize == MBEDTLS_AES_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -070077 {
Brian Murrayb0c3c432016-05-18 14:29:51 -070078 R_n = R_128;
Simon Butcher327398a2016-10-05 14:09:11 +010079 }
Simon Butcher69283e52016-10-06 12:49:58 +010080 else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE )
Brian Murray6a3c0d22016-05-20 18:25:43 -070081 {
Brian Murrayb0c3c432016-05-18 14:29:51 -070082 R_n = R_64;
Simon Butcher327398a2016-10-05 14:09:11 +010083 }
84 else
Brian Murray6a3c0d22016-05-20 18:25:43 -070085 {
Simon Butcher327398a2016-10-05 14:09:11 +010086 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -070087 }
88
Simon B3249cb72016-11-03 01:11:37 +000089 for( i = (int)blocksize - 1; i >= 0; i-- )
Robert Cragie3d23b1d2015-12-15 07:38:11 +000090 {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000091 output[i] = input[i] << 1 | overflow;
92 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000093 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000094
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000095 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
96 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +010097
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000098 /* MSVC has a warning about unary minus on unsigned, but this is
99 * well-defined and precisely what we want to do here */
100#if defined(_MSC_VER)
101#pragma warning( push )
102#pragma warning( disable : 4146 )
103#endif
104 mask = - ( input[0] >> 7 );
105#if defined(_MSC_VER)
106#pragma warning( pop )
107#endif
108
Simon Butcher327398a2016-10-05 14:09:11 +0100109 output[ blocksize - 1 ] ^= R_n & mask;
110
Brian Murrayb439d452016-05-19 16:02:42 -0700111 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000112}
113
114/*
115 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +0100116 *
117 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000118 */
Simon Butcher327398a2016-10-05 14:09:11 +0100119static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
120 unsigned char* K1, unsigned char* K2 )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000121{
Janos Follath24eed8d2019-11-22 13:21:35 +0000122 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100123 unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700124 size_t olen, block_size;
125
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500126 mbedtls_platform_zeroize( L, sizeof( L ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700127
Simon Butcher327398a2016-10-05 14:09:11 +0100128 block_size = ctx->cipher_info->block_size;
129
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000130 /* Calculate Ek(0) */
Simon Butcher327398a2016-10-05 14:09:11 +0100131 if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700132 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000133
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000134 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000135 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000136 */
Simon Butcher327398a2016-10-05 14:09:11 +0100137 if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700138 goto exit;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000139
Simon Butcher327398a2016-10-05 14:09:11 +0100140 if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 )
141 goto exit;
142
143exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500144 mbedtls_platform_zeroize( L, sizeof( L ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100145
146 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000147}
Ron Eldor621080d2017-12-21 10:57:43 +0200148#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000149
Ron Eldor621080d2017-12-21 10:57:43 +0200150#if !defined(MBEDTLS_CMAC_ALT)
Simon Butcher69283e52016-10-06 12:49:58 +0100151static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
152 const unsigned char *input2,
153 const size_t block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000154{
Hanno Becker61937d42017-04-26 15:01:23 +0100155 size_t idx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000156
Hanno Becker61937d42017-04-26 15:01:23 +0100157 for( idx = 0; idx < block_size; idx++ )
158 output[ idx ] = input1[ idx ] ^ input2[ idx ];
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000159}
160
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000161/*
162 * Create padded last block from (partial) last block.
163 *
164 * We can't use the padding option from the cipher layer, as it only works for
165 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
166 */
Simon Butcher69283e52016-10-06 12:49:58 +0100167static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
Brian Murray53e23b62016-09-13 14:00:15 -0700168 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000169 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700170 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000171{
172 size_t j;
173
Brian Murrayb0c3c432016-05-18 14:29:51 -0700174 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000175 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700176 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000177 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700178 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000179 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000180 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000181 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000182 }
183}
184
Simon Butcher327398a2016-10-05 14:09:11 +0100185int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
Simon Butcher94ffde72016-10-05 15:33:53 +0100186 const unsigned char *key, size_t keybits )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000187{
Simon Butcher327398a2016-10-05 14:09:11 +0100188 mbedtls_cipher_type_t type;
189 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100190 int retval;
191
192 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
193 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
194
Simon B3249cb72016-11-03 01:11:37 +0000195 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
Simon Butcher327398a2016-10-05 14:09:11 +0100196 MBEDTLS_ENCRYPT ) ) != 0 )
197 return( retval );
198
Simon Butcher327398a2016-10-05 14:09:11 +0100199 type = ctx->cipher_info->type;
200
201 switch( type )
202 {
203 case MBEDTLS_CIPHER_AES_128_ECB:
204 case MBEDTLS_CIPHER_AES_192_ECB:
205 case MBEDTLS_CIPHER_AES_256_ECB:
206 case MBEDTLS_CIPHER_DES_EDE3_ECB:
207 break;
208 default:
209 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
210 }
211
212 /* Allocated and initialise in the cipher context memory for the CMAC
213 * context */
214 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
215 if( cmac_ctx == NULL )
216 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
217
218 ctx->cmac_ctx = cmac_ctx;
219
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500220 mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100221
222 return 0;
223}
224
225int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
226 const unsigned char *input, size_t ilen )
227{
228 mbedtls_cmac_context_t* cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700229 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000230 int ret = 0;
231 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700232
Simon Butcher327398a2016-10-05 14:09:11 +0100233 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
234 ctx->cmac_ctx == NULL )
235 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700236
Simon Butcher327398a2016-10-05 14:09:11 +0100237 cmac_ctx = ctx->cmac_ctx;
238 block_size = ctx->cipher_info->block_size;
239 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000240
Simon Butcher6b0774a2016-10-10 21:37:42 +0100241 /* Is there data still to process from the last call, that's greater in
242 * size than a block? */
Simon Butcher327398a2016-10-05 14:09:11 +0100243 if( cmac_ctx->unprocessed_len > 0 &&
Andres AGa592dcc2016-10-06 15:23:39 +0100244 ilen > block_size - cmac_ctx->unprocessed_len )
Brian Murray57863ad2016-05-19 16:38:36 -0700245 {
Simon Butcher327398a2016-10-05 14:09:11 +0100246 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
247 input,
248 block_size - cmac_ctx->unprocessed_len );
249
250 cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
251
252 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
253 &olen ) ) != 0 )
254 {
255 goto exit;
256 }
257
Simon Butcher6b0774a2016-10-10 21:37:42 +0100258 input += block_size - cmac_ctx->unprocessed_len;
259 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100260 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700261 }
262
Simon Butcher327398a2016-10-05 14:09:11 +0100263 /* n is the number of blocks including any final partial block */
264 n = ( ilen + block_size - 1 ) / block_size;
265
Simon B3249cb72016-11-03 01:11:37 +0000266 /* Iterate across the input data in block sized chunks, excluding any
267 * final partial or complete block */
268 for( j = 1; j < n; j++ )
Brian Murray57863ad2016-05-19 16:38:36 -0700269 {
Simon Butcher327398a2016-10-05 14:09:11 +0100270 cmac_xor_block( state, input, state, block_size );
271
272 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
273 &olen ) ) != 0 )
274 goto exit;
275
276 ilen -= block_size;
277 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700278 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000279
Simon Butcher327398a2016-10-05 14:09:11 +0100280 /* If there is data left over that wasn't aligned to a block */
281 if( ilen > 0 )
282 {
Simon Butcher6b0774a2016-10-10 21:37:42 +0100283 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
284 input,
285 ilen );
286 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100287 }
288
289exit:
290 return( ret );
291}
292
293int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
294 unsigned char *output )
295{
296 mbedtls_cmac_context_t* cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100297 unsigned char *state, *last_block;
298 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
299 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
300 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Janos Follath24eed8d2019-11-22 13:21:35 +0000301 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100302 size_t olen, block_size;
303
304 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
305 output == NULL )
306 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
307
308 cmac_ctx = ctx->cmac_ctx;
309 block_size = ctx->cipher_info->block_size;
310 state = cmac_ctx->state;
311
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500312 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
313 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100314 cmac_generate_subkeys( ctx, K1, K2 );
315
Simon Butcher69283e52016-10-06 12:49:58 +0100316 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000317
318 /* Calculate last block */
Janos Follathe3d882a2016-10-11 10:49:26 +0100319 if( cmac_ctx->unprocessed_len < block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000320 {
Simon Butcher327398a2016-10-05 14:09:11 +0100321 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
322 cmac_xor_block( M_last, M_last, K2, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000323 }
324 else
325 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000326 /* Last block is complete block */
Simon Butcher327398a2016-10-05 14:09:11 +0100327 cmac_xor_block( M_last, last_block, K1, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000328 }
329
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000330
Simon Butcher327398a2016-10-05 14:09:11 +0100331 cmac_xor_block( state, M_last, state, block_size );
332 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
333 &olen ) ) != 0 )
334 {
335 goto exit;
336 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000337
Simon Butcher327398a2016-10-05 14:09:11 +0100338 memcpy( output, state, block_size );
339
340exit:
341 /* Wipe the generated keys on the stack, and any other transients to avoid
342 * side channel leakage */
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500343 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
344 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100345
346 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500347 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
348 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100349
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500350 mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
Simon Butcher327398a2016-10-05 14:09:11 +0100351 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000352}
353
Simon Butcher327398a2016-10-05 14:09:11 +0100354int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000355{
Simon Butcher327398a2016-10-05 14:09:11 +0100356 mbedtls_cmac_context_t* cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000357
Simon Butcher327398a2016-10-05 14:09:11 +0100358 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
359 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700360
Simon Butcher327398a2016-10-05 14:09:11 +0100361 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000362
Simon Butcher327398a2016-10-05 14:09:11 +0100363 /* Reset the internal state */
364 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500365 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
366 sizeof( cmac_ctx->unprocessed_block ) );
367 mbedtls_platform_zeroize( cmac_ctx->state,
368 sizeof( cmac_ctx->state ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000369
Simon Butcher327398a2016-10-05 14:09:11 +0100370 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000371}
372
Simon Butcher327398a2016-10-05 14:09:11 +0100373int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
374 const unsigned char *key, size_t keylen,
375 const unsigned char *input, size_t ilen,
376 unsigned char *output )
377{
378 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000379 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100380
381 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
382 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
383
384 mbedtls_cipher_init( &ctx );
385
386 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
387 goto exit;
388
389 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
Simon Butcher327398a2016-10-05 14:09:11 +0100390 if( ret != 0 )
391 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100392
393 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
394 if( ret != 0 )
395 goto exit;
396
Simon Butcher69283e52016-10-06 12:49:58 +0100397 ret = mbedtls_cipher_cmac_finish( &ctx, output );
Simon Butcher327398a2016-10-05 14:09:11 +0100398
399exit:
Simon Butcher69283e52016-10-06 12:49:58 +0100400 mbedtls_cipher_free( &ctx );
401
Simon Butcher327398a2016-10-05 14:09:11 +0100402 return( ret );
403}
Simon Butcher327398a2016-10-05 14:09:11 +0100404
Simon Butcher69283e52016-10-06 12:49:58 +0100405#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000406/*
Simon Butcher69283e52016-10-06 12:49:58 +0100407 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000408 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700409int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000410 const unsigned char *input, size_t in_len,
Rodrigo Dias Correa2c424572020-11-10 01:38:00 -0300411 unsigned char output[16] )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000412{
Janos Follath24eed8d2019-11-22 13:21:35 +0000413 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100414 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100415 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
416 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
417
418 if( key == NULL || input == NULL || output == NULL )
419 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000420
Simon Butcher327398a2016-10-05 14:09:11 +0100421 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
422 if( cipher_info == NULL )
423 {
424 /* Failing at this point must be due to a build issue */
425 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
426 goto exit;
427 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700428
Simon Butcher69283e52016-10-06 12:49:58 +0100429 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000430 {
431 /* Use key as is */
Simon Butcher69283e52016-10-06 12:49:58 +0100432 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000433 }
434 else
435 {
Simon Butcher69283e52016-10-06 12:49:58 +0100436 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000437
Simon Butcher327398a2016-10-05 14:09:11 +0100438 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
439 key_length, int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000440 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700441 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000442 }
443
Simon Butcher327398a2016-10-05 14:09:11 +0100444 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
445 output );
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000446
Simon Butcher327398a2016-10-05 14:09:11 +0100447exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500448 mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700449
Simon Butcher327398a2016-10-05 14:09:11 +0100450 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000451}
Brian Murrayb439d452016-05-19 16:02:42 -0700452#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000453
Steven Cooreman63342772017-04-04 11:47:16 +0200454#endif /* !MBEDTLS_CMAC_ALT */
455
Simon Butcher69283e52016-10-06 12:49:58 +0100456#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000457/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000458 * CMAC test data for SP800-38B
459 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
460 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700461 *
462 * AES-CMAC-PRF-128 test data from RFC 4615
463 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000464 */
465
Brian Murray0f6af732016-05-19 15:59:23 -0700466#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000467#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100468
Brian Murray0f6af732016-05-19 15:59:23 -0700469#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
470/* All CMAC test inputs are truncated from the same 64 byte buffer. */
471static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000472 /* PT */
473 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
474 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
475 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
476 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
477 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
478 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
479 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
480 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000481};
Simon Butcher69283e52016-10-06 12:49:58 +0100482#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700483
Simon Butcher69283e52016-10-06 12:49:58 +0100484#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700485/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700486static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000487 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700488 0,
489 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000490 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700491 64
492};
493
Janos Follathcd13bd22016-12-13 11:51:04 +0000494/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700495static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000496 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
497 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700498};
Simon Butcher69283e52016-10-06 12:49:58 +0100499static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700500 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000501 /* K1 */
502 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
503 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700504 },
505 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000506 /* K2 */
507 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
508 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700509 }
510};
Simon Butcher69283e52016-10-06 12:49:58 +0100511static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000512 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000513 /* Example #1 */
514 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
515 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000516 },
517 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000518 /* Example #2 */
519 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
520 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000521 },
522 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000523 /* Example #3 */
524 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
525 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000526 },
527 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000528 /* Example #4 */
529 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
530 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000531 }
532};
533
Janos Follathcd13bd22016-12-13 11:51:04 +0000534/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700535static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000536 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
537 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
538 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000539};
Simon Butcher69283e52016-10-06 12:49:58 +0100540static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700541 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000542 /* K1 */
543 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
544 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700545 },
546 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000547 /* K2 */
548 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
549 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700550 }
551};
Simon Butcher69283e52016-10-06 12:49:58 +0100552static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700553 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000554 /* Example #1 */
555 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
556 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700557 },
558 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000559 /* Example #2 */
560 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
561 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700562 },
563 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000564 /* Example #3 */
565 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
566 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700567 },
568 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000569 /* Example #4 */
570 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
571 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700572 }
573};
574
Janos Follathcd13bd22016-12-13 11:51:04 +0000575/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700576static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000577 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
578 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
579 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
580 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700581};
Simon Butcher69283e52016-10-06 12:49:58 +0100582static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700583 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000584 /* K1 */
585 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
586 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700587 },
588 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000589 /* K2 */
590 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
591 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700592 }
593};
Simon Butcher69283e52016-10-06 12:49:58 +0100594static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700595 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000596 /* Example #1 */
597 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
598 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700599 },
600 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000601 /* Example #2 */
602 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
603 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700604 },
605 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000606 /* Example #3 */
607 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
608 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700609 },
610 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000611 /* Example #4 */
612 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
613 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700614 }
615};
616#endif /* MBEDTLS_AES_C */
617
Simon Butcher69283e52016-10-06 12:49:58 +0100618#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700619/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700620static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700621 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000622 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700623 20,
624 32
625};
626
Janos Follathcd13bd22016-12-13 11:51:04 +0000627/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700628static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000629 /* Key1 */
630 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
631 /* Key2 */
632 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
633 /* Key3 */
634 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700635};
636static const unsigned char des3_2key_subkeys[2][8] = {
637 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000638 /* K1 */
639 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700640 },
641 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000642 /* K2 */
643 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700644 }
645};
Simon Butcher69283e52016-10-06 12:49:58 +0100646static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700647 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000648 /* Sample #1 */
649 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700650 },
651 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000652 /* Sample #2 */
653 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700654 },
655 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000656 /* Sample #3 */
657 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700658 },
659 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000660 /* Sample #4 */
661 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700662 }
663};
664
Janos Follathcd13bd22016-12-13 11:51:04 +0000665/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700666static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000667 /* Key1 */
668 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
669 /* Key2 */
670 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
671 /* Key3 */
672 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700673};
674static const unsigned char des3_3key_subkeys[2][8] = {
675 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000676 /* K1 */
677 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700678 },
679 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000680 /* K2 */
681 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700682 }
683};
Simon Butcher69283e52016-10-06 12:49:58 +0100684static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700685 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000686 /* Sample #1 */
687 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700688 },
689 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000690 /* Sample #2 */
691 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700692 },
693 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000694 /* Sample #3 */
695 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700696 },
697 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000698 /* Sample #4 */
699 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700700 }
701};
702
Brian Murray0f6af732016-05-19 15:59:23 -0700703#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700704
Simon Butcher69283e52016-10-06 12:49:58 +0100705#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700706/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000707static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000708 /* Key */
709 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
710 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000711 0xed, 0xcb
712};
713
714/* Sizes in bytes */
715static const size_t PRFKlen[NB_PRF_TESTS] = {
716 18,
717 16,
718 10
719};
720
Janos Follathcd13bd22016-12-13 11:51:04 +0000721/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000722static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000723 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
724 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000725 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000726};
727
728static const unsigned char PRFT[NB_PRF_TESTS][16] = {
729 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000730 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
731 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000732 },
733 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000734 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
735 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000736 },
737 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000738 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
739 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000740 }
741};
Brian Murray0f6af732016-05-19 15:59:23 -0700742#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000743
Simon Butcher327398a2016-10-05 14:09:11 +0100744static int cmac_test_subkeys( int verbose,
745 const char* testname,
746 const unsigned char* key,
747 int keybits,
748 const unsigned char* subkeys,
749 mbedtls_cipher_type_t cipher_type,
750 int block_size,
751 int num_tests )
752{
Brian Murray2fab5c92016-12-15 18:51:13 -0800753 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100754 mbedtls_cipher_context_t ctx;
755 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100756 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
757 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100758
759 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
760 if( cipher_info == NULL )
761 {
762 /* Failing at this point must be due to a build issue */
Simon Butcher69283e52016-10-06 12:49:58 +0100763 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Simon Butcher327398a2016-10-05 14:09:11 +0100764 }
765
766 for( i = 0; i < num_tests; i++ )
767 {
768 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +0200769 mbedtls_printf( " %s CMAC subkey #%d: ", testname, i + 1 );
Simon Butcher327398a2016-10-05 14:09:11 +0100770
Janos Follathd4443582016-10-12 10:00:42 +0100771 mbedtls_cipher_init( &ctx );
772
Simon Butcher327398a2016-10-05 14:09:11 +0100773 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
774 {
775 if( verbose != 0 )
776 mbedtls_printf( "test execution failed\n" );
777
Janos Follathd4443582016-10-12 10:00:42 +0100778 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100779 }
780
781 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
782 MBEDTLS_ENCRYPT ) ) != 0 )
783 {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100784 /* When CMAC is implemented by an alternative implementation, or
785 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100786 * AES-192 may be unavailable. This should not cause the selftest
787 * function to fail. */
Steven Cooreman03f40842021-01-19 13:30:48 +0100788 if( ( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
789 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) &&
790 cipher_type == MBEDTLS_CIPHER_AES_192_ECB ) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100791 if( verbose != 0 )
792 mbedtls_printf( "skipped\n" );
793 goto next_test;
794 }
795
Simon Butcher327398a2016-10-05 14:09:11 +0100796 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 ret = cmac_generate_subkeys( &ctx, K1, K2 );
803 if( ret != 0 )
804 {
805 if( verbose != 0 )
806 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100807
808 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100809 }
810
Simon Butcher420be4e2016-10-07 12:55:43 +0100811 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
812 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100813 {
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
820 if( verbose != 0 )
821 mbedtls_printf( "passed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100822
Steven Cooreman830d5af2021-01-08 18:01:46 +0100823next_test:
Janos Follathd4443582016-10-12 10:00:42 +0100824 mbedtls_cipher_free( &ctx );
Simon Butcher327398a2016-10-05 14:09:11 +0100825 }
826
Gilles Peskinedf761d52018-03-01 22:18:14 +0100827 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100828 goto exit;
829
830cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100831 mbedtls_cipher_free( &ctx );
832
Janos Follathd4443582016-10-12 10:00:42 +0100833exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100834 return( ret );
835}
836
Simon Butcher69283e52016-10-06 12:49:58 +0100837static int cmac_test_wth_cipher( int verbose,
838 const char* testname,
839 const unsigned char* key,
840 int keybits,
841 const unsigned char* messages,
842 const unsigned int message_lengths[4],
843 const unsigned char* expected_result,
844 mbedtls_cipher_type_t cipher_type,
845 int block_size,
846 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700847{
Simon Butcher327398a2016-10-05 14:09:11 +0100848 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800849 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100850 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700851
Simon Butcher327398a2016-10-05 14:09:11 +0100852 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
853 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700854 {
Simon Butcher327398a2016-10-05 14:09:11 +0100855 /* Failing at this point must be due to a build issue */
856 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700857 goto exit;
858 }
859
860 for( i = 0; i < num_tests; i++ )
861 {
862 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +0200863 mbedtls_printf( " %s CMAC #%d: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700864
Simon Butcher327398a2016-10-05 14:09:11 +0100865 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
866 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700867 {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100868 /* When CMAC is implemented by an alternative implementation, or
869 * the underlying primitive itself is implemented alternatively,
Steven Cooreman146e7fc2021-02-15 13:42:35 +0100870 * AES-192 and/or 3DES may be unavailable. This should not cause
871 * the selftest function to fail. */
Steven Cooreman03f40842021-01-19 13:30:48 +0100872 if( ( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
873 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) &&
Steven Cooreman146e7fc2021-02-15 13:42:35 +0100874 ( cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
875 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB ) ) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100876 if( verbose != 0 )
877 mbedtls_printf( "skipped\n" );
878 continue;
879 }
880
Brian Murray00dc5f02016-05-19 14:23:50 -0700881 if( verbose != 0 )
882 mbedtls_printf( "failed\n" );
883 goto exit;
884 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700885
Simon Butcher327398a2016-10-05 14:09:11 +0100886 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700887 {
888 if( verbose != 0 )
889 mbedtls_printf( "failed\n" );
890 goto exit;
891 }
892
Brian Murray9ce2e092016-05-24 22:46:43 -0700893 if( verbose != 0 )
894 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700895 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100896 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100897
Simon Butcher69283e52016-10-06 12:49:58 +0100898exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100899 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700900}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000901
Simon Butcher69283e52016-10-06 12:49:58 +0100902#if defined(MBEDTLS_AES_C)
903static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700904{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000905 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000906 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100907 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100908
Brian Murrayb0c3c432016-05-18 14:29:51 -0700909 for( i = 0; i < NB_PRF_TESTS; i++ )
910 {
Kenneth Soerensen518d4352020-04-01 17:22:45 +0200911 mbedtls_printf( " AES CMAC 128 PRF #%d: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100912 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700913 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100914 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700915 {
Simon Butcher327398a2016-10-05 14:09:11 +0100916
Brian Murrayb0c3c432016-05-18 14:29:51 -0700917 if( verbose != 0 )
918 mbedtls_printf( "failed\n" );
919
Brian Murray0f6af732016-05-19 15:59:23 -0700920 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100921 }
922 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700923 {
924 mbedtls_printf( "passed\n" );
925 }
926 }
Brian Murray0f6af732016-05-19 15:59:23 -0700927 return( ret );
928}
929#endif /* MBEDTLS_AES_C */
930
931int mbedtls_cmac_self_test( int verbose )
932{
Janos Follath24eed8d2019-11-22 13:21:35 +0000933 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100934
Simon Butcher69283e52016-10-06 12:49:58 +0100935#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100936 /* AES-128 */
937 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100938 "AES 128",
939 aes_128_key,
940 128,
941 (const unsigned char*)aes_128_subkeys,
942 MBEDTLS_CIPHER_AES_128_ECB,
943 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100944 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100945 {
946 return( ret );
947 }
948
Brian Murrayae1cb122016-05-23 15:01:59 -0700949 if( ( ret = cmac_test_wth_cipher( verbose,
950 "AES 128",
951 aes_128_key,
952 128,
953 test_message,
954 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100955 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100956 MBEDTLS_CIPHER_AES_128_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100957 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100958 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100959 {
960 return( ret );
961 }
962
963 /* AES-192 */
964 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100965 "AES 192",
966 aes_192_key,
967 192,
968 (const unsigned char*)aes_192_subkeys,
969 MBEDTLS_CIPHER_AES_192_ECB,
970 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100971 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700972 {
973 return( ret );
974 }
Brian Murray0f6af732016-05-19 15:59:23 -0700975
Brian Murrayae1cb122016-05-23 15:01:59 -0700976 if( ( ret = cmac_test_wth_cipher( verbose,
977 "AES 192",
978 aes_192_key,
979 192,
980 test_message,
981 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100982 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100983 MBEDTLS_CIPHER_AES_192_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100984 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100985 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100986 {
Simon Butcher327398a2016-10-05 14:09:11 +0100987 return( ret );
988 }
989
990 /* AES-256 */
991 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100992 "AES 256",
993 aes_256_key,
994 256,
995 (const unsigned char*)aes_256_subkeys,
996 MBEDTLS_CIPHER_AES_256_ECB,
997 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100998 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700999 {
1000 return( ret );
1001 }
Brian Murray0f6af732016-05-19 15:59:23 -07001002
Simon Butcher69283e52016-10-06 12:49:58 +01001003 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -07001004 "AES 256",
1005 aes_256_key,
1006 256,
1007 test_message,
1008 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001009 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001010 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001011 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001012 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001013 {
1014 return( ret );
1015 }
Brian Murray0f6af732016-05-19 15:59:23 -07001016#endif /* MBEDTLS_AES_C */
1017
Simon Butcher69283e52016-10-06 12:49:58 +01001018#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001019 /* 3DES 2 key */
1020 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001021 "3DES 2 key",
1022 des3_2key_key,
1023 192,
1024 (const unsigned char*)des3_2key_subkeys,
1025 MBEDTLS_CIPHER_DES_EDE3_ECB,
1026 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001027 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001028 {
1029 return( ret );
1030 }
1031
Brian Murrayae1cb122016-05-23 15:01:59 -07001032 if( ( ret = cmac_test_wth_cipher( verbose,
1033 "3DES 2 key",
1034 des3_2key_key,
1035 192,
1036 test_message,
1037 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001038 (const unsigned char*)des3_2key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001039 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001040 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001041 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001042 {
1043 return( ret );
1044 }
Brian Murray0f6af732016-05-19 15:59:23 -07001045
Simon Butcher327398a2016-10-05 14:09:11 +01001046 /* 3DES 3 key */
1047 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001048 "3DES 3 key",
1049 des3_3key_key,
1050 192,
1051 (const unsigned char*)des3_3key_subkeys,
1052 MBEDTLS_CIPHER_DES_EDE3_ECB,
1053 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001054 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001055 {
1056 return( ret );
1057 }
1058
Brian Murrayae1cb122016-05-23 15:01:59 -07001059 if( ( ret = cmac_test_wth_cipher( verbose,
1060 "3DES 3 key",
1061 des3_3key_key,
1062 192,
1063 test_message,
1064 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001065 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001066 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001067 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001068 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001069 {
1070 return( ret );
1071 }
Brian Murray0f6af732016-05-19 15:59:23 -07001072#endif /* MBEDTLS_DES_C */
1073
Simon Butcher69283e52016-10-06 12:49:58 +01001074#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001075 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001076 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001077#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001078
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001079 if( verbose != 0 )
1080 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001081
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001082 return( 0 );
1083}
1084
Brian Murray0f6af732016-05-19 15:59:23 -07001085#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001086
1087#endif /* MBEDTLS_CMAC_C */