blob: 987085686163bc4a5a81ca69e25f5a06defd2694 [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)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000151
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000152/*
153 * Create padded last block from (partial) last block.
154 *
155 * We can't use the padding option from the cipher layer, as it only works for
156 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
157 */
Simon Butcher69283e52016-10-06 12:49:58 +0100158static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
Brian Murray53e23b62016-09-13 14:00:15 -0700159 size_t padded_block_len,
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000160 const unsigned char *last_block,
Brian Murrayb0c3c432016-05-18 14:29:51 -0700161 size_t last_block_len )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000162{
163 size_t j;
164
Brian Murrayb0c3c432016-05-18 14:29:51 -0700165 for( j = 0; j < padded_block_len; j++ )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000166 {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700167 if( j < last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000168 padded_block[j] = last_block[j];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700169 else if( j == last_block_len )
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000170 padded_block[j] = 0x80;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000171 else
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000172 padded_block[j] = 0x00;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000173 }
174}
175
Simon Butcher327398a2016-10-05 14:09:11 +0100176int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
Simon Butcher94ffde72016-10-05 15:33:53 +0100177 const unsigned char *key, size_t keybits )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000178{
Simon Butcher327398a2016-10-05 14:09:11 +0100179 mbedtls_cipher_type_t type;
180 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100181 int retval;
182
183 if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
184 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
185
Simon B3249cb72016-11-03 01:11:37 +0000186 if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
Simon Butcher327398a2016-10-05 14:09:11 +0100187 MBEDTLS_ENCRYPT ) ) != 0 )
188 return( retval );
189
Simon Butcher327398a2016-10-05 14:09:11 +0100190 type = ctx->cipher_info->type;
191
192 switch( type )
193 {
194 case MBEDTLS_CIPHER_AES_128_ECB:
195 case MBEDTLS_CIPHER_AES_192_ECB:
196 case MBEDTLS_CIPHER_AES_256_ECB:
197 case MBEDTLS_CIPHER_DES_EDE3_ECB:
198 break;
199 default:
200 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
201 }
202
203 /* Allocated and initialise in the cipher context memory for the CMAC
204 * context */
205 cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
206 if( cmac_ctx == NULL )
207 return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
208
209 ctx->cmac_ctx = cmac_ctx;
210
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500211 mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100212
213 return 0;
214}
215
216int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
217 const unsigned char *input, size_t ilen )
218{
219 mbedtls_cmac_context_t* cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700220 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000221 int ret = 0;
222 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700223
Simon Butcher327398a2016-10-05 14:09:11 +0100224 if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
225 ctx->cmac_ctx == NULL )
226 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700227
Simon Butcher327398a2016-10-05 14:09:11 +0100228 cmac_ctx = ctx->cmac_ctx;
229 block_size = ctx->cipher_info->block_size;
230 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000231
Simon Butcher6b0774a2016-10-10 21:37:42 +0100232 /* Is there data still to process from the last call, that's greater in
233 * size than a block? */
Simon Butcher327398a2016-10-05 14:09:11 +0100234 if( cmac_ctx->unprocessed_len > 0 &&
Andres AGa592dcc2016-10-06 15:23:39 +0100235 ilen > block_size - cmac_ctx->unprocessed_len )
Brian Murray57863ad2016-05-19 16:38:36 -0700236 {
Simon Butcher327398a2016-10-05 14:09:11 +0100237 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
238 input,
239 block_size - cmac_ctx->unprocessed_len );
240
Dave Rodgman8c0ff812022-11-22 16:38:44 +0000241 mbedtls_xor( state, cmac_ctx->unprocessed_block, state, block_size );
Simon Butcher327398a2016-10-05 14:09:11 +0100242
243 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
244 &olen ) ) != 0 )
245 {
246 goto exit;
247 }
248
Simon Butcher6b0774a2016-10-10 21:37:42 +0100249 input += block_size - cmac_ctx->unprocessed_len;
250 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100251 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700252 }
253
Simon Butcher327398a2016-10-05 14:09:11 +0100254 /* n is the number of blocks including any final partial block */
255 n = ( ilen + block_size - 1 ) / block_size;
256
Simon B3249cb72016-11-03 01:11:37 +0000257 /* Iterate across the input data in block sized chunks, excluding any
258 * final partial or complete block */
259 for( j = 1; j < n; j++ )
Brian Murray57863ad2016-05-19 16:38:36 -0700260 {
Dave Rodgman8c0ff812022-11-22 16:38:44 +0000261 mbedtls_xor( state, input, state, block_size );
Simon Butcher327398a2016-10-05 14:09:11 +0100262
263 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
264 &olen ) ) != 0 )
265 goto exit;
266
267 ilen -= block_size;
268 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700269 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000270
Simon Butcher327398a2016-10-05 14:09:11 +0100271 /* If there is data left over that wasn't aligned to a block */
272 if( ilen > 0 )
273 {
Simon Butcher6b0774a2016-10-10 21:37:42 +0100274 memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
275 input,
276 ilen );
277 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100278 }
279
280exit:
281 return( ret );
282}
283
284int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
285 unsigned char *output )
286{
287 mbedtls_cmac_context_t* cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100288 unsigned char *state, *last_block;
289 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
290 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
291 unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
Janos Follath24eed8d2019-11-22 13:21:35 +0000292 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100293 size_t olen, block_size;
294
295 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
296 output == NULL )
297 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
298
299 cmac_ctx = ctx->cmac_ctx;
300 block_size = ctx->cipher_info->block_size;
301 state = cmac_ctx->state;
302
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500303 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
304 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100305 cmac_generate_subkeys( ctx, K1, K2 );
306
Simon Butcher69283e52016-10-06 12:49:58 +0100307 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000308
309 /* Calculate last block */
Janos Follathe3d882a2016-10-11 10:49:26 +0100310 if( cmac_ctx->unprocessed_len < block_size )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000311 {
Simon Butcher327398a2016-10-05 14:09:11 +0100312 cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
Dave Rodgman8c0ff812022-11-22 16:38:44 +0000313 mbedtls_xor( M_last, M_last, K2, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000314 }
315 else
316 {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000317 /* Last block is complete block */
Dave Rodgman8c0ff812022-11-22 16:38:44 +0000318 mbedtls_xor( M_last, last_block, K1, block_size );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000319 }
320
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000321
Dave Rodgman8c0ff812022-11-22 16:38:44 +0000322 mbedtls_xor( state, M_last, state, block_size );
Simon Butcher327398a2016-10-05 14:09:11 +0100323 if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
324 &olen ) ) != 0 )
325 {
326 goto exit;
327 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000328
Simon Butcher327398a2016-10-05 14:09:11 +0100329 memcpy( output, state, block_size );
330
331exit:
332 /* Wipe the generated keys on the stack, and any other transients to avoid
333 * side channel leakage */
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500334 mbedtls_platform_zeroize( K1, sizeof( K1 ) );
335 mbedtls_platform_zeroize( K2, sizeof( K2 ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100336
337 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500338 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
339 sizeof( cmac_ctx->unprocessed_block ) );
Simon Butcher327398a2016-10-05 14:09:11 +0100340
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500341 mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
Simon Butcher327398a2016-10-05 14:09:11 +0100342 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000343}
344
Simon Butcher327398a2016-10-05 14:09:11 +0100345int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000346{
Simon Butcher327398a2016-10-05 14:09:11 +0100347 mbedtls_cmac_context_t* cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000348
Simon Butcher327398a2016-10-05 14:09:11 +0100349 if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
350 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700351
Simon Butcher327398a2016-10-05 14:09:11 +0100352 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000353
Simon Butcher327398a2016-10-05 14:09:11 +0100354 /* Reset the internal state */
355 cmac_ctx->unprocessed_len = 0;
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500356 mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
357 sizeof( cmac_ctx->unprocessed_block ) );
358 mbedtls_platform_zeroize( cmac_ctx->state,
359 sizeof( cmac_ctx->state ) );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000360
Simon Butcher327398a2016-10-05 14:09:11 +0100361 return( 0 );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000362}
363
Simon Butcher327398a2016-10-05 14:09:11 +0100364int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
365 const unsigned char *key, size_t keylen,
366 const unsigned char *input, size_t ilen,
367 unsigned char *output )
368{
369 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000370 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100371
372 if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
373 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
374
375 mbedtls_cipher_init( &ctx );
376
377 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
378 goto exit;
379
380 ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
Simon Butcher327398a2016-10-05 14:09:11 +0100381 if( ret != 0 )
382 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100383
384 ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
385 if( ret != 0 )
386 goto exit;
387
Simon Butcher69283e52016-10-06 12:49:58 +0100388 ret = mbedtls_cipher_cmac_finish( &ctx, output );
Simon Butcher327398a2016-10-05 14:09:11 +0100389
390exit:
Simon Butcher69283e52016-10-06 12:49:58 +0100391 mbedtls_cipher_free( &ctx );
392
Simon Butcher327398a2016-10-05 14:09:11 +0100393 return( ret );
394}
Simon Butcher327398a2016-10-05 14:09:11 +0100395
Simon Butcher69283e52016-10-06 12:49:58 +0100396#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000397/*
Simon Butcher69283e52016-10-06 12:49:58 +0100398 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000399 */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700400int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
Manuel Pégourié-Gonnard690083c2016-01-13 10:48:02 +0000401 const unsigned char *input, size_t in_len,
Rodrigo Dias Correa2c424572020-11-10 01:38:00 -0300402 unsigned char output[16] )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000403{
Janos Follath24eed8d2019-11-22 13:21:35 +0000404 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100405 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100406 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
407 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
408
409 if( key == NULL || input == NULL || output == NULL )
410 return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000411
Simon Butcher327398a2016-10-05 14:09:11 +0100412 cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
413 if( cipher_info == NULL )
414 {
415 /* Failing at this point must be due to a build issue */
416 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
417 goto exit;
418 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700419
Simon Butcher69283e52016-10-06 12:49:58 +0100420 if( key_length == MBEDTLS_AES_BLOCK_SIZE )
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000421 {
422 /* Use key as is */
Simon Butcher69283e52016-10-06 12:49:58 +0100423 memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000424 }
425 else
426 {
Simon Butcher69283e52016-10-06 12:49:58 +0100427 memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000428
Simon Butcher327398a2016-10-05 14:09:11 +0100429 ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
430 key_length, int_key );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000431 if( ret != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700432 goto exit;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000433 }
434
Simon Butcher327398a2016-10-05 14:09:11 +0100435 ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
436 output );
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000437
Simon Butcher327398a2016-10-05 14:09:11 +0100438exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500439 mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700440
Simon Butcher327398a2016-10-05 14:09:11 +0100441 return( ret );
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000442}
Brian Murrayb439d452016-05-19 16:02:42 -0700443#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000444
Steven Cooreman63342772017-04-04 11:47:16 +0200445#endif /* !MBEDTLS_CMAC_ALT */
446
Simon Butcher69283e52016-10-06 12:49:58 +0100447#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000448/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000449 * CMAC test data for SP800-38B
450 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
451 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700452 *
453 * AES-CMAC-PRF-128 test data from RFC 4615
454 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000455 */
456
Brian Murray0f6af732016-05-19 15:59:23 -0700457#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000458#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100459
Brian Murray0f6af732016-05-19 15:59:23 -0700460#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
461/* All CMAC test inputs are truncated from the same 64 byte buffer. */
462static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000463 /* PT */
464 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
465 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
466 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
467 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
468 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
469 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
470 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
471 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000472};
Simon Butcher69283e52016-10-06 12:49:58 +0100473#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700474
Simon Butcher69283e52016-10-06 12:49:58 +0100475#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700476/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700477static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000478 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700479 0,
480 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000481 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700482 64
483};
484
Janos Follathcd13bd22016-12-13 11:51:04 +0000485/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700486static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000487 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
488 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700489};
Simon Butcher69283e52016-10-06 12:49:58 +0100490static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700491 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000492 /* K1 */
493 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
494 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700495 },
496 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000497 /* K2 */
498 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
499 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700500 }
501};
Simon Butcher69283e52016-10-06 12:49:58 +0100502static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000503 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000504 /* Example #1 */
505 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
506 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000507 },
508 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000509 /* Example #2 */
510 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
511 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000512 },
513 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000514 /* Example #3 */
515 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
516 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000517 },
518 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000519 /* Example #4 */
520 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
521 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000522 }
523};
524
Janos Follathcd13bd22016-12-13 11:51:04 +0000525/* CMAC-AES192 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700526static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000527 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
528 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
529 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000530};
Simon Butcher69283e52016-10-06 12:49:58 +0100531static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700532 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000533 /* K1 */
534 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
535 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700536 },
537 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000538 /* K2 */
539 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
540 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700541 }
542};
Simon Butcher69283e52016-10-06 12:49:58 +0100543static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700544 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000545 /* Example #1 */
546 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
547 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700548 },
549 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000550 /* Example #2 */
551 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
552 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700553 },
554 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000555 /* Example #3 */
556 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
557 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700558 },
559 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000560 /* Example #4 */
561 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
562 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700563 }
564};
565
Janos Follathcd13bd22016-12-13 11:51:04 +0000566/* CMAC-AES256 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700567static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000568 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
569 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
570 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
571 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700572};
Simon Butcher69283e52016-10-06 12:49:58 +0100573static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700574 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000575 /* K1 */
576 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
577 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700578 },
579 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000580 /* K2 */
581 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
582 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700583 }
584};
Simon Butcher69283e52016-10-06 12:49:58 +0100585static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700586 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000587 /* Example #1 */
588 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
589 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700590 },
591 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000592 /* Example #2 */
593 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
594 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700595 },
596 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000597 /* Example #3 */
598 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
599 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700600 },
601 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000602 /* Example #4 */
603 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
604 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700605 }
606};
607#endif /* MBEDTLS_AES_C */
608
Simon Butcher69283e52016-10-06 12:49:58 +0100609#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700610/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700611static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700612 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000613 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700614 20,
615 32
616};
617
Janos Follathcd13bd22016-12-13 11:51:04 +0000618/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700619static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000620 /* Key1 */
621 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
622 /* Key2 */
623 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
624 /* Key3 */
625 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700626};
627static const unsigned char des3_2key_subkeys[2][8] = {
628 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000629 /* K1 */
630 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700631 },
632 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000633 /* K2 */
634 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700635 }
636};
Simon Butcher69283e52016-10-06 12:49:58 +0100637static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700638 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000639 /* Sample #1 */
640 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700641 },
642 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000643 /* Sample #2 */
644 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700645 },
646 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000647 /* Sample #3 */
648 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700649 },
650 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000651 /* Sample #4 */
652 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700653 }
654};
655
Janos Follathcd13bd22016-12-13 11:51:04 +0000656/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700657static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000658 /* Key1 */
659 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
660 /* Key2 */
661 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
662 /* Key3 */
663 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700664};
665static const unsigned char des3_3key_subkeys[2][8] = {
666 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000667 /* K1 */
668 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700669 },
670 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000671 /* K2 */
672 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700673 }
674};
Simon Butcher69283e52016-10-06 12:49:58 +0100675static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700676 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000677 /* Sample #1 */
678 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700679 },
680 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000681 /* Sample #2 */
682 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700683 },
684 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000685 /* Sample #3 */
686 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700687 },
688 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000689 /* Sample #4 */
690 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700691 }
692};
693
Brian Murray0f6af732016-05-19 15:59:23 -0700694#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700695
Simon Butcher69283e52016-10-06 12:49:58 +0100696#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700697/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000698static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000699 /* Key */
700 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
701 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000702 0xed, 0xcb
703};
704
705/* Sizes in bytes */
706static const size_t PRFKlen[NB_PRF_TESTS] = {
707 18,
708 16,
709 10
710};
711
Janos Follathcd13bd22016-12-13 11:51:04 +0000712/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000713static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000714 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
715 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000716 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000717};
718
719static const unsigned char PRFT[NB_PRF_TESTS][16] = {
720 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000721 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
722 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000723 },
724 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000725 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
726 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000727 },
728 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000729 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
730 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000731 }
732};
Brian Murray0f6af732016-05-19 15:59:23 -0700733#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000734
Simon Butcher327398a2016-10-05 14:09:11 +0100735static int cmac_test_subkeys( int verbose,
736 const char* testname,
737 const unsigned char* key,
738 int keybits,
739 const unsigned char* subkeys,
740 mbedtls_cipher_type_t cipher_type,
741 int block_size,
742 int num_tests )
743{
Brian Murray2fab5c92016-12-15 18:51:13 -0800744 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100745 mbedtls_cipher_context_t ctx;
746 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100747 unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
748 unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
Simon Butcher327398a2016-10-05 14:09:11 +0100749
750 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
751 if( cipher_info == NULL )
752 {
753 /* Failing at this point must be due to a build issue */
Simon Butcher69283e52016-10-06 12:49:58 +0100754 return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
Simon Butcher327398a2016-10-05 14:09:11 +0100755 }
756
757 for( i = 0; i < num_tests; i++ )
758 {
759 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +0200760 mbedtls_printf( " %s CMAC subkey #%d: ", testname, i + 1 );
Simon Butcher327398a2016-10-05 14:09:11 +0100761
Janos Follathd4443582016-10-12 10:00:42 +0100762 mbedtls_cipher_init( &ctx );
763
Simon Butcher327398a2016-10-05 14:09:11 +0100764 if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
765 {
766 if( verbose != 0 )
767 mbedtls_printf( "test execution failed\n" );
768
Janos Follathd4443582016-10-12 10:00:42 +0100769 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100770 }
771
772 if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
773 MBEDTLS_ENCRYPT ) ) != 0 )
774 {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100775 /* When CMAC is implemented by an alternative implementation, or
776 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100777 * AES-192 may be unavailable. This should not cause the selftest
778 * function to fail. */
Steven Cooreman03f40842021-01-19 13:30:48 +0100779 if( ( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
780 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) &&
781 cipher_type == MBEDTLS_CIPHER_AES_192_ECB ) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100782 if( verbose != 0 )
783 mbedtls_printf( "skipped\n" );
784 goto next_test;
785 }
786
Simon Butcher327398a2016-10-05 14:09:11 +0100787 if( verbose != 0 )
788 mbedtls_printf( "test execution failed\n" );
789
Janos Follathd4443582016-10-12 10:00:42 +0100790 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100791 }
792
793 ret = cmac_generate_subkeys( &ctx, K1, K2 );
794 if( ret != 0 )
795 {
796 if( verbose != 0 )
797 mbedtls_printf( "failed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100798
799 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100800 }
801
Simon Butcher420be4e2016-10-07 12:55:43 +0100802 if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 ||
803 ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100804 {
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
811 if( verbose != 0 )
812 mbedtls_printf( "passed\n" );
Janos Follathd4443582016-10-12 10:00:42 +0100813
Steven Cooreman830d5af2021-01-08 18:01:46 +0100814next_test:
Janos Follathd4443582016-10-12 10:00:42 +0100815 mbedtls_cipher_free( &ctx );
Simon Butcher327398a2016-10-05 14:09:11 +0100816 }
817
Gilles Peskinedf761d52018-03-01 22:18:14 +0100818 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100819 goto exit;
820
821cleanup:
Simon Butcher69283e52016-10-06 12:49:58 +0100822 mbedtls_cipher_free( &ctx );
823
Janos Follathd4443582016-10-12 10:00:42 +0100824exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100825 return( ret );
826}
827
Simon Butcher69283e52016-10-06 12:49:58 +0100828static int cmac_test_wth_cipher( int verbose,
829 const char* testname,
830 const unsigned char* key,
831 int keybits,
832 const unsigned char* messages,
833 const unsigned int message_lengths[4],
834 const unsigned char* expected_result,
835 mbedtls_cipher_type_t cipher_type,
836 int block_size,
837 int num_tests )
Brian Murray00dc5f02016-05-19 14:23:50 -0700838{
Simon Butcher327398a2016-10-05 14:09:11 +0100839 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800840 int i, ret = 0;
Simon Butcher69283e52016-10-06 12:49:58 +0100841 unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
Brian Murray57863ad2016-05-19 16:38:36 -0700842
Simon Butcher327398a2016-10-05 14:09:11 +0100843 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
844 if( cipher_info == NULL )
Brian Murray00dc5f02016-05-19 14:23:50 -0700845 {
Simon Butcher327398a2016-10-05 14:09:11 +0100846 /* Failing at this point must be due to a build issue */
847 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700848 goto exit;
849 }
850
851 for( i = 0; i < num_tests; i++ )
852 {
853 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +0200854 mbedtls_printf( " %s CMAC #%d: ", testname, i + 1 );
Brian Murray00dc5f02016-05-19 14:23:50 -0700855
Simon Butcher327398a2016-10-05 14:09:11 +0100856 if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
857 message_lengths[i], output ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700858 {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100859 /* When CMAC is implemented by an alternative implementation, or
860 * the underlying primitive itself is implemented alternatively,
Steven Cooremand3679902021-02-15 13:42:35 +0100861 * AES-192 and/or 3DES may be unavailable. This should not cause
862 * the selftest function to fail. */
Steven Cooreman03f40842021-01-19 13:30:48 +0100863 if( ( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
864 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) &&
Steven Cooremand3679902021-02-15 13:42:35 +0100865 ( cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
866 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB ) ) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100867 if( verbose != 0 )
868 mbedtls_printf( "skipped\n" );
869 continue;
870 }
871
Brian Murray00dc5f02016-05-19 14:23:50 -0700872 if( verbose != 0 )
873 mbedtls_printf( "failed\n" );
874 goto exit;
875 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700876
Simon Butcher327398a2016-10-05 14:09:11 +0100877 if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
Brian Murray00dc5f02016-05-19 14:23:50 -0700878 {
879 if( verbose != 0 )
880 mbedtls_printf( "failed\n" );
881 goto exit;
882 }
883
Brian Murray9ce2e092016-05-24 22:46:43 -0700884 if( verbose != 0 )
885 mbedtls_printf( "passed\n" );
Brian Murray00dc5f02016-05-19 14:23:50 -0700886 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100887 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100888
Simon Butcher69283e52016-10-06 12:49:58 +0100889exit:
Simon Butcher327398a2016-10-05 14:09:11 +0100890 return( ret );
Brian Murray00dc5f02016-05-19 14:23:50 -0700891}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000892
Simon Butcher69283e52016-10-06 12:49:58 +0100893#if defined(MBEDTLS_AES_C)
894static int test_aes128_cmac_prf( int verbose )
Brian Murray6a3c0d22016-05-20 18:25:43 -0700895{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000896 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000897 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100898 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100899
Brian Murrayb0c3c432016-05-18 14:29:51 -0700900 for( i = 0; i < NB_PRF_TESTS; i++ )
901 {
Kenneth Soerensen518d4352020-04-01 17:22:45 +0200902 mbedtls_printf( " AES CMAC 128 PRF #%d: ", i );
Simon Butcher327398a2016-10-05 14:09:11 +0100903 ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
Brian Murrayb0c3c432016-05-18 14:29:51 -0700904 if( ret != 0 ||
Simon Butcher69283e52016-10-06 12:49:58 +0100905 memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700906 {
Simon Butcher327398a2016-10-05 14:09:11 +0100907
Brian Murrayb0c3c432016-05-18 14:29:51 -0700908 if( verbose != 0 )
909 mbedtls_printf( "failed\n" );
910
Brian Murray0f6af732016-05-19 15:59:23 -0700911 return( ret );
Simon Butcher69283e52016-10-06 12:49:58 +0100912 }
913 else if( verbose != 0 )
Brian Murrayb0c3c432016-05-18 14:29:51 -0700914 {
915 mbedtls_printf( "passed\n" );
916 }
917 }
Brian Murray0f6af732016-05-19 15:59:23 -0700918 return( ret );
919}
920#endif /* MBEDTLS_AES_C */
921
922int mbedtls_cmac_self_test( int verbose )
923{
Janos Follath24eed8d2019-11-22 13:21:35 +0000924 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100925
Simon Butcher69283e52016-10-06 12:49:58 +0100926#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100927 /* AES-128 */
928 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100929 "AES 128",
930 aes_128_key,
931 128,
932 (const unsigned char*)aes_128_subkeys,
933 MBEDTLS_CIPHER_AES_128_ECB,
934 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100935 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100936 {
937 return( ret );
938 }
939
Brian Murrayae1cb122016-05-23 15:01:59 -0700940 if( ( ret = cmac_test_wth_cipher( verbose,
941 "AES 128",
942 aes_128_key,
943 128,
944 test_message,
945 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100946 (const unsigned char*)aes_128_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100947 MBEDTLS_CIPHER_AES_128_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100948 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100949 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100950 {
951 return( ret );
952 }
953
954 /* AES-192 */
955 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100956 "AES 192",
957 aes_192_key,
958 192,
959 (const unsigned char*)aes_192_subkeys,
960 MBEDTLS_CIPHER_AES_192_ECB,
961 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100962 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700963 {
964 return( ret );
965 }
Brian Murray0f6af732016-05-19 15:59:23 -0700966
Brian Murrayae1cb122016-05-23 15:01:59 -0700967 if( ( ret = cmac_test_wth_cipher( verbose,
968 "AES 192",
969 aes_192_key,
970 192,
971 test_message,
972 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +0100973 (const unsigned char*)aes_192_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +0100974 MBEDTLS_CIPHER_AES_192_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +0100975 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100976 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +0100977 {
Simon Butcher327398a2016-10-05 14:09:11 +0100978 return( ret );
979 }
980
981 /* AES-256 */
982 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +0100983 "AES 256",
984 aes_256_key,
985 256,
986 (const unsigned char*)aes_256_subkeys,
987 MBEDTLS_CIPHER_AES_256_ECB,
988 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +0100989 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -0700990 {
991 return( ret );
992 }
Brian Murray0f6af732016-05-19 15:59:23 -0700993
Simon Butcher69283e52016-10-06 12:49:58 +0100994 if( ( ret = cmac_test_wth_cipher ( verbose,
Brian Murrayae1cb122016-05-23 15:01:59 -0700995 "AES 256",
996 aes_256_key,
997 256,
998 test_message,
999 aes_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001000 (const unsigned char*)aes_256_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001001 MBEDTLS_CIPHER_AES_256_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001002 MBEDTLS_AES_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001003 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001004 {
1005 return( ret );
1006 }
Brian Murray0f6af732016-05-19 15:59:23 -07001007#endif /* MBEDTLS_AES_C */
1008
Simon Butcher69283e52016-10-06 12:49:58 +01001009#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001010 /* 3DES 2 key */
1011 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001012 "3DES 2 key",
1013 des3_2key_key,
1014 192,
1015 (const unsigned char*)des3_2key_subkeys,
1016 MBEDTLS_CIPHER_DES_EDE3_ECB,
1017 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001018 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001019 {
1020 return( ret );
1021 }
1022
Brian Murrayae1cb122016-05-23 15:01:59 -07001023 if( ( ret = cmac_test_wth_cipher( verbose,
1024 "3DES 2 key",
1025 des3_2key_key,
1026 192,
1027 test_message,
1028 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001029 (const unsigned char*)des3_2key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001030 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001031 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001032 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001033 {
1034 return( ret );
1035 }
Brian Murray0f6af732016-05-19 15:59:23 -07001036
Simon Butcher327398a2016-10-05 14:09:11 +01001037 /* 3DES 3 key */
1038 if( ( ret = cmac_test_subkeys( verbose,
Simon Butcher69283e52016-10-06 12:49:58 +01001039 "3DES 3 key",
1040 des3_3key_key,
1041 192,
1042 (const unsigned char*)des3_3key_subkeys,
1043 MBEDTLS_CIPHER_DES_EDE3_ECB,
1044 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001045 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Simon Butcher327398a2016-10-05 14:09:11 +01001046 {
1047 return( ret );
1048 }
1049
Brian Murrayae1cb122016-05-23 15:01:59 -07001050 if( ( ret = cmac_test_wth_cipher( verbose,
1051 "3DES 3 key",
1052 des3_3key_key,
1053 192,
1054 test_message,
1055 des3_message_lengths,
Simon Butcher69283e52016-10-06 12:49:58 +01001056 (const unsigned char*)des3_3key_expected_result,
Simon Butcher327398a2016-10-05 14:09:11 +01001057 MBEDTLS_CIPHER_DES_EDE3_ECB,
Simon Butcher69283e52016-10-06 12:49:58 +01001058 MBEDTLS_DES3_BLOCK_SIZE,
Simon Butcher420be4e2016-10-07 12:55:43 +01001059 NB_CMAC_TESTS_PER_KEY ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001060 {
1061 return( ret );
1062 }
Brian Murray0f6af732016-05-19 15:59:23 -07001063#endif /* MBEDTLS_DES_C */
1064
Simon Butcher69283e52016-10-06 12:49:58 +01001065#if defined(MBEDTLS_AES_C)
Simon Butcher420be4e2016-10-07 12:55:43 +01001066 if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
Brian Murray9044b022016-05-19 16:36:56 -07001067 return( ret );
Brian Murray0f6af732016-05-19 15:59:23 -07001068#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001069
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001070 if( verbose != 0 )
1071 mbedtls_printf( "\n" );
Brian Murray0f6af732016-05-19 15:59:23 -07001072
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001073 return( 0 );
1074}
1075
Brian Murray0f6af732016-05-19 15:59:23 -07001076#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001077
1078#endif /* MBEDTLS_CMAC_C */