blob: 56a9c7101e15971b5e23a9000521c6a813658547 [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"
Dave Rodgman64172bc2024-01-29 12:29:14 +000037#include "constant_time_internal.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000038
39#include <string.h>
40
Ron Eldor621080d2017-12-21 10:57:43 +020041#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020042
Robert Cragie3d23b1d2015-12-15 07:38:11 +000043/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070044 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000045 *
Brian Murray72b69e32016-09-13 14:21:01 -070046 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000047 *
Simon Butcher327398a2016-10-05 14:09:11 +010048 * If MSB(p) = 0, then p = (p << 1)
49 * If MSB(p) = 1, then p = (p << 1) ^ R_n
50 * with R_64 = 0x1B and R_128 = 0x87
51 *
52 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -080053 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000054 */
Gilles Peskine449bd832023-01-11 14:50:10 +010055static int cmac_multiply_by_u(unsigned char *output,
56 const unsigned char *input,
57 size_t blocksize)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000058{
Brian Murrayb0c3c432016-05-18 14:29:51 -070059 const unsigned char R_128 = 0x87;
60 const unsigned char R_64 = 0x1B;
Dave Rodgman64172bc2024-01-29 12:29:14 +000061 unsigned char R_n;
Brian Murrayb0c3c432016-05-18 14:29:51 -070062 unsigned char overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010063 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070064
Gilles Peskine449bd832023-01-11 14:50:10 +010065 if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070066 R_n = R_128;
Gilles Peskine449bd832023-01-11 14:50:10 +010067 } else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070068 R_n = R_64;
Gilles Peskine449bd832023-01-11 14:50:10 +010069 } else {
70 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Brian Murrayb0c3c432016-05-18 14:29:51 -070071 }
72
Gilles Peskine449bd832023-01-11 14:50:10 +010073 for (i = (int) blocksize - 1; i >= 0; i--) {
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000074 output[i] = input[i] << 1 | overflow;
75 overflow = input[i] >> 7;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000076 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000077
Dave Rodgman64172bc2024-01-29 12:29:14 +000078 R_n = (unsigned char) mbedtls_ct_uint_if_else_0(mbedtls_ct_bool(input[0] >> 7), R_n);
79 output[blocksize - 1] ^= R_n;
Simon Butcher327398a2016-10-05 14:09:11 +010080
Gilles Peskine449bd832023-01-11 14:50:10 +010081 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000082}
83
84/*
85 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +010086 *
87 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +000088 */
Gilles Peskine449bd832023-01-11 14:50:10 +010089static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
90 unsigned char *K1, unsigned char *K2)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000091{
Janos Follath24eed8d2019-11-22 13:21:35 +000092 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9e930e22023-06-14 17:52:54 +020093 unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murrayb0c3c432016-05-18 14:29:51 -070094 size_t olen, block_size;
95
Gilles Peskine449bd832023-01-11 14:50:10 +010096 mbedtls_platform_zeroize(L, sizeof(L));
Brian Murrayb0c3c432016-05-18 14:29:51 -070097
Dave Rodgman85a88132023-06-24 11:41:50 +010098 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +010099
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000100 /* Calculate Ek(0) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700102 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100103 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000104
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000105 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000106 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000107 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700109 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000111
Gilles Peskine449bd832023-01-11 14:50:10 +0100112 if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100113 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 }
Simon Butcher327398a2016-10-05 14:09:11 +0100115
116exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 mbedtls_platform_zeroize(L, sizeof(L));
Simon Butcher327398a2016-10-05 14:09:11 +0100118
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000120}
Ron Eldor621080d2017-12-21 10:57:43 +0200121#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000122
Ron Eldor621080d2017-12-21 10:57:43 +0200123#if !defined(MBEDTLS_CMAC_ALT)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000124
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000125/*
126 * Create padded last block from (partial) last block.
127 *
128 * We can't use the padding option from the cipher layer, as it only works for
129 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
130 */
Gilles Peskine9e930e22023-06-14 17:52:54 +0200131static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 size_t padded_block_len,
133 const unsigned char *last_block,
134 size_t last_block_len)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000135{
136 size_t j;
137
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 for (j = 0; j < padded_block_len; j++) {
139 if (j < last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000140 padded_block[j] = last_block[j];
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 } else if (j == last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000142 padded_block[j] = 0x80;
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 } else {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000144 padded_block[j] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000146 }
147}
148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
150 const unsigned char *key, size_t keybits)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000151{
Simon Butcher327398a2016-10-05 14:09:11 +0100152 mbedtls_cipher_type_t type;
153 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100154 int retval;
155
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
157 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
158 }
Simon Butcher327398a2016-10-05 14:09:11 +0100159
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
161 MBEDTLS_ENCRYPT)) != 0) {
162 return retval;
163 }
Simon Butcher327398a2016-10-05 14:09:11 +0100164
Dave Rodgman2e8f6aa2023-06-24 17:32:18 +0100165 type = mbedtls_cipher_info_get_type(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100166
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 switch (type) {
Simon Butcher327398a2016-10-05 14:09:11 +0100168 case MBEDTLS_CIPHER_AES_128_ECB:
169 case MBEDTLS_CIPHER_AES_192_ECB:
170 case MBEDTLS_CIPHER_AES_256_ECB:
171 case MBEDTLS_CIPHER_DES_EDE3_ECB:
172 break;
173 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Simon Butcher327398a2016-10-05 14:09:11 +0100175 }
176
177 /* Allocated and initialise in the cipher context memory for the CMAC
178 * context */
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
180 if (cmac_ctx == NULL) {
181 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
182 }
Simon Butcher327398a2016-10-05 14:09:11 +0100183
184 ctx->cmac_ctx = cmac_ctx;
185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
Simon Butcher327398a2016-10-05 14:09:11 +0100187
188 return 0;
189}
190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
192 const unsigned char *input, size_t ilen)
Simon Butcher327398a2016-10-05 14:09:11 +0100193{
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 mbedtls_cmac_context_t *cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700195 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000196 int ret = 0;
197 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
200 ctx->cmac_ctx == NULL) {
201 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
202 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700203
Simon Butcher327398a2016-10-05 14:09:11 +0100204 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100205 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100206 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000207
Simon Butcher6b0774a2016-10-10 21:37:42 +0100208 /* Is there data still to process from the last call, that's greater in
209 * size than a block? */
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 if (cmac_ctx->unprocessed_len > 0 &&
211 ilen > block_size - cmac_ctx->unprocessed_len) {
212 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
213 input,
214 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100215
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100216 mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
219 &olen)) != 0) {
220 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100221 }
222
Simon Butcher6b0774a2016-10-10 21:37:42 +0100223 input += block_size - cmac_ctx->unprocessed_len;
224 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100225 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700226 }
227
Simon Butcher327398a2016-10-05 14:09:11 +0100228 /* n is the number of blocks including any final partial block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100230
Simon B3249cb72016-11-03 01:11:37 +0000231 /* Iterate across the input data in block sized chunks, excluding any
232 * final partial or complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 for (j = 1; j < n; j++) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100234 mbedtls_xor_no_simd(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
237 &olen)) != 0) {
238 goto exit;
239 }
Simon Butcher327398a2016-10-05 14:09:11 +0100240
241 ilen -= block_size;
242 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700243 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000244
Simon Butcher327398a2016-10-05 14:09:11 +0100245 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 if (ilen > 0) {
247 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
248 input,
249 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100250 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100251 }
252
253exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100255}
256
Gilles Peskine449bd832023-01-11 14:50:10 +0100257int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
258 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100259{
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100261 unsigned char *state, *last_block;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200262 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
263 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
264 unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Janos Follath24eed8d2019-11-22 13:21:35 +0000265 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100266 size_t olen, block_size;
267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
269 output == NULL) {
270 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
271 }
Simon Butcher327398a2016-10-05 14:09:11 +0100272
273 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100274 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100275 state = cmac_ctx->state;
276
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 mbedtls_platform_zeroize(K1, sizeof(K1));
278 mbedtls_platform_zeroize(K2, sizeof(K2));
279 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100280
Simon Butcher69283e52016-10-06 12:49:58 +0100281 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000282
283 /* Calculate last block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 if (cmac_ctx->unprocessed_len < block_size) {
285 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
286 mbedtls_xor(M_last, M_last, K2, block_size);
287 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000288 /* Last block is complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 mbedtls_xor(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000290 }
291
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 mbedtls_xor(state, M_last, state, block_size);
294 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
295 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100296 goto exit;
297 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100300
301exit:
302 /* Wipe the generated keys on the stack, and any other transients to avoid
303 * side channel leakage */
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 mbedtls_platform_zeroize(K1, sizeof(K1));
305 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100306
307 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
309 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100310
Gilles Peskine9e930e22023-06-14 17:52:54 +0200311 mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000313}
314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000316{
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
320 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
321 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700322
Simon Butcher327398a2016-10-05 14:09:11 +0100323 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000324
Simon Butcher327398a2016-10-05 14:09:11 +0100325 /* Reset the internal state */
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));
329 mbedtls_platform_zeroize(cmac_ctx->state,
330 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000333}
334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
336 const unsigned char *key, size_t keylen,
337 const unsigned char *input, size_t ilen,
338 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100339{
340 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000341 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
344 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
345 }
Simon Butcher327398a2016-10-05 14:09:11 +0100346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100350 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 }
Simon Butcher327398a2016-10-05 14:09:11 +0100352
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
354 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100355 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 }
Simon Butcher327398a2016-10-05 14:09:11 +0100357
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
359 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100360 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 }
Simon Butcher327398a2016-10-05 14:09:11 +0100362
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 ret = mbedtls_cipher_cmac_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100364
365exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100367
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100369}
Simon Butcher327398a2016-10-05 14:09:11 +0100370
Simon Butcher69283e52016-10-06 12:49:58 +0100371#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000372/*
Simon Butcher69283e52016-10-06 12:49:58 +0100373 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000374 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
376 const unsigned char *input, size_t in_len,
377 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000378{
Janos Follath24eed8d2019-11-22 13:21:35 +0000379 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100380 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100381 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
382 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 if (key == NULL || input == NULL || output == NULL) {
385 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
386 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
389 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100390 /* Failing at this point must be due to a build issue */
391 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
392 goto exit;
393 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000396 /* Use key as is */
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
398 } else {
399 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
402 key_length, int_key);
403 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700404 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000406 }
407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
409 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000410
Simon Butcher327398a2016-10-05 14:09:11 +0100411exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000415}
Brian Murrayb439d452016-05-19 16:02:42 -0700416#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000417
Steven Cooreman63342772017-04-04 11:47:16 +0200418#endif /* !MBEDTLS_CMAC_ALT */
419
Simon Butcher69283e52016-10-06 12:49:58 +0100420#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000421/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000422 * CMAC test data for SP800-38B
423 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
424 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700425 *
426 * AES-CMAC-PRF-128 test data from RFC 4615
427 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000428 */
429
Brian Murray0f6af732016-05-19 15:59:23 -0700430#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000431#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100432
Brian Murray0f6af732016-05-19 15:59:23 -0700433#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
434/* All CMAC test inputs are truncated from the same 64 byte buffer. */
435static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000436 /* PT */
437 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
438 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
439 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
440 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
441 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
442 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
443 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
444 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000445};
Simon Butcher69283e52016-10-06 12:49:58 +0100446#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700447
Simon Butcher69283e52016-10-06 12:49:58 +0100448#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700449/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700450static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000451 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700452 0,
453 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000454 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700455 64
456};
457
Janos Follathcd13bd22016-12-13 11:51:04 +0000458/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700459static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000460 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
461 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700462};
Simon Butcher69283e52016-10-06 12:49:58 +0100463static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700464 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000465 /* K1 */
466 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
467 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700468 },
469 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000470 /* K2 */
471 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
472 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700473 }
474};
Gilles Peskine449bd832023-01-11 14:50:10 +0100475static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
476{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000477 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000478 /* Example #1 */
479 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
480 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000481 },
482 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000483 /* Example #2 */
484 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
485 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000486 },
487 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000488 /* Example #3 */
489 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
490 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000491 },
492 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000493 /* Example #4 */
494 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
495 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000496 }
497};
498
Janos Follathcd13bd22016-12-13 11:51:04 +0000499/* CMAC-AES192 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800500#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700501static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000502 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
503 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
504 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000505};
Simon Butcher69283e52016-10-06 12:49:58 +0100506static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700507 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000508 /* K1 */
509 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
510 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700511 },
512 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000513 /* K2 */
514 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
515 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700516 }
517};
Gilles Peskine449bd832023-01-11 14:50:10 +0100518static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
519{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700520 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000521 /* Example #1 */
522 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
523 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700524 },
525 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000526 /* Example #2 */
527 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
528 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700529 },
530 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000531 /* Example #3 */
532 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
533 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700534 },
535 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000536 /* Example #4 */
537 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
538 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700539 }
540};
Yanray Wangdd56add2023-05-11 13:53:46 +0800541#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700542
Janos Follathcd13bd22016-12-13 11:51:04 +0000543/* CMAC-AES256 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800544#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700545static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000546 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
547 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
548 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
549 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700550};
Simon Butcher69283e52016-10-06 12:49:58 +0100551static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700552 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000553 /* K1 */
554 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
555 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700556 },
557 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000558 /* K2 */
559 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
560 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700561 }
562};
Gilles Peskine449bd832023-01-11 14:50:10 +0100563static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
564{
Brian Murray0f6af732016-05-19 15:59:23 -0700565 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000566 /* Example #1 */
567 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
568 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700569 },
570 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000571 /* Example #2 */
572 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
573 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700574 },
575 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000576 /* Example #3 */
577 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
578 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700579 },
580 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000581 /* Example #4 */
582 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
583 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700584 }
585};
Yanray Wangdd56add2023-05-11 13:53:46 +0800586#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700587#endif /* MBEDTLS_AES_C */
588
Simon Butcher69283e52016-10-06 12:49:58 +0100589#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700590/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700591static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700592 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000593 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700594 20,
595 32
596};
597
Janos Follathcd13bd22016-12-13 11:51:04 +0000598/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700599static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000600 /* Key1 */
601 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
602 /* Key2 */
603 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
604 /* Key3 */
605 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700606};
607static const unsigned char des3_2key_subkeys[2][8] = {
608 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000609 /* K1 */
610 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700611 },
612 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000613 /* K2 */
614 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700615 }
616};
Gilles Peskine449bd832023-01-11 14:50:10 +0100617static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
618 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700619 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000620 /* Sample #1 */
621 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700622 },
623 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000624 /* Sample #2 */
625 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700626 },
627 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000628 /* Sample #3 */
629 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700630 },
631 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000632 /* Sample #4 */
633 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700634 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700636
Janos Follathcd13bd22016-12-13 11:51:04 +0000637/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700638static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000639 /* Key1 */
640 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
641 /* Key2 */
642 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
643 /* Key3 */
644 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700645};
646static const unsigned char des3_3key_subkeys[2][8] = {
647 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000648 /* K1 */
649 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700650 },
651 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000652 /* K2 */
653 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700654 }
655};
Gilles Peskine449bd832023-01-11 14:50:10 +0100656static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
657 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700658 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000659 /* Sample #1 */
660 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700661 },
662 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000663 /* Sample #2 */
664 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700665 },
666 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000667 /* Sample #3 */
668 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700669 },
670 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000671 /* Sample #4 */
672 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700673 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700675
Brian Murray0f6af732016-05-19 15:59:23 -0700676#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700677
Simon Butcher69283e52016-10-06 12:49:58 +0100678#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700679/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000680static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000681 /* Key */
682 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
683 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000684 0xed, 0xcb
685};
686
687/* Sizes in bytes */
688static const size_t PRFKlen[NB_PRF_TESTS] = {
689 18,
690 16,
691 10
692};
693
Janos Follathcd13bd22016-12-13 11:51:04 +0000694/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000695static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000696 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
697 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000698 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000699};
700
701static const unsigned char PRFT[NB_PRF_TESTS][16] = {
702 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000703 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
704 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000705 },
706 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000707 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
708 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000709 },
710 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000711 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
712 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000713 }
714};
Brian Murray0f6af732016-05-19 15:59:23 -0700715#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717static int cmac_test_subkeys(int verbose,
718 const char *testname,
719 const unsigned char *key,
720 int keybits,
721 const unsigned char *subkeys,
722 mbedtls_cipher_type_t cipher_type,
723 int block_size,
724 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100725{
Brian Murray2fab5c92016-12-15 18:51:13 -0800726 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100727 mbedtls_cipher_context_t ctx;
728 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200729 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
730 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
733 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100734 /* Failing at this point must be due to a build issue */
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100736 }
737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 for (i = 0; i < num_tests; i++) {
739 if (verbose != 0) {
740 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
741 }
Simon Butcher327398a2016-10-05 14:09:11 +0100742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100744
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
746 if (verbose != 0) {
747 mbedtls_printf("test execution failed\n");
748 }
Simon Butcher327398a2016-10-05 14:09:11 +0100749
Janos Follathd4443582016-10-12 10:00:42 +0100750 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100751 }
752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
754 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100755 /* When CMAC is implemented by an alternative implementation, or
756 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100757 * AES-192 may be unavailable. This should not cause the selftest
758 * function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
760 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
761 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
762 if (verbose != 0) {
763 mbedtls_printf("skipped\n");
764 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100765 goto next_test;
766 }
767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 if (verbose != 0) {
769 mbedtls_printf("test execution failed\n");
770 }
Simon Butcher327398a2016-10-05 14:09:11 +0100771
Janos Follathd4443582016-10-12 10:00:42 +0100772 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100773 }
774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 ret = cmac_generate_subkeys(&ctx, K1, K2);
776 if (ret != 0) {
777 if (verbose != 0) {
778 mbedtls_printf("failed\n");
779 }
Janos Follathd4443582016-10-12 10:00:42 +0100780
781 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100782 }
783
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
785 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
786 if (verbose != 0) {
787 mbedtls_printf("failed\n");
788 }
Janos Follathd4443582016-10-12 10:00:42 +0100789
790 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100791 }
792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 if (verbose != 0) {
794 mbedtls_printf("passed\n");
795 }
Janos Follathd4443582016-10-12 10:00:42 +0100796
Steven Cooreman830d5af2021-01-08 18:01:46 +0100797next_test:
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100799 }
800
Gilles Peskinedf761d52018-03-01 22:18:14 +0100801 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100802 goto exit;
803
804cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100806
Janos Follathd4443582016-10-12 10:00:42 +0100807exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100809}
810
Gilles Peskine449bd832023-01-11 14:50:10 +0100811static int cmac_test_wth_cipher(int verbose,
812 const char *testname,
813 const unsigned char *key,
814 int keybits,
815 const unsigned char *messages,
816 const unsigned int message_lengths[4],
817 const unsigned char *expected_result,
818 mbedtls_cipher_type_t cipher_type,
819 int block_size,
820 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700821{
Simon Butcher327398a2016-10-05 14:09:11 +0100822 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800823 int i, ret = 0;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200824 unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murray57863ad2016-05-19 16:38:36 -0700825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
827 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100828 /* Failing at this point must be due to a build issue */
829 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700830 goto exit;
831 }
832
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 for (i = 0; i < num_tests; i++) {
834 if (verbose != 0) {
835 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
836 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
839 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100840 /* When CMAC is implemented by an alternative implementation, or
841 * the underlying primitive itself is implemented alternatively,
Steven Cooremand3679902021-02-15 13:42:35 +0100842 * AES-192 and/or 3DES may be unavailable. This should not cause
843 * the selftest function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
845 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
846 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
847 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
848 if (verbose != 0) {
849 mbedtls_printf("skipped\n");
850 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100851 continue;
852 }
853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 if (verbose != 0) {
855 mbedtls_printf("failed\n");
856 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700857 goto exit;
858 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700859
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
861 if (verbose != 0) {
862 mbedtls_printf("failed\n");
863 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700864 goto exit;
865 }
866
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 if (verbose != 0) {
868 mbedtls_printf("passed\n");
869 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700870 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100871 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100872
Simon Butcher69283e52016-10-06 12:49:58 +0100873exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700875}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000876
Simon Butcher69283e52016-10-06 12:49:58 +0100877#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100878static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700879{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000880 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000881 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100882 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 for (i = 0; i < NB_PRF_TESTS; i++) {
885 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
886 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
887 if (ret != 0 ||
888 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 if (verbose != 0) {
891 mbedtls_printf("failed\n");
892 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 return ret;
895 } else if (verbose != 0) {
896 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700897 }
898 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700900}
901#endif /* MBEDTLS_AES_C */
902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700904{
Janos Follath24eed8d2019-11-22 13:21:35 +0000905 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100906
Simon Butcher69283e52016-10-06 12:49:58 +0100907#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100908 /* AES-128 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 if ((ret = cmac_test_subkeys(verbose,
910 "AES 128",
911 aes_128_key,
912 128,
913 (const unsigned char *) aes_128_subkeys,
914 MBEDTLS_CIPHER_AES_128_ECB,
915 MBEDTLS_AES_BLOCK_SIZE,
916 NB_CMAC_TESTS_PER_KEY)) != 0) {
917 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100918 }
919
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 if ((ret = cmac_test_wth_cipher(verbose,
921 "AES 128",
922 aes_128_key,
923 128,
924 test_message,
925 aes_message_lengths,
926 (const unsigned char *) aes_128_expected_result,
927 MBEDTLS_CIPHER_AES_128_ECB,
928 MBEDTLS_AES_BLOCK_SIZE,
929 NB_CMAC_TESTS_PER_KEY)) != 0) {
930 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100931 }
932
933 /* AES-192 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800934#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 if ((ret = cmac_test_subkeys(verbose,
936 "AES 192",
937 aes_192_key,
938 192,
939 (const unsigned char *) aes_192_subkeys,
940 MBEDTLS_CIPHER_AES_192_ECB,
941 MBEDTLS_AES_BLOCK_SIZE,
942 NB_CMAC_TESTS_PER_KEY)) != 0) {
943 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700944 }
Brian Murray0f6af732016-05-19 15:59:23 -0700945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 if ((ret = cmac_test_wth_cipher(verbose,
947 "AES 192",
948 aes_192_key,
949 192,
950 test_message,
951 aes_message_lengths,
952 (const unsigned char *) aes_192_expected_result,
953 MBEDTLS_CIPHER_AES_192_ECB,
954 MBEDTLS_AES_BLOCK_SIZE,
955 NB_CMAC_TESTS_PER_KEY)) != 0) {
956 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100957 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800958#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Simon Butcher327398a2016-10-05 14:09:11 +0100959
960 /* AES-256 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800961#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 if ((ret = cmac_test_subkeys(verbose,
963 "AES 256",
964 aes_256_key,
965 256,
966 (const unsigned char *) aes_256_subkeys,
967 MBEDTLS_CIPHER_AES_256_ECB,
968 MBEDTLS_AES_BLOCK_SIZE,
969 NB_CMAC_TESTS_PER_KEY)) != 0) {
970 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700971 }
Brian Murray0f6af732016-05-19 15:59:23 -0700972
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 if ((ret = cmac_test_wth_cipher(verbose,
974 "AES 256",
975 aes_256_key,
976 256,
977 test_message,
978 aes_message_lengths,
979 (const unsigned char *) aes_256_expected_result,
980 MBEDTLS_CIPHER_AES_256_ECB,
981 MBEDTLS_AES_BLOCK_SIZE,
982 NB_CMAC_TESTS_PER_KEY)) != 0) {
983 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700984 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800985#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700986#endif /* MBEDTLS_AES_C */
987
Simon Butcher69283e52016-10-06 12:49:58 +0100988#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100989 /* 3DES 2 key */
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 if ((ret = cmac_test_subkeys(verbose,
991 "3DES 2 key",
992 des3_2key_key,
993 192,
994 (const unsigned char *) des3_2key_subkeys,
995 MBEDTLS_CIPHER_DES_EDE3_ECB,
996 MBEDTLS_DES3_BLOCK_SIZE,
997 NB_CMAC_TESTS_PER_KEY)) != 0) {
998 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100999 }
1000
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 if ((ret = cmac_test_wth_cipher(verbose,
1002 "3DES 2 key",
1003 des3_2key_key,
1004 192,
1005 test_message,
1006 des3_message_lengths,
1007 (const unsigned char *) des3_2key_expected_result,
1008 MBEDTLS_CIPHER_DES_EDE3_ECB,
1009 MBEDTLS_DES3_BLOCK_SIZE,
1010 NB_CMAC_TESTS_PER_KEY)) != 0) {
1011 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001012 }
Brian Murray0f6af732016-05-19 15:59:23 -07001013
Simon Butcher327398a2016-10-05 14:09:11 +01001014 /* 3DES 3 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 if ((ret = cmac_test_subkeys(verbose,
1016 "3DES 3 key",
1017 des3_3key_key,
1018 192,
1019 (const unsigned char *) des3_3key_subkeys,
1020 MBEDTLS_CIPHER_DES_EDE3_ECB,
1021 MBEDTLS_DES3_BLOCK_SIZE,
1022 NB_CMAC_TESTS_PER_KEY)) != 0) {
1023 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001024 }
1025
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 if ((ret = cmac_test_wth_cipher(verbose,
1027 "3DES 3 key",
1028 des3_3key_key,
1029 192,
1030 test_message,
1031 des3_message_lengths,
1032 (const unsigned char *) des3_3key_expected_result,
1033 MBEDTLS_CIPHER_DES_EDE3_ECB,
1034 MBEDTLS_DES3_BLOCK_SIZE,
1035 NB_CMAC_TESTS_PER_KEY)) != 0) {
1036 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001037 }
Brian Murray0f6af732016-05-19 15:59:23 -07001038#endif /* MBEDTLS_DES_C */
1039
Simon Butcher69283e52016-10-06 12:49:58 +01001040#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1042 return ret;
1043 }
Brian Murray0f6af732016-05-19 15:59:23 -07001044#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 if (verbose != 0) {
1047 mbedtls_printf("\n");
1048 }
Brian Murray0f6af732016-05-19 15:59:23 -07001049
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001051}
1052
Brian Murray0f6af732016-05-19 15:59:23 -07001053#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001054
1055#endif /* MBEDTLS_CMAC_C */