blob: c4f0b5408f9670cf761708beeb744e9f045ed6cf [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;
Brian Murrayb0c3c432016-05-18 14:29:51 -070059 unsigned char R_n, mask;
Dave Rodgman7f86d352024-03-05 15:35:59 +000060 uint32_t overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010061 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070062
Gilles Peskine449bd832023-01-11 14:50:10 +010063 if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070064 R_n = R_128;
Dave Rodgman5ba2b2b2024-03-06 11:38:49 +000065 }
66#if defined(MBEDTLS_DES_C)
67 else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
68 const unsigned char R_64 = 0x1B;
Brian Murrayb0c3c432016-05-18 14:29:51 -070069 R_n = R_64;
Dave Rodgman5ba2b2b2024-03-06 11:38:49 +000070 }
71#endif
72 else {
Gilles Peskine449bd832023-01-11 14:50:10 +010073 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Brian Murrayb0c3c432016-05-18 14:29:51 -070074 }
75
Dave Rodgman7f86d352024-03-05 15:35:59 +000076 for (i = (int) blocksize - 4; i >= 0; i -= 4) {
77 uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
78 uint32_t new_overflow = i32 >> 31;
79 i32 = (i32 << 1) | overflow;
80 MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
81 overflow = new_overflow;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000082 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000083
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000084 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
85 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +010086
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000087 /* MSVC has a warning about unary minus on unsigned, but this is
88 * well-defined and precisely what we want to do here */
89#if defined(_MSC_VER)
90#pragma warning( push )
91#pragma warning( disable : 4146 )
92#endif
Gilles Peskine449bd832023-01-11 14:50:10 +010093 mask = -(input[0] >> 7);
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000094#if defined(_MSC_VER)
95#pragma warning( pop )
96#endif
97
Gilles Peskine449bd832023-01-11 14:50:10 +010098 output[blocksize - 1] ^= R_n & mask;
Simon Butcher327398a2016-10-05 14:09:11 +010099
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000101}
102
103/*
104 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +0100105 *
106 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000107 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100108static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
109 unsigned char *K1, unsigned char *K2)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000110{
Janos Follath24eed8d2019-11-22 13:21:35 +0000111 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200112 unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700113 size_t olen, block_size;
114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 mbedtls_platform_zeroize(L, sizeof(L));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700116
Dave Rodgman85a88132023-06-24 11:41:50 +0100117 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100118
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000119 /* Calculate Ek(0) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700121 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000123
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000124 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000125 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000126 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700128 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100132 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 }
Simon Butcher327398a2016-10-05 14:09:11 +0100134
135exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 mbedtls_platform_zeroize(L, sizeof(L));
Simon Butcher327398a2016-10-05 14:09:11 +0100137
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000139}
Ron Eldor621080d2017-12-21 10:57:43 +0200140#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000141
Ron Eldor621080d2017-12-21 10:57:43 +0200142#if !defined(MBEDTLS_CMAC_ALT)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000143
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000144/*
145 * Create padded last block from (partial) last block.
146 *
147 * We can't use the padding option from the cipher layer, as it only works for
148 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
149 */
Gilles Peskine9e930e22023-06-14 17:52:54 +0200150static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 size_t padded_block_len,
152 const unsigned char *last_block,
153 size_t last_block_len)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000154{
155 size_t j;
156
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 for (j = 0; j < padded_block_len; j++) {
158 if (j < last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000159 padded_block[j] = last_block[j];
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 } else if (j == last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000161 padded_block[j] = 0x80;
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 } else {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000163 padded_block[j] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000165 }
166}
167
Gilles Peskine449bd832023-01-11 14:50:10 +0100168int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
169 const unsigned char *key, size_t keybits)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000170{
Simon Butcher327398a2016-10-05 14:09:11 +0100171 mbedtls_cipher_type_t type;
172 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100173 int retval;
174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
176 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
177 }
Simon Butcher327398a2016-10-05 14:09:11 +0100178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
180 MBEDTLS_ENCRYPT)) != 0) {
181 return retval;
182 }
Simon Butcher327398a2016-10-05 14:09:11 +0100183
Dave Rodgman2e8f6aa2023-06-24 17:32:18 +0100184 type = mbedtls_cipher_info_get_type(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 switch (type) {
Simon Butcher327398a2016-10-05 14:09:11 +0100187 case MBEDTLS_CIPHER_AES_128_ECB:
188 case MBEDTLS_CIPHER_AES_192_ECB:
189 case MBEDTLS_CIPHER_AES_256_ECB:
190 case MBEDTLS_CIPHER_DES_EDE3_ECB:
191 break;
192 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Simon Butcher327398a2016-10-05 14:09:11 +0100194 }
195
196 /* Allocated and initialise in the cipher context memory for the CMAC
197 * context */
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
199 if (cmac_ctx == NULL) {
200 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
201 }
Simon Butcher327398a2016-10-05 14:09:11 +0100202
203 ctx->cmac_ctx = cmac_ctx;
204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
Simon Butcher327398a2016-10-05 14:09:11 +0100206
207 return 0;
208}
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
211 const unsigned char *input, size_t ilen)
Simon Butcher327398a2016-10-05 14:09:11 +0100212{
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 mbedtls_cmac_context_t *cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700214 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000215 int ret = 0;
216 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
219 ctx->cmac_ctx == NULL) {
220 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
221 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700222
Simon Butcher327398a2016-10-05 14:09:11 +0100223 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100224 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100225 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000226
Dave Rodgman4faa34d2024-03-12 16:34:43 +0000227 /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form
228 * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */
229 MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE);
230
Simon Butcher6b0774a2016-10-10 21:37:42 +0100231 /* Is there data still to process from the last call, that's greater in
232 * size than a block? */
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 if (cmac_ctx->unprocessed_len > 0 &&
234 ilen > block_size - cmac_ctx->unprocessed_len) {
235 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
236 input,
237 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100238
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100239 mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100240
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
242 &olen)) != 0) {
243 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100244 }
245
Simon Butcher6b0774a2016-10-10 21:37:42 +0100246 input += block_size - cmac_ctx->unprocessed_len;
247 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100248 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700249 }
250
Simon Butcher327398a2016-10-05 14:09:11 +0100251 /* n is the number of blocks including any final partial block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100253
Simon B3249cb72016-11-03 01:11:37 +0000254 /* Iterate across the input data in block sized chunks, excluding any
255 * final partial or complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 for (j = 1; j < n; j++) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100257 mbedtls_xor_no_simd(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
260 &olen)) != 0) {
261 goto exit;
262 }
Simon Butcher327398a2016-10-05 14:09:11 +0100263
264 ilen -= block_size;
265 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700266 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000267
Simon Butcher327398a2016-10-05 14:09:11 +0100268 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 if (ilen > 0) {
270 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
271 input,
272 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100273 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100274 }
275
276exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100278}
279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
281 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100282{
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100284 unsigned char *state, *last_block;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200285 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
286 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
287 unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Janos Follath24eed8d2019-11-22 13:21:35 +0000288 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100289 size_t olen, block_size;
290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
292 output == NULL) {
293 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
294 }
Simon Butcher327398a2016-10-05 14:09:11 +0100295
296 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100297 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Dave Rodgman4faa34d2024-03-12 16:34:43 +0000298 MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning
Simon Butcher327398a2016-10-05 14:09:11 +0100299 state = cmac_ctx->state;
300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 mbedtls_platform_zeroize(K1, sizeof(K1));
302 mbedtls_platform_zeroize(K2, sizeof(K2));
303 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100304
Simon Butcher69283e52016-10-06 12:49:58 +0100305 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000306
307 /* Calculate last block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 if (cmac_ctx->unprocessed_len < block_size) {
309 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
310 mbedtls_xor(M_last, M_last, K2, block_size);
311 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000312 /* Last block is complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 mbedtls_xor(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000314 }
315
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 mbedtls_xor(state, M_last, state, block_size);
318 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
319 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100320 goto exit;
321 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100324
325exit:
326 /* Wipe the generated keys on the stack, and any other transients to avoid
327 * side channel leakage */
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 mbedtls_platform_zeroize(K1, sizeof(K1));
329 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100330
331 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
333 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100334
Gilles Peskine9e930e22023-06-14 17:52:54 +0200335 mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000337}
338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000340{
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
344 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
345 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700346
Simon Butcher327398a2016-10-05 14:09:11 +0100347 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000348
Simon Butcher327398a2016-10-05 14:09:11 +0100349 /* Reset the internal state */
350 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
352 sizeof(cmac_ctx->unprocessed_block));
353 mbedtls_platform_zeroize(cmac_ctx->state,
354 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000357}
358
Gilles Peskine449bd832023-01-11 14:50:10 +0100359int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
360 const unsigned char *key, size_t keylen,
361 const unsigned char *input, size_t ilen,
362 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100363{
364 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000365 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
368 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
369 }
Simon Butcher327398a2016-10-05 14:09:11 +0100370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100374 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 }
Simon Butcher327398a2016-10-05 14:09:11 +0100376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
378 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100379 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 }
Simon Butcher327398a2016-10-05 14:09:11 +0100381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
383 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100384 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 }
Simon Butcher327398a2016-10-05 14:09:11 +0100386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 ret = mbedtls_cipher_cmac_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100388
389exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100393}
Simon Butcher327398a2016-10-05 14:09:11 +0100394
Simon Butcher69283e52016-10-06 12:49:58 +0100395#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000396/*
Simon Butcher69283e52016-10-06 12:49:58 +0100397 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000398 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100399int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
400 const unsigned char *input, size_t in_len,
401 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000402{
Janos Follath24eed8d2019-11-22 13:21:35 +0000403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100404 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100405 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
406 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 if (key == NULL || input == NULL || output == NULL) {
409 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
410 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
413 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100414 /* Failing at this point must be due to a build issue */
415 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
416 goto exit;
417 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000420 /* Use key as is */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
422 } else {
423 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
426 key_length, int_key);
427 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700428 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000430 }
431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
433 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000434
Simon Butcher327398a2016-10-05 14:09:11 +0100435exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000439}
Brian Murrayb439d452016-05-19 16:02:42 -0700440#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000441
Steven Cooreman63342772017-04-04 11:47:16 +0200442#endif /* !MBEDTLS_CMAC_ALT */
443
Simon Butcher69283e52016-10-06 12:49:58 +0100444#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000445/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000446 * CMAC test data for SP800-38B
447 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
448 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700449 *
450 * AES-CMAC-PRF-128 test data from RFC 4615
451 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000452 */
453
Brian Murray0f6af732016-05-19 15:59:23 -0700454#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000455#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100456
Brian Murray0f6af732016-05-19 15:59:23 -0700457#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
458/* All CMAC test inputs are truncated from the same 64 byte buffer. */
459static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000460 /* PT */
461 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
462 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
463 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
464 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
465 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
466 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
467 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
468 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000469};
Simon Butcher69283e52016-10-06 12:49:58 +0100470#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700471
Simon Butcher69283e52016-10-06 12:49:58 +0100472#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700473/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700474static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000475 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700476 0,
477 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000478 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700479 64
480};
481
Janos Follathcd13bd22016-12-13 11:51:04 +0000482/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700483static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000484 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
485 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700486};
Simon Butcher69283e52016-10-06 12:49:58 +0100487static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700488 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000489 /* K1 */
490 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
491 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700492 },
493 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000494 /* K2 */
495 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
496 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700497 }
498};
Gilles Peskine449bd832023-01-11 14:50:10 +0100499static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
500{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000501 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000502 /* Example #1 */
503 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
504 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000505 },
506 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000507 /* Example #2 */
508 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
509 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000510 },
511 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000512 /* Example #3 */
513 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
514 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000515 },
516 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000517 /* Example #4 */
518 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
519 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000520 }
521};
522
Janos Follathcd13bd22016-12-13 11:51:04 +0000523/* CMAC-AES192 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800524#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700525static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000526 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
527 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
528 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000529};
Simon Butcher69283e52016-10-06 12:49:58 +0100530static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700531 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000532 /* K1 */
533 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
534 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700535 },
536 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000537 /* K2 */
538 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
539 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700540 }
541};
Gilles Peskine449bd832023-01-11 14:50:10 +0100542static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
543{
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};
Yanray Wangdd56add2023-05-11 13:53:46 +0800565#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700566
Janos Follathcd13bd22016-12-13 11:51:04 +0000567/* CMAC-AES256 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800568#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700569static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000570 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
571 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
572 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
573 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700574};
Simon Butcher69283e52016-10-06 12:49:58 +0100575static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700576 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000577 /* K1 */
578 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
579 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700580 },
581 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000582 /* K2 */
583 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
584 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700585 }
586};
Gilles Peskine449bd832023-01-11 14:50:10 +0100587static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
588{
Brian Murray0f6af732016-05-19 15:59:23 -0700589 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000590 /* Example #1 */
591 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
592 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700593 },
594 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000595 /* Example #2 */
596 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
597 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700598 },
599 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000600 /* Example #3 */
601 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
602 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700603 },
604 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000605 /* Example #4 */
606 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
607 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700608 }
609};
Yanray Wangdd56add2023-05-11 13:53:46 +0800610#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700611#endif /* MBEDTLS_AES_C */
612
Simon Butcher69283e52016-10-06 12:49:58 +0100613#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700614/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700615static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700616 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000617 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700618 20,
619 32
620};
621
Janos Follathcd13bd22016-12-13 11:51:04 +0000622/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700623static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000624 /* Key1 */
625 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
626 /* Key2 */
627 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
628 /* Key3 */
629 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700630};
631static const unsigned char des3_2key_subkeys[2][8] = {
632 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000633 /* K1 */
634 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700635 },
636 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000637 /* K2 */
638 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700639 }
640};
Gilles Peskine449bd832023-01-11 14:50:10 +0100641static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
642 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700643 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000644 /* Sample #1 */
645 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700646 },
647 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000648 /* Sample #2 */
649 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700650 },
651 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000652 /* Sample #3 */
653 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700654 },
655 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000656 /* Sample #4 */
657 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700658 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700660
Janos Follathcd13bd22016-12-13 11:51:04 +0000661/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700662static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000663 /* Key1 */
664 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
665 /* Key2 */
666 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
667 /* Key3 */
668 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700669};
670static const unsigned char des3_3key_subkeys[2][8] = {
671 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000672 /* K1 */
673 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700674 },
675 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000676 /* K2 */
677 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700678 }
679};
Gilles Peskine449bd832023-01-11 14:50:10 +0100680static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
681 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700682 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000683 /* Sample #1 */
684 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700685 },
686 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000687 /* Sample #2 */
688 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700689 },
690 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000691 /* Sample #3 */
692 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700693 },
694 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000695 /* Sample #4 */
696 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700697 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700699
Brian Murray0f6af732016-05-19 15:59:23 -0700700#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700701
Simon Butcher69283e52016-10-06 12:49:58 +0100702#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700703/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000704static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000705 /* Key */
706 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
707 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000708 0xed, 0xcb
709};
710
711/* Sizes in bytes */
712static const size_t PRFKlen[NB_PRF_TESTS] = {
713 18,
714 16,
715 10
716};
717
Janos Follathcd13bd22016-12-13 11:51:04 +0000718/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000719static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000720 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
721 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000722 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000723};
724
725static const unsigned char PRFT[NB_PRF_TESTS][16] = {
726 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000727 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
728 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000729 },
730 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000731 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
732 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000733 },
734 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000735 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
736 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000737 }
738};
Brian Murray0f6af732016-05-19 15:59:23 -0700739#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741static int cmac_test_subkeys(int verbose,
742 const char *testname,
743 const unsigned char *key,
744 int keybits,
745 const unsigned char *subkeys,
746 mbedtls_cipher_type_t cipher_type,
747 int block_size,
748 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100749{
Brian Murray2fab5c92016-12-15 18:51:13 -0800750 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100751 mbedtls_cipher_context_t ctx;
752 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200753 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
754 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100755
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
757 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100758 /* Failing at this point must be due to a build issue */
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100760 }
761
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 for (i = 0; i < num_tests; i++) {
763 if (verbose != 0) {
764 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
765 }
Simon Butcher327398a2016-10-05 14:09:11 +0100766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
770 if (verbose != 0) {
771 mbedtls_printf("test execution failed\n");
772 }
Simon Butcher327398a2016-10-05 14:09:11 +0100773
Janos Follathd4443582016-10-12 10:00:42 +0100774 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100775 }
776
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
778 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100779 /* When CMAC is implemented by an alternative implementation, or
780 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100781 * AES-192 may be unavailable. This should not cause the selftest
782 * function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
784 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
785 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
786 if (verbose != 0) {
787 mbedtls_printf("skipped\n");
788 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100789 goto next_test;
790 }
791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 if (verbose != 0) {
793 mbedtls_printf("test execution failed\n");
794 }
Simon Butcher327398a2016-10-05 14:09:11 +0100795
Janos Follathd4443582016-10-12 10:00:42 +0100796 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100797 }
798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 ret = cmac_generate_subkeys(&ctx, K1, K2);
800 if (ret != 0) {
801 if (verbose != 0) {
802 mbedtls_printf("failed\n");
803 }
Janos Follathd4443582016-10-12 10:00:42 +0100804
805 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100806 }
807
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
809 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
810 if (verbose != 0) {
811 mbedtls_printf("failed\n");
812 }
Janos Follathd4443582016-10-12 10:00:42 +0100813
814 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100815 }
816
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 if (verbose != 0) {
818 mbedtls_printf("passed\n");
819 }
Janos Follathd4443582016-10-12 10:00:42 +0100820
Steven Cooreman830d5af2021-01-08 18:01:46 +0100821next_test:
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100823 }
824
Gilles Peskinedf761d52018-03-01 22:18:14 +0100825 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100826 goto exit;
827
828cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100830
Janos Follathd4443582016-10-12 10:00:42 +0100831exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100833}
834
Gilles Peskine449bd832023-01-11 14:50:10 +0100835static int cmac_test_wth_cipher(int verbose,
836 const char *testname,
837 const unsigned char *key,
838 int keybits,
839 const unsigned char *messages,
840 const unsigned int message_lengths[4],
841 const unsigned char *expected_result,
842 mbedtls_cipher_type_t cipher_type,
843 int block_size,
844 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700845{
Simon Butcher327398a2016-10-05 14:09:11 +0100846 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800847 int i, ret = 0;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200848 unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murray57863ad2016-05-19 16:38:36 -0700849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
851 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100852 /* Failing at this point must be due to a build issue */
853 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700854 goto exit;
855 }
856
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 for (i = 0; i < num_tests; i++) {
858 if (verbose != 0) {
859 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
860 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
863 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100864 /* When CMAC is implemented by an alternative implementation, or
865 * the underlying primitive itself is implemented alternatively,
Steven Cooremand3679902021-02-15 13:42:35 +0100866 * AES-192 and/or 3DES may be unavailable. This should not cause
867 * the selftest function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
869 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
870 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
871 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
872 if (verbose != 0) {
873 mbedtls_printf("skipped\n");
874 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100875 continue;
876 }
877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 if (verbose != 0) {
879 mbedtls_printf("failed\n");
880 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700881 goto exit;
882 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
885 if (verbose != 0) {
886 mbedtls_printf("failed\n");
887 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700888 goto exit;
889 }
890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 if (verbose != 0) {
892 mbedtls_printf("passed\n");
893 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700894 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100895 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100896
Simon Butcher69283e52016-10-06 12:49:58 +0100897exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700899}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000900
Simon Butcher69283e52016-10-06 12:49:58 +0100901#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100902static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700903{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000904 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000905 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100906 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 for (i = 0; i < NB_PRF_TESTS; i++) {
909 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
910 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
911 if (ret != 0 ||
912 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 if (verbose != 0) {
915 mbedtls_printf("failed\n");
916 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 return ret;
919 } else if (verbose != 0) {
920 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700921 }
922 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700924}
925#endif /* MBEDTLS_AES_C */
926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700928{
Janos Follath24eed8d2019-11-22 13:21:35 +0000929 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100930
Simon Butcher69283e52016-10-06 12:49:58 +0100931#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100932 /* AES-128 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 if ((ret = cmac_test_subkeys(verbose,
934 "AES 128",
935 aes_128_key,
936 128,
937 (const unsigned char *) aes_128_subkeys,
938 MBEDTLS_CIPHER_AES_128_ECB,
939 MBEDTLS_AES_BLOCK_SIZE,
940 NB_CMAC_TESTS_PER_KEY)) != 0) {
941 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100942 }
943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 if ((ret = cmac_test_wth_cipher(verbose,
945 "AES 128",
946 aes_128_key,
947 128,
948 test_message,
949 aes_message_lengths,
950 (const unsigned char *) aes_128_expected_result,
951 MBEDTLS_CIPHER_AES_128_ECB,
952 MBEDTLS_AES_BLOCK_SIZE,
953 NB_CMAC_TESTS_PER_KEY)) != 0) {
954 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100955 }
956
957 /* AES-192 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800958#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 if ((ret = cmac_test_subkeys(verbose,
960 "AES 192",
961 aes_192_key,
962 192,
963 (const unsigned char *) aes_192_subkeys,
964 MBEDTLS_CIPHER_AES_192_ECB,
965 MBEDTLS_AES_BLOCK_SIZE,
966 NB_CMAC_TESTS_PER_KEY)) != 0) {
967 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700968 }
Brian Murray0f6af732016-05-19 15:59:23 -0700969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 if ((ret = cmac_test_wth_cipher(verbose,
971 "AES 192",
972 aes_192_key,
973 192,
974 test_message,
975 aes_message_lengths,
976 (const unsigned char *) aes_192_expected_result,
977 MBEDTLS_CIPHER_AES_192_ECB,
978 MBEDTLS_AES_BLOCK_SIZE,
979 NB_CMAC_TESTS_PER_KEY)) != 0) {
980 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100981 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800982#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Simon Butcher327398a2016-10-05 14:09:11 +0100983
984 /* AES-256 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800985#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 if ((ret = cmac_test_subkeys(verbose,
987 "AES 256",
988 aes_256_key,
989 256,
990 (const unsigned char *) aes_256_subkeys,
991 MBEDTLS_CIPHER_AES_256_ECB,
992 MBEDTLS_AES_BLOCK_SIZE,
993 NB_CMAC_TESTS_PER_KEY)) != 0) {
994 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700995 }
Brian Murray0f6af732016-05-19 15:59:23 -0700996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 if ((ret = cmac_test_wth_cipher(verbose,
998 "AES 256",
999 aes_256_key,
1000 256,
1001 test_message,
1002 aes_message_lengths,
1003 (const unsigned char *) aes_256_expected_result,
1004 MBEDTLS_CIPHER_AES_256_ECB,
1005 MBEDTLS_AES_BLOCK_SIZE,
1006 NB_CMAC_TESTS_PER_KEY)) != 0) {
1007 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001008 }
Yanray Wangdd56add2023-05-11 13:53:46 +08001009#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -07001010#endif /* MBEDTLS_AES_C */
1011
Simon Butcher69283e52016-10-06 12:49:58 +01001012#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001013 /* 3DES 2 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 if ((ret = cmac_test_subkeys(verbose,
1015 "3DES 2 key",
1016 des3_2key_key,
1017 192,
1018 (const unsigned char *) des3_2key_subkeys,
1019 MBEDTLS_CIPHER_DES_EDE3_ECB,
1020 MBEDTLS_DES3_BLOCK_SIZE,
1021 NB_CMAC_TESTS_PER_KEY)) != 0) {
1022 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001023 }
1024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 if ((ret = cmac_test_wth_cipher(verbose,
1026 "3DES 2 key",
1027 des3_2key_key,
1028 192,
1029 test_message,
1030 des3_message_lengths,
1031 (const unsigned char *) des3_2key_expected_result,
1032 MBEDTLS_CIPHER_DES_EDE3_ECB,
1033 MBEDTLS_DES3_BLOCK_SIZE,
1034 NB_CMAC_TESTS_PER_KEY)) != 0) {
1035 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001036 }
Brian Murray0f6af732016-05-19 15:59:23 -07001037
Simon Butcher327398a2016-10-05 14:09:11 +01001038 /* 3DES 3 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 if ((ret = cmac_test_subkeys(verbose,
1040 "3DES 3 key",
1041 des3_3key_key,
1042 192,
1043 (const unsigned char *) des3_3key_subkeys,
1044 MBEDTLS_CIPHER_DES_EDE3_ECB,
1045 MBEDTLS_DES3_BLOCK_SIZE,
1046 NB_CMAC_TESTS_PER_KEY)) != 0) {
1047 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001048 }
1049
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 if ((ret = cmac_test_wth_cipher(verbose,
1051 "3DES 3 key",
1052 des3_3key_key,
1053 192,
1054 test_message,
1055 des3_message_lengths,
1056 (const unsigned char *) des3_3key_expected_result,
1057 MBEDTLS_CIPHER_DES_EDE3_ECB,
1058 MBEDTLS_DES3_BLOCK_SIZE,
1059 NB_CMAC_TESTS_PER_KEY)) != 0) {
1060 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001061 }
Brian Murray0f6af732016-05-19 15:59:23 -07001062#endif /* MBEDTLS_DES_C */
1063
Simon Butcher69283e52016-10-06 12:49:58 +01001064#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1066 return ret;
1067 }
Brian Murray0f6af732016-05-19 15:59:23 -07001068#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 if (verbose != 0) {
1071 mbedtls_printf("\n");
1072 }
Brian Murray0f6af732016-05-19 15:59:23 -07001073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001075}
1076
Brian Murray0f6af732016-05-19 15:59:23 -07001077#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001078
1079#endif /* MBEDTLS_CMAC_C */