blob: f40cae20c4ead7f2f6ae04cb13b8e4afbab7c10b [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
Dave Rodgman16799db2023-11-02 19:47:20 +00007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Robert Cragie3d23b1d2015-12-15 07:38:11 +00008 */
9
10/*
Brian Murray53e23b62016-09-13 14:00:15 -070011 * References:
Simon Butcher327398a2016-10-05 14:09:11 +010012 *
13 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
14 * CMAC Mode for Authentication
Janos Follathcd13bd22016-12-13 11:51:04 +000015 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
Simon Butcher327398a2016-10-05 14:09:11 +010016 *
17 * - RFC 4493 - The AES-CMAC Algorithm
18 * https://tools.ietf.org/html/rfc4493
19 *
20 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
21 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
22 * Algorithm for the Internet Key Exchange Protocol (IKE)
23 * https://tools.ietf.org/html/rfc4615
24 *
25 * Additional test vectors: ISO/IEC 9797-1
26 *
Robert Cragie3d23b1d2015-12-15 07:38:11 +000027 */
28
Gilles Peskinedb09ef62020-06-03 01:43:33 +020029#include "common.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000030
31#if defined(MBEDTLS_CMAC_C)
32
33#include "mbedtls/cmac.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Steven Cooreman655b0122021-01-11 14:34:51 +010036#include "mbedtls/platform.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000037
38#include <string.h>
39
Ron Eldor621080d2017-12-21 10:57:43 +020040#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020041
Robert Cragie3d23b1d2015-12-15 07:38:11 +000042/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070043 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000044 *
Brian Murray72b69e32016-09-13 14:21:01 -070045 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000046 *
Simon Butcher327398a2016-10-05 14:09:11 +010047 * If MSB(p) = 0, then p = (p << 1)
48 * If MSB(p) = 1, then p = (p << 1) ^ R_n
49 * with R_64 = 0x1B and R_128 = 0x87
50 *
51 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -080052 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000053 */
Gilles Peskine449bd832023-01-11 14:50:10 +010054static int cmac_multiply_by_u(unsigned char *output,
55 const unsigned char *input,
56 size_t blocksize)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000057{
Brian Murrayb0c3c432016-05-18 14:29:51 -070058 const unsigned char R_128 = 0x87;
59 const unsigned char R_64 = 0x1B;
60 unsigned char R_n, mask;
61 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010062 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070063
Gilles Peskine449bd832023-01-11 14:50:10 +010064 if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070065 R_n = R_128;
Gilles Peskine449bd832023-01-11 14:50:10 +010066 } else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070067 R_n = R_64;
Gilles Peskine449bd832023-01-11 14:50:10 +010068 } else {
69 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Brian Murrayb0c3c432016-05-18 14:29:51 -070070 }
71
Gilles Peskine449bd832023-01-11 14:50:10 +010072 for (i = (int) blocksize - 1; i >= 0; i--) {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000073 output[i] = input[i] << 1 | overflow;
74 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000075 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000076
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000077 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
78 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +010079
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000080 /* MSVC has a warning about unary minus on unsigned, but this is
81 * well-defined and precisely what we want to do here */
82#if defined(_MSC_VER)
83#pragma warning( push )
84#pragma warning( disable : 4146 )
85#endif
Gilles Peskine449bd832023-01-11 14:50:10 +010086 mask = -(input[0] >> 7);
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000087#if defined(_MSC_VER)
88#pragma warning( pop )
89#endif
90
Gilles Peskine449bd832023-01-11 14:50:10 +010091 output[blocksize - 1] ^= R_n & mask;
Simon Butcher327398a2016-10-05 14:09:11 +010092
Gilles Peskine449bd832023-01-11 14:50:10 +010093 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000094}
95
96/*
97 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +010098 *
99 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000100 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100101static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
102 unsigned char *K1, unsigned char *K2)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000103{
Janos Follath24eed8d2019-11-22 13:21:35 +0000104 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200105 unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700106 size_t olen, block_size;
107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 mbedtls_platform_zeroize(L, sizeof(L));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700109
Dave Rodgman85a88132023-06-24 11:41:50 +0100110 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100111
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000112 /* Calculate Ek(0) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100113 if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700114 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000116
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000117 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000118 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000119 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700121 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100125 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 }
Simon Butcher327398a2016-10-05 14:09:11 +0100127
128exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 mbedtls_platform_zeroize(L, sizeof(L));
Simon Butcher327398a2016-10-05 14:09:11 +0100130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000132}
Ron Eldor621080d2017-12-21 10:57:43 +0200133#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000134
Ron Eldor621080d2017-12-21 10:57:43 +0200135#if !defined(MBEDTLS_CMAC_ALT)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000136
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000137/*
138 * Create padded last block from (partial) last block.
139 *
140 * We can't use the padding option from the cipher layer, as it only works for
141 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
142 */
Gilles Peskine9e930e22023-06-14 17:52:54 +0200143static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 size_t padded_block_len,
145 const unsigned char *last_block,
146 size_t last_block_len)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000147{
148 size_t j;
149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 for (j = 0; j < padded_block_len; j++) {
151 if (j < last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000152 padded_block[j] = last_block[j];
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 } else if (j == last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000154 padded_block[j] = 0x80;
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 } else {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000156 padded_block[j] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000158 }
159}
160
Gilles Peskine449bd832023-01-11 14:50:10 +0100161int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
162 const unsigned char *key, size_t keybits)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000163{
Simon Butcher327398a2016-10-05 14:09:11 +0100164 mbedtls_cipher_type_t type;
165 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100166 int retval;
167
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
169 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
170 }
Simon Butcher327398a2016-10-05 14:09:11 +0100171
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
173 MBEDTLS_ENCRYPT)) != 0) {
174 return retval;
175 }
Simon Butcher327398a2016-10-05 14:09:11 +0100176
Dave Rodgman2e8f6aa2023-06-24 17:32:18 +0100177 type = mbedtls_cipher_info_get_type(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 switch (type) {
Simon Butcher327398a2016-10-05 14:09:11 +0100180 case MBEDTLS_CIPHER_AES_128_ECB:
181 case MBEDTLS_CIPHER_AES_192_ECB:
182 case MBEDTLS_CIPHER_AES_256_ECB:
183 case MBEDTLS_CIPHER_DES_EDE3_ECB:
184 break;
185 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Simon Butcher327398a2016-10-05 14:09:11 +0100187 }
188
189 /* Allocated and initialise in the cipher context memory for the CMAC
190 * context */
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
192 if (cmac_ctx == NULL) {
193 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
194 }
Simon Butcher327398a2016-10-05 14:09:11 +0100195
196 ctx->cmac_ctx = cmac_ctx;
197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
Simon Butcher327398a2016-10-05 14:09:11 +0100199
200 return 0;
201}
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
204 const unsigned char *input, size_t ilen)
Simon Butcher327398a2016-10-05 14:09:11 +0100205{
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 mbedtls_cmac_context_t *cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700207 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000208 int ret = 0;
209 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700210
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
212 ctx->cmac_ctx == NULL) {
213 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
214 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700215
Simon Butcher327398a2016-10-05 14:09:11 +0100216 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100217 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100218 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000219
Simon Butcher6b0774a2016-10-10 21:37:42 +0100220 /* Is there data still to process from the last call, that's greater in
221 * size than a block? */
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 if (cmac_ctx->unprocessed_len > 0 &&
223 ilen > block_size - cmac_ctx->unprocessed_len) {
224 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
225 input,
226 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100227
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100228 mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
231 &olen)) != 0) {
232 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100233 }
234
Simon Butcher6b0774a2016-10-10 21:37:42 +0100235 input += block_size - cmac_ctx->unprocessed_len;
236 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100237 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700238 }
239
Simon Butcher327398a2016-10-05 14:09:11 +0100240 /* n is the number of blocks including any final partial block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100242
Simon B3249cb72016-11-03 01:11:37 +0000243 /* Iterate across the input data in block sized chunks, excluding any
244 * final partial or complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 for (j = 1; j < n; j++) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100246 mbedtls_xor_no_simd(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
249 &olen)) != 0) {
250 goto exit;
251 }
Simon Butcher327398a2016-10-05 14:09:11 +0100252
253 ilen -= block_size;
254 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700255 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000256
Simon Butcher327398a2016-10-05 14:09:11 +0100257 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 if (ilen > 0) {
259 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
260 input,
261 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100262 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100263 }
264
265exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100267}
268
Gilles Peskine449bd832023-01-11 14:50:10 +0100269int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
270 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100271{
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100273 unsigned char *state, *last_block;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200274 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
275 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
276 unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Janos Follath24eed8d2019-11-22 13:21:35 +0000277 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100278 size_t olen, block_size;
279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
281 output == NULL) {
282 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
283 }
Simon Butcher327398a2016-10-05 14:09:11 +0100284
285 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100286 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100287 state = cmac_ctx->state;
288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 mbedtls_platform_zeroize(K1, sizeof(K1));
290 mbedtls_platform_zeroize(K2, sizeof(K2));
291 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100292
Simon Butcher69283e52016-10-06 12:49:58 +0100293 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000294
295 /* Calculate last block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 if (cmac_ctx->unprocessed_len < block_size) {
297 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
298 mbedtls_xor(M_last, M_last, K2, block_size);
299 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000300 /* Last block is complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 mbedtls_xor(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000302 }
303
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 mbedtls_xor(state, M_last, state, block_size);
306 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
307 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100308 goto exit;
309 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100312
313exit:
314 /* Wipe the generated keys on the stack, and any other transients to avoid
315 * side channel leakage */
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 mbedtls_platform_zeroize(K1, sizeof(K1));
317 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100318
319 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
321 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100322
Gilles Peskine9e930e22023-06-14 17:52:54 +0200323 mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000325}
326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000328{
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
332 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
333 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700334
Simon Butcher327398a2016-10-05 14:09:11 +0100335 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000336
Simon Butcher327398a2016-10-05 14:09:11 +0100337 /* Reset the internal state */
338 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
340 sizeof(cmac_ctx->unprocessed_block));
341 mbedtls_platform_zeroize(cmac_ctx->state,
342 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000345}
346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
348 const unsigned char *key, size_t keylen,
349 const unsigned char *input, size_t ilen,
350 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100351{
352 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000353 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
356 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
357 }
Simon Butcher327398a2016-10-05 14:09:11 +0100358
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100362 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 }
Simon Butcher327398a2016-10-05 14:09:11 +0100364
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
366 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100367 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 }
Simon Butcher327398a2016-10-05 14:09:11 +0100369
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
371 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100372 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 }
Simon Butcher327398a2016-10-05 14:09:11 +0100374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 ret = mbedtls_cipher_cmac_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100376
377exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100379
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100381}
Simon Butcher327398a2016-10-05 14:09:11 +0100382
Simon Butcher69283e52016-10-06 12:49:58 +0100383#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000384/*
Simon Butcher69283e52016-10-06 12:49:58 +0100385 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000386 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100387int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
388 const unsigned char *input, size_t in_len,
389 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000390{
Janos Follath24eed8d2019-11-22 13:21:35 +0000391 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100392 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100393 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
394 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 if (key == NULL || input == NULL || output == NULL) {
397 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
398 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
401 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100402 /* Failing at this point must be due to a build issue */
403 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
404 goto exit;
405 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000408 /* Use key as is */
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
410 } else {
411 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
414 key_length, int_key);
415 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700416 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000418 }
419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
421 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000422
Simon Butcher327398a2016-10-05 14:09:11 +0100423exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000427}
Brian Murrayb439d452016-05-19 16:02:42 -0700428#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000429
Steven Cooreman63342772017-04-04 11:47:16 +0200430#endif /* !MBEDTLS_CMAC_ALT */
431
Simon Butcher69283e52016-10-06 12:49:58 +0100432#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000433/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000434 * CMAC test data for SP800-38B
435 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
436 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700437 *
438 * AES-CMAC-PRF-128 test data from RFC 4615
439 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000440 */
441
Brian Murray0f6af732016-05-19 15:59:23 -0700442#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000443#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100444
Brian Murray0f6af732016-05-19 15:59:23 -0700445#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
446/* All CMAC test inputs are truncated from the same 64 byte buffer. */
447static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000448 /* PT */
449 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
450 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
451 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
452 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
453 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
454 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
455 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
456 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000457};
Simon Butcher69283e52016-10-06 12:49:58 +0100458#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700459
Simon Butcher69283e52016-10-06 12:49:58 +0100460#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700461/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700462static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000463 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700464 0,
465 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000466 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700467 64
468};
469
Janos Follathcd13bd22016-12-13 11:51:04 +0000470/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700471static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000472 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
473 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700474};
Simon Butcher69283e52016-10-06 12:49:58 +0100475static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700476 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000477 /* K1 */
478 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
479 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700480 },
481 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000482 /* K2 */
483 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
484 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700485 }
486};
Gilles Peskine449bd832023-01-11 14:50:10 +0100487static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
488{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000489 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000490 /* Example #1 */
491 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
492 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000493 },
494 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000495 /* Example #2 */
496 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
497 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000498 },
499 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000500 /* Example #3 */
501 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
502 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000503 },
504 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000505 /* Example #4 */
506 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
507 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000508 }
509};
510
Janos Follathcd13bd22016-12-13 11:51:04 +0000511/* CMAC-AES192 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800512#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700513static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000514 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
515 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
516 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000517};
Simon Butcher69283e52016-10-06 12:49:58 +0100518static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700519 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000520 /* K1 */
521 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
522 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700523 },
524 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000525 /* K2 */
526 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
527 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700528 }
529};
Gilles Peskine449bd832023-01-11 14:50:10 +0100530static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
531{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700532 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000533 /* Example #1 */
534 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
535 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700536 },
537 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000538 /* Example #2 */
539 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
540 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700541 },
542 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000543 /* Example #3 */
544 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
545 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700546 },
547 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000548 /* Example #4 */
549 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
550 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700551 }
552};
Yanray Wangdd56add2023-05-11 13:53:46 +0800553#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700554
Janos Follathcd13bd22016-12-13 11:51:04 +0000555/* CMAC-AES256 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800556#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700557static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000558 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
559 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
560 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
561 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700562};
Simon Butcher69283e52016-10-06 12:49:58 +0100563static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700564 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000565 /* K1 */
566 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
567 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700568 },
569 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000570 /* K2 */
571 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
572 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700573 }
574};
Gilles Peskine449bd832023-01-11 14:50:10 +0100575static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
576{
Brian Murray0f6af732016-05-19 15:59:23 -0700577 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000578 /* Example #1 */
579 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
580 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700581 },
582 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000583 /* Example #2 */
584 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
585 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700586 },
587 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000588 /* Example #3 */
589 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
590 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700591 },
592 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000593 /* Example #4 */
594 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
595 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700596 }
597};
Yanray Wangdd56add2023-05-11 13:53:46 +0800598#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700599#endif /* MBEDTLS_AES_C */
600
Simon Butcher69283e52016-10-06 12:49:58 +0100601#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700602/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700603static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700604 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000605 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700606 20,
607 32
608};
609
Janos Follathcd13bd22016-12-13 11:51:04 +0000610/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700611static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000612 /* Key1 */
613 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
614 /* Key2 */
615 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
616 /* Key3 */
617 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700618};
619static const unsigned char des3_2key_subkeys[2][8] = {
620 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000621 /* K1 */
622 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700623 },
624 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000625 /* K2 */
626 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700627 }
628};
Gilles Peskine449bd832023-01-11 14:50:10 +0100629static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
630 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700631 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000632 /* Sample #1 */
633 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700634 },
635 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000636 /* Sample #2 */
637 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700638 },
639 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000640 /* Sample #3 */
641 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700642 },
643 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000644 /* Sample #4 */
645 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700646 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700648
Janos Follathcd13bd22016-12-13 11:51:04 +0000649/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700650static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000651 /* Key1 */
652 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
653 /* Key2 */
654 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
655 /* Key3 */
656 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700657};
658static const unsigned char des3_3key_subkeys[2][8] = {
659 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000660 /* K1 */
661 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700662 },
663 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000664 /* K2 */
665 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700666 }
667};
Gilles Peskine449bd832023-01-11 14:50:10 +0100668static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
669 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700670 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000671 /* Sample #1 */
672 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700673 },
674 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000675 /* Sample #2 */
676 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700677 },
678 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000679 /* Sample #3 */
680 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700681 },
682 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000683 /* Sample #4 */
684 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700685 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700687
Brian Murray0f6af732016-05-19 15:59:23 -0700688#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700689
Simon Butcher69283e52016-10-06 12:49:58 +0100690#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700691/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000692static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000693 /* Key */
694 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
695 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000696 0xed, 0xcb
697};
698
699/* Sizes in bytes */
700static const size_t PRFKlen[NB_PRF_TESTS] = {
701 18,
702 16,
703 10
704};
705
Janos Follathcd13bd22016-12-13 11:51:04 +0000706/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000707static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000708 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
709 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000710 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000711};
712
713static const unsigned char PRFT[NB_PRF_TESTS][16] = {
714 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000715 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
716 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000717 },
718 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000719 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
720 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000721 },
722 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000723 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
724 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000725 }
726};
Brian Murray0f6af732016-05-19 15:59:23 -0700727#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000728
Gilles Peskine449bd832023-01-11 14:50:10 +0100729static int cmac_test_subkeys(int verbose,
730 const char *testname,
731 const unsigned char *key,
732 int keybits,
733 const unsigned char *subkeys,
734 mbedtls_cipher_type_t cipher_type,
735 int block_size,
736 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100737{
Brian Murray2fab5c92016-12-15 18:51:13 -0800738 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100739 mbedtls_cipher_context_t ctx;
740 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200741 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
742 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
745 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100746 /* Failing at this point must be due to a build issue */
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100748 }
749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 for (i = 0; i < num_tests; i++) {
751 if (verbose != 0) {
752 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
753 }
Simon Butcher327398a2016-10-05 14:09:11 +0100754
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
758 if (verbose != 0) {
759 mbedtls_printf("test execution failed\n");
760 }
Simon Butcher327398a2016-10-05 14:09:11 +0100761
Janos Follathd4443582016-10-12 10:00:42 +0100762 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100763 }
764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
766 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100767 /* When CMAC is implemented by an alternative implementation, or
768 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100769 * AES-192 may be unavailable. This should not cause the selftest
770 * function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
772 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
773 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
774 if (verbose != 0) {
775 mbedtls_printf("skipped\n");
776 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100777 goto next_test;
778 }
779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 if (verbose != 0) {
781 mbedtls_printf("test execution failed\n");
782 }
Simon Butcher327398a2016-10-05 14:09:11 +0100783
Janos Follathd4443582016-10-12 10:00:42 +0100784 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100785 }
786
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 ret = cmac_generate_subkeys(&ctx, K1, K2);
788 if (ret != 0) {
789 if (verbose != 0) {
790 mbedtls_printf("failed\n");
791 }
Janos Follathd4443582016-10-12 10:00:42 +0100792
793 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100794 }
795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
797 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
798 if (verbose != 0) {
799 mbedtls_printf("failed\n");
800 }
Janos Follathd4443582016-10-12 10:00:42 +0100801
802 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100803 }
804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 if (verbose != 0) {
806 mbedtls_printf("passed\n");
807 }
Janos Follathd4443582016-10-12 10:00:42 +0100808
Steven Cooreman830d5af2021-01-08 18:01:46 +0100809next_test:
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100811 }
812
Gilles Peskinedf761d52018-03-01 22:18:14 +0100813 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100814 goto exit;
815
816cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100818
Janos Follathd4443582016-10-12 10:00:42 +0100819exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100821}
822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823static int cmac_test_wth_cipher(int verbose,
824 const char *testname,
825 const unsigned char *key,
826 int keybits,
827 const unsigned char *messages,
828 const unsigned int message_lengths[4],
829 const unsigned char *expected_result,
830 mbedtls_cipher_type_t cipher_type,
831 int block_size,
832 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700833{
Simon Butcher327398a2016-10-05 14:09:11 +0100834 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800835 int i, ret = 0;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200836 unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murray57863ad2016-05-19 16:38:36 -0700837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
839 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100840 /* Failing at this point must be due to a build issue */
841 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700842 goto exit;
843 }
844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 for (i = 0; i < num_tests; i++) {
846 if (verbose != 0) {
847 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
848 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
851 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100852 /* When CMAC is implemented by an alternative implementation, or
853 * the underlying primitive itself is implemented alternatively,
Steven Cooremand3679902021-02-15 13:42:35 +0100854 * AES-192 and/or 3DES may be unavailable. This should not cause
855 * the selftest function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
857 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
858 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
859 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
860 if (verbose != 0) {
861 mbedtls_printf("skipped\n");
862 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100863 continue;
864 }
865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 if (verbose != 0) {
867 mbedtls_printf("failed\n");
868 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700869 goto exit;
870 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
873 if (verbose != 0) {
874 mbedtls_printf("failed\n");
875 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700876 goto exit;
877 }
878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 if (verbose != 0) {
880 mbedtls_printf("passed\n");
881 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700882 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100883 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100884
Simon Butcher69283e52016-10-06 12:49:58 +0100885exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700887}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000888
Simon Butcher69283e52016-10-06 12:49:58 +0100889#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100890static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700891{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000892 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000893 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100894 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 for (i = 0; i < NB_PRF_TESTS; i++) {
897 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
898 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
899 if (ret != 0 ||
900 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 if (verbose != 0) {
903 mbedtls_printf("failed\n");
904 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 return ret;
907 } else if (verbose != 0) {
908 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700909 }
910 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700912}
913#endif /* MBEDTLS_AES_C */
914
Gilles Peskine449bd832023-01-11 14:50:10 +0100915int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700916{
Janos Follath24eed8d2019-11-22 13:21:35 +0000917 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100918
Simon Butcher69283e52016-10-06 12:49:58 +0100919#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100920 /* AES-128 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 if ((ret = cmac_test_subkeys(verbose,
922 "AES 128",
923 aes_128_key,
924 128,
925 (const unsigned char *) aes_128_subkeys,
926 MBEDTLS_CIPHER_AES_128_ECB,
927 MBEDTLS_AES_BLOCK_SIZE,
928 NB_CMAC_TESTS_PER_KEY)) != 0) {
929 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100930 }
931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 if ((ret = cmac_test_wth_cipher(verbose,
933 "AES 128",
934 aes_128_key,
935 128,
936 test_message,
937 aes_message_lengths,
938 (const unsigned char *) aes_128_expected_result,
939 MBEDTLS_CIPHER_AES_128_ECB,
940 MBEDTLS_AES_BLOCK_SIZE,
941 NB_CMAC_TESTS_PER_KEY)) != 0) {
942 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100943 }
944
945 /* AES-192 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800946#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 if ((ret = cmac_test_subkeys(verbose,
948 "AES 192",
949 aes_192_key,
950 192,
951 (const unsigned char *) aes_192_subkeys,
952 MBEDTLS_CIPHER_AES_192_ECB,
953 MBEDTLS_AES_BLOCK_SIZE,
954 NB_CMAC_TESTS_PER_KEY)) != 0) {
955 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700956 }
Brian Murray0f6af732016-05-19 15:59:23 -0700957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 if ((ret = cmac_test_wth_cipher(verbose,
959 "AES 192",
960 aes_192_key,
961 192,
962 test_message,
963 aes_message_lengths,
964 (const unsigned char *) aes_192_expected_result,
965 MBEDTLS_CIPHER_AES_192_ECB,
966 MBEDTLS_AES_BLOCK_SIZE,
967 NB_CMAC_TESTS_PER_KEY)) != 0) {
968 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100969 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800970#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Simon Butcher327398a2016-10-05 14:09:11 +0100971
972 /* AES-256 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800973#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 if ((ret = cmac_test_subkeys(verbose,
975 "AES 256",
976 aes_256_key,
977 256,
978 (const unsigned char *) aes_256_subkeys,
979 MBEDTLS_CIPHER_AES_256_ECB,
980 MBEDTLS_AES_BLOCK_SIZE,
981 NB_CMAC_TESTS_PER_KEY)) != 0) {
982 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700983 }
Brian Murray0f6af732016-05-19 15:59:23 -0700984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 if ((ret = cmac_test_wth_cipher(verbose,
986 "AES 256",
987 aes_256_key,
988 256,
989 test_message,
990 aes_message_lengths,
991 (const unsigned char *) aes_256_expected_result,
992 MBEDTLS_CIPHER_AES_256_ECB,
993 MBEDTLS_AES_BLOCK_SIZE,
994 NB_CMAC_TESTS_PER_KEY)) != 0) {
995 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700996 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800997#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700998#endif /* MBEDTLS_AES_C */
999
Simon Butcher69283e52016-10-06 12:49:58 +01001000#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001001 /* 3DES 2 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 if ((ret = cmac_test_subkeys(verbose,
1003 "3DES 2 key",
1004 des3_2key_key,
1005 192,
1006 (const unsigned char *) des3_2key_subkeys,
1007 MBEDTLS_CIPHER_DES_EDE3_ECB,
1008 MBEDTLS_DES3_BLOCK_SIZE,
1009 NB_CMAC_TESTS_PER_KEY)) != 0) {
1010 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001011 }
1012
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 if ((ret = cmac_test_wth_cipher(verbose,
1014 "3DES 2 key",
1015 des3_2key_key,
1016 192,
1017 test_message,
1018 des3_message_lengths,
1019 (const unsigned char *) des3_2key_expected_result,
1020 MBEDTLS_CIPHER_DES_EDE3_ECB,
1021 MBEDTLS_DES3_BLOCK_SIZE,
1022 NB_CMAC_TESTS_PER_KEY)) != 0) {
1023 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001024 }
Brian Murray0f6af732016-05-19 15:59:23 -07001025
Simon Butcher327398a2016-10-05 14:09:11 +01001026 /* 3DES 3 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 if ((ret = cmac_test_subkeys(verbose,
1028 "3DES 3 key",
1029 des3_3key_key,
1030 192,
1031 (const unsigned char *) des3_3key_subkeys,
1032 MBEDTLS_CIPHER_DES_EDE3_ECB,
1033 MBEDTLS_DES3_BLOCK_SIZE,
1034 NB_CMAC_TESTS_PER_KEY)) != 0) {
1035 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001036 }
1037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 if ((ret = cmac_test_wth_cipher(verbose,
1039 "3DES 3 key",
1040 des3_3key_key,
1041 192,
1042 test_message,
1043 des3_message_lengths,
1044 (const unsigned char *) des3_3key_expected_result,
1045 MBEDTLS_CIPHER_DES_EDE3_ECB,
1046 MBEDTLS_DES3_BLOCK_SIZE,
1047 NB_CMAC_TESTS_PER_KEY)) != 0) {
1048 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001049 }
Brian Murray0f6af732016-05-19 15:59:23 -07001050#endif /* MBEDTLS_DES_C */
1051
Simon Butcher69283e52016-10-06 12:49:58 +01001052#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1054 return ret;
1055 }
Brian Murray0f6af732016-05-19 15:59:23 -07001056#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 if (verbose != 0) {
1059 mbedtls_printf("\n");
1060 }
Brian Murray0f6af732016-05-19 15:59:23 -07001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001063}
1064
Brian Murray0f6af732016-05-19 15:59:23 -07001065#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001066
1067#endif /* MBEDTLS_CMAC_C */