blob: cd3bd3ae4093ac54909e0c05ddda9568035545ba [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
Simon Butcher6b0774a2016-10-10 21:37:42 +0100227 /* Is there data still to process from the last call, that's greater in
228 * size than a block? */
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 if (cmac_ctx->unprocessed_len > 0 &&
230 ilen > block_size - cmac_ctx->unprocessed_len) {
231 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
232 input,
233 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100234
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100235 mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
238 &olen)) != 0) {
239 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100240 }
241
Simon Butcher6b0774a2016-10-10 21:37:42 +0100242 input += block_size - cmac_ctx->unprocessed_len;
243 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100244 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700245 }
246
Simon Butcher327398a2016-10-05 14:09:11 +0100247 /* n is the number of blocks including any final partial block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100249
Simon B3249cb72016-11-03 01:11:37 +0000250 /* Iterate across the input data in block sized chunks, excluding any
251 * final partial or complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 for (j = 1; j < n; j++) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100253 mbedtls_xor_no_simd(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
256 &olen)) != 0) {
257 goto exit;
258 }
Simon Butcher327398a2016-10-05 14:09:11 +0100259
260 ilen -= block_size;
261 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700262 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000263
Simon Butcher327398a2016-10-05 14:09:11 +0100264 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 if (ilen > 0) {
266 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
267 input,
268 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100269 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100270 }
271
272exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100274}
275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
277 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100278{
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100280 unsigned char *state, *last_block;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200281 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
282 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
283 unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Janos Follath24eed8d2019-11-22 13:21:35 +0000284 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100285 size_t olen, block_size;
286
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
288 output == NULL) {
289 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
290 }
Simon Butcher327398a2016-10-05 14:09:11 +0100291
292 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100293 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100294 state = cmac_ctx->state;
295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 mbedtls_platform_zeroize(K1, sizeof(K1));
297 mbedtls_platform_zeroize(K2, sizeof(K2));
298 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100299
Simon Butcher69283e52016-10-06 12:49:58 +0100300 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000301
302 /* Calculate last block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 if (cmac_ctx->unprocessed_len < block_size) {
304 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
305 mbedtls_xor(M_last, M_last, K2, block_size);
306 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000307 /* Last block is complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 mbedtls_xor(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000309 }
310
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 mbedtls_xor(state, M_last, state, block_size);
313 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
314 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100315 goto exit;
316 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000317
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100319
320exit:
321 /* Wipe the generated keys on the stack, and any other transients to avoid
322 * side channel leakage */
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 mbedtls_platform_zeroize(K1, sizeof(K1));
324 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100325
326 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
328 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100329
Gilles Peskine9e930e22023-06-14 17:52:54 +0200330 mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000332}
333
Gilles Peskine449bd832023-01-11 14:50:10 +0100334int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000335{
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
339 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
340 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700341
Simon Butcher327398a2016-10-05 14:09:11 +0100342 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000343
Simon Butcher327398a2016-10-05 14:09:11 +0100344 /* Reset the internal state */
345 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
347 sizeof(cmac_ctx->unprocessed_block));
348 mbedtls_platform_zeroize(cmac_ctx->state,
349 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000350
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000352}
353
Gilles Peskine449bd832023-01-11 14:50:10 +0100354int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
355 const unsigned char *key, size_t keylen,
356 const unsigned char *input, size_t ilen,
357 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100358{
359 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000360 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
363 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
364 }
Simon Butcher327398a2016-10-05 14:09:11 +0100365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100367
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100369 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 }
Simon Butcher327398a2016-10-05 14:09:11 +0100371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
373 if (ret != 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_update(&ctx, input, ilen);
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_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100383
384exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100388}
Simon Butcher327398a2016-10-05 14:09:11 +0100389
Simon Butcher69283e52016-10-06 12:49:58 +0100390#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000391/*
Simon Butcher69283e52016-10-06 12:49:58 +0100392 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000393 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
395 const unsigned char *input, size_t in_len,
396 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000397{
Janos Follath24eed8d2019-11-22 13:21:35 +0000398 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100399 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100400 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
401 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 if (key == NULL || input == NULL || output == NULL) {
404 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
405 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
408 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100409 /* Failing at this point must be due to a build issue */
410 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
411 goto exit;
412 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000415 /* Use key as is */
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
417 } else {
418 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
421 key_length, int_key);
422 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700423 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000425 }
426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
428 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000429
Simon Butcher327398a2016-10-05 14:09:11 +0100430exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000434}
Brian Murrayb439d452016-05-19 16:02:42 -0700435#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000436
Steven Cooreman63342772017-04-04 11:47:16 +0200437#endif /* !MBEDTLS_CMAC_ALT */
438
Simon Butcher69283e52016-10-06 12:49:58 +0100439#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000440/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000441 * CMAC test data for SP800-38B
442 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
443 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700444 *
445 * AES-CMAC-PRF-128 test data from RFC 4615
446 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000447 */
448
Brian Murray0f6af732016-05-19 15:59:23 -0700449#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000450#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100451
Brian Murray0f6af732016-05-19 15:59:23 -0700452#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
453/* All CMAC test inputs are truncated from the same 64 byte buffer. */
454static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000455 /* PT */
456 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
457 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
458 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
459 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
460 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
461 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
462 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
463 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000464};
Simon Butcher69283e52016-10-06 12:49:58 +0100465#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700466
Simon Butcher69283e52016-10-06 12:49:58 +0100467#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700468/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700469static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000470 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700471 0,
472 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000473 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700474 64
475};
476
Janos Follathcd13bd22016-12-13 11:51:04 +0000477/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700478static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000479 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
480 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700481};
Simon Butcher69283e52016-10-06 12:49:58 +0100482static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700483 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000484 /* K1 */
485 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
486 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700487 },
488 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000489 /* K2 */
490 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
491 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700492 }
493};
Gilles Peskine449bd832023-01-11 14:50:10 +0100494static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
495{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000496 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000497 /* Example #1 */
498 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
499 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000500 },
501 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000502 /* Example #2 */
503 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
504 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000505 },
506 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000507 /* Example #3 */
508 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
509 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000510 },
511 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000512 /* Example #4 */
513 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
514 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000515 }
516};
517
Janos Follathcd13bd22016-12-13 11:51:04 +0000518/* CMAC-AES192 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800519#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700520static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000521 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
522 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
523 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000524};
Simon Butcher69283e52016-10-06 12:49:58 +0100525static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700526 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000527 /* K1 */
528 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
529 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700530 },
531 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000532 /* K2 */
533 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
534 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700535 }
536};
Gilles Peskine449bd832023-01-11 14:50:10 +0100537static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
538{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700539 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000540 /* Example #1 */
541 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
542 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700543 },
544 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000545 /* Example #2 */
546 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
547 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700548 },
549 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000550 /* Example #3 */
551 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
552 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700553 },
554 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000555 /* Example #4 */
556 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
557 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700558 }
559};
Yanray Wangdd56add2023-05-11 13:53:46 +0800560#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700561
Janos Follathcd13bd22016-12-13 11:51:04 +0000562/* CMAC-AES256 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800563#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700564static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000565 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
566 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
567 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
568 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700569};
Simon Butcher69283e52016-10-06 12:49:58 +0100570static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700571 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000572 /* K1 */
573 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
574 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700575 },
576 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000577 /* K2 */
578 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
579 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700580 }
581};
Gilles Peskine449bd832023-01-11 14:50:10 +0100582static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
583{
Brian Murray0f6af732016-05-19 15:59:23 -0700584 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000585 /* Example #1 */
586 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
587 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700588 },
589 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000590 /* Example #2 */
591 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
592 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700593 },
594 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000595 /* Example #3 */
596 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
597 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700598 },
599 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000600 /* Example #4 */
601 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
602 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700603 }
604};
Yanray Wangdd56add2023-05-11 13:53:46 +0800605#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700606#endif /* MBEDTLS_AES_C */
607
Simon Butcher69283e52016-10-06 12:49:58 +0100608#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700609/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700610static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700611 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000612 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700613 20,
614 32
615};
616
Janos Follathcd13bd22016-12-13 11:51:04 +0000617/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700618static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000619 /* Key1 */
620 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
621 /* Key2 */
622 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
623 /* Key3 */
624 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700625};
626static const unsigned char des3_2key_subkeys[2][8] = {
627 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000628 /* K1 */
629 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700630 },
631 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000632 /* K2 */
633 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700634 }
635};
Gilles Peskine449bd832023-01-11 14:50:10 +0100636static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
637 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700638 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000639 /* Sample #1 */
640 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700641 },
642 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000643 /* Sample #2 */
644 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700645 },
646 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000647 /* Sample #3 */
648 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700649 },
650 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000651 /* Sample #4 */
652 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700653 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700655
Janos Follathcd13bd22016-12-13 11:51:04 +0000656/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700657static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000658 /* Key1 */
659 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
660 /* Key2 */
661 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
662 /* Key3 */
663 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700664};
665static const unsigned char des3_3key_subkeys[2][8] = {
666 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000667 /* K1 */
668 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700669 },
670 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000671 /* K2 */
672 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700673 }
674};
Gilles Peskine449bd832023-01-11 14:50:10 +0100675static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
676 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700677 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000678 /* Sample #1 */
679 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700680 },
681 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000682 /* Sample #2 */
683 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700684 },
685 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000686 /* Sample #3 */
687 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700688 },
689 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000690 /* Sample #4 */
691 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700692 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700694
Brian Murray0f6af732016-05-19 15:59:23 -0700695#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700696
Simon Butcher69283e52016-10-06 12:49:58 +0100697#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700698/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000699static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000700 /* Key */
701 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
702 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000703 0xed, 0xcb
704};
705
706/* Sizes in bytes */
707static const size_t PRFKlen[NB_PRF_TESTS] = {
708 18,
709 16,
710 10
711};
712
Janos Follathcd13bd22016-12-13 11:51:04 +0000713/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000714static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000715 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
716 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000717 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000718};
719
720static const unsigned char PRFT[NB_PRF_TESTS][16] = {
721 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000722 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
723 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000724 },
725 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000726 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
727 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000728 },
729 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000730 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
731 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000732 }
733};
Brian Murray0f6af732016-05-19 15:59:23 -0700734#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736static int cmac_test_subkeys(int verbose,
737 const char *testname,
738 const unsigned char *key,
739 int keybits,
740 const unsigned char *subkeys,
741 mbedtls_cipher_type_t cipher_type,
742 int block_size,
743 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100744{
Brian Murray2fab5c92016-12-15 18:51:13 -0800745 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100746 mbedtls_cipher_context_t ctx;
747 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200748 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
749 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
752 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100753 /* Failing at this point must be due to a build issue */
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100755 }
756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 for (i = 0; i < num_tests; i++) {
758 if (verbose != 0) {
759 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
760 }
Simon Butcher327398a2016-10-05 14:09:11 +0100761
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100763
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
765 if (verbose != 0) {
766 mbedtls_printf("test execution failed\n");
767 }
Simon Butcher327398a2016-10-05 14:09:11 +0100768
Janos Follathd4443582016-10-12 10:00:42 +0100769 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100770 }
771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
773 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100774 /* When CMAC is implemented by an alternative implementation, or
775 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100776 * AES-192 may be unavailable. This should not cause the selftest
777 * function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
779 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
780 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
781 if (verbose != 0) {
782 mbedtls_printf("skipped\n");
783 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100784 goto next_test;
785 }
786
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 if (verbose != 0) {
788 mbedtls_printf("test execution failed\n");
789 }
Simon Butcher327398a2016-10-05 14:09:11 +0100790
Janos Follathd4443582016-10-12 10:00:42 +0100791 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100792 }
793
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 ret = cmac_generate_subkeys(&ctx, K1, K2);
795 if (ret != 0) {
796 if (verbose != 0) {
797 mbedtls_printf("failed\n");
798 }
Janos Follathd4443582016-10-12 10:00:42 +0100799
800 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100801 }
802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
804 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
805 if (verbose != 0) {
806 mbedtls_printf("failed\n");
807 }
Janos Follathd4443582016-10-12 10:00:42 +0100808
809 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100810 }
811
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 if (verbose != 0) {
813 mbedtls_printf("passed\n");
814 }
Janos Follathd4443582016-10-12 10:00:42 +0100815
Steven Cooreman830d5af2021-01-08 18:01:46 +0100816next_test:
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100818 }
819
Gilles Peskinedf761d52018-03-01 22:18:14 +0100820 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100821 goto exit;
822
823cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100825
Janos Follathd4443582016-10-12 10:00:42 +0100826exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100828}
829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830static int cmac_test_wth_cipher(int verbose,
831 const char *testname,
832 const unsigned char *key,
833 int keybits,
834 const unsigned char *messages,
835 const unsigned int message_lengths[4],
836 const unsigned char *expected_result,
837 mbedtls_cipher_type_t cipher_type,
838 int block_size,
839 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700840{
Simon Butcher327398a2016-10-05 14:09:11 +0100841 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800842 int i, ret = 0;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200843 unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murray57863ad2016-05-19 16:38:36 -0700844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
846 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100847 /* Failing at this point must be due to a build issue */
848 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700849 goto exit;
850 }
851
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 for (i = 0; i < num_tests; i++) {
853 if (verbose != 0) {
854 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
855 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700856
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
858 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100859 /* When CMAC is implemented by an alternative implementation, or
860 * the underlying primitive itself is implemented alternatively,
Steven Cooremand3679902021-02-15 13:42:35 +0100861 * AES-192 and/or 3DES may be unavailable. This should not cause
862 * the selftest function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
864 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
865 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
866 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
867 if (verbose != 0) {
868 mbedtls_printf("skipped\n");
869 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100870 continue;
871 }
872
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 if (verbose != 0) {
874 mbedtls_printf("failed\n");
875 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700876 goto exit;
877 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
880 if (verbose != 0) {
881 mbedtls_printf("failed\n");
882 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700883 goto exit;
884 }
885
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 if (verbose != 0) {
887 mbedtls_printf("passed\n");
888 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700889 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100890 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100891
Simon Butcher69283e52016-10-06 12:49:58 +0100892exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700894}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000895
Simon Butcher69283e52016-10-06 12:49:58 +0100896#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100897static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700898{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000899 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000900 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100901 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 for (i = 0; i < NB_PRF_TESTS; i++) {
904 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
905 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
906 if (ret != 0 ||
907 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 if (verbose != 0) {
910 mbedtls_printf("failed\n");
911 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 return ret;
914 } else if (verbose != 0) {
915 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700916 }
917 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700919}
920#endif /* MBEDTLS_AES_C */
921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700923{
Janos Follath24eed8d2019-11-22 13:21:35 +0000924 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100925
Simon Butcher69283e52016-10-06 12:49:58 +0100926#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100927 /* AES-128 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 if ((ret = cmac_test_subkeys(verbose,
929 "AES 128",
930 aes_128_key,
931 128,
932 (const unsigned char *) aes_128_subkeys,
933 MBEDTLS_CIPHER_AES_128_ECB,
934 MBEDTLS_AES_BLOCK_SIZE,
935 NB_CMAC_TESTS_PER_KEY)) != 0) {
936 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100937 }
938
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 if ((ret = cmac_test_wth_cipher(verbose,
940 "AES 128",
941 aes_128_key,
942 128,
943 test_message,
944 aes_message_lengths,
945 (const unsigned char *) aes_128_expected_result,
946 MBEDTLS_CIPHER_AES_128_ECB,
947 MBEDTLS_AES_BLOCK_SIZE,
948 NB_CMAC_TESTS_PER_KEY)) != 0) {
949 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100950 }
951
952 /* AES-192 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800953#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 if ((ret = cmac_test_subkeys(verbose,
955 "AES 192",
956 aes_192_key,
957 192,
958 (const unsigned char *) aes_192_subkeys,
959 MBEDTLS_CIPHER_AES_192_ECB,
960 MBEDTLS_AES_BLOCK_SIZE,
961 NB_CMAC_TESTS_PER_KEY)) != 0) {
962 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700963 }
Brian Murray0f6af732016-05-19 15:59:23 -0700964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 if ((ret = cmac_test_wth_cipher(verbose,
966 "AES 192",
967 aes_192_key,
968 192,
969 test_message,
970 aes_message_lengths,
971 (const unsigned char *) aes_192_expected_result,
972 MBEDTLS_CIPHER_AES_192_ECB,
973 MBEDTLS_AES_BLOCK_SIZE,
974 NB_CMAC_TESTS_PER_KEY)) != 0) {
975 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100976 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800977#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Simon Butcher327398a2016-10-05 14:09:11 +0100978
979 /* AES-256 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800980#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 if ((ret = cmac_test_subkeys(verbose,
982 "AES 256",
983 aes_256_key,
984 256,
985 (const unsigned char *) aes_256_subkeys,
986 MBEDTLS_CIPHER_AES_256_ECB,
987 MBEDTLS_AES_BLOCK_SIZE,
988 NB_CMAC_TESTS_PER_KEY)) != 0) {
989 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700990 }
Brian Murray0f6af732016-05-19 15:59:23 -0700991
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 if ((ret = cmac_test_wth_cipher(verbose,
993 "AES 256",
994 aes_256_key,
995 256,
996 test_message,
997 aes_message_lengths,
998 (const unsigned char *) aes_256_expected_result,
999 MBEDTLS_CIPHER_AES_256_ECB,
1000 MBEDTLS_AES_BLOCK_SIZE,
1001 NB_CMAC_TESTS_PER_KEY)) != 0) {
1002 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001003 }
Yanray Wangdd56add2023-05-11 13:53:46 +08001004#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -07001005#endif /* MBEDTLS_AES_C */
1006
Simon Butcher69283e52016-10-06 12:49:58 +01001007#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001008 /* 3DES 2 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 if ((ret = cmac_test_subkeys(verbose,
1010 "3DES 2 key",
1011 des3_2key_key,
1012 192,
1013 (const unsigned char *) des3_2key_subkeys,
1014 MBEDTLS_CIPHER_DES_EDE3_ECB,
1015 MBEDTLS_DES3_BLOCK_SIZE,
1016 NB_CMAC_TESTS_PER_KEY)) != 0) {
1017 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001018 }
1019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 if ((ret = cmac_test_wth_cipher(verbose,
1021 "3DES 2 key",
1022 des3_2key_key,
1023 192,
1024 test_message,
1025 des3_message_lengths,
1026 (const unsigned char *) des3_2key_expected_result,
1027 MBEDTLS_CIPHER_DES_EDE3_ECB,
1028 MBEDTLS_DES3_BLOCK_SIZE,
1029 NB_CMAC_TESTS_PER_KEY)) != 0) {
1030 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001031 }
Brian Murray0f6af732016-05-19 15:59:23 -07001032
Simon Butcher327398a2016-10-05 14:09:11 +01001033 /* 3DES 3 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 if ((ret = cmac_test_subkeys(verbose,
1035 "3DES 3 key",
1036 des3_3key_key,
1037 192,
1038 (const unsigned char *) des3_3key_subkeys,
1039 MBEDTLS_CIPHER_DES_EDE3_ECB,
1040 MBEDTLS_DES3_BLOCK_SIZE,
1041 NB_CMAC_TESTS_PER_KEY)) != 0) {
1042 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001043 }
1044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 if ((ret = cmac_test_wth_cipher(verbose,
1046 "3DES 3 key",
1047 des3_3key_key,
1048 192,
1049 test_message,
1050 des3_message_lengths,
1051 (const unsigned char *) des3_3key_expected_result,
1052 MBEDTLS_CIPHER_DES_EDE3_ECB,
1053 MBEDTLS_DES3_BLOCK_SIZE,
1054 NB_CMAC_TESTS_PER_KEY)) != 0) {
1055 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001056 }
Brian Murray0f6af732016-05-19 15:59:23 -07001057#endif /* MBEDTLS_DES_C */
1058
Simon Butcher69283e52016-10-06 12:49:58 +01001059#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1061 return ret;
1062 }
Brian Murray0f6af732016-05-19 15:59:23 -07001063#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001064
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 if (verbose != 0) {
1066 mbedtls_printf("\n");
1067 }
Brian Murray0f6af732016-05-19 15:59:23 -07001068
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001070}
1071
Brian Murray0f6af732016-05-19 15:59:23 -07001072#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001073
1074#endif /* MBEDTLS_CMAC_C */