blob: f9f606f16adcd1566a0d1c4cd6871a77d2f2b81a [file] [log] [blame]
Andres Amaya Garciaaf610a02016-12-14 10:13:43 +00001/**
Brian Murray53e23b62016-09-13 14:00:15 -07002 * \file cmac.c
Simon Butcher327398a2016-10-05 14:09:11 +01003 *
Simon Butcher69283e52016-10-06 12:49:58 +01004 * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
Robert Cragie3d23b1d2015-12-15 07:38:11 +00005 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02006 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Robert Cragie3d23b1d2015-12-15 07:38:11 +00008 */
9
10/*
Brian Murray53e23b62016-09-13 14:00:15 -070011 * References:
Simon Butcher327398a2016-10-05 14:09:11 +010012 *
13 * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
14 * CMAC Mode for Authentication
Janos Follathcd13bd22016-12-13 11:51:04 +000015 * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
Simon Butcher327398a2016-10-05 14:09:11 +010016 *
17 * - RFC 4493 - The AES-CMAC Algorithm
18 * https://tools.ietf.org/html/rfc4493
19 *
20 * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
21 * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
22 * Algorithm for the Internet Key Exchange Protocol (IKE)
23 * https://tools.ietf.org/html/rfc4615
24 *
25 * Additional test vectors: ISO/IEC 9797-1
26 *
Robert Cragie3d23b1d2015-12-15 07:38:11 +000027 */
28
Gilles Peskinedb09ef62020-06-03 01:43:33 +020029#include "common.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000030
31#if defined(MBEDTLS_CMAC_C)
32
33#include "mbedtls/cmac.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Steven Cooreman655b0122021-01-11 14:34:51 +010036#include "mbedtls/platform.h"
Robert Cragie3d23b1d2015-12-15 07:38:11 +000037
38#include <string.h>
39
Ron Eldor621080d2017-12-21 10:57:43 +020040#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
Steven Cooreman63342772017-04-04 11:47:16 +020041
Robert Cragie3d23b1d2015-12-15 07:38:11 +000042/*
Brian Murrayb0c3c432016-05-18 14:29:51 -070043 * Multiplication by u in the Galois field of GF(2^n)
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000044 *
Brian Murray72b69e32016-09-13 14:21:01 -070045 * As explained in NIST SP 800-38B, this can be computed:
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +000046 *
Simon Butcher327398a2016-10-05 14:09:11 +010047 * If MSB(p) = 0, then p = (p << 1)
48 * If MSB(p) = 1, then p = (p << 1) ^ R_n
49 * with R_64 = 0x1B and R_128 = 0x87
50 *
51 * Input and output MUST NOT point to the same buffer
Brian J Murray2adecba2016-11-06 04:45:15 -080052 * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
Robert Cragie3d23b1d2015-12-15 07:38:11 +000053 */
Gilles Peskine449bd832023-01-11 14:50:10 +010054static int cmac_multiply_by_u(unsigned char *output,
55 const unsigned char *input,
56 size_t blocksize)
Robert Cragie3d23b1d2015-12-15 07:38:11 +000057{
Brian Murrayb0c3c432016-05-18 14:29:51 -070058 const unsigned char R_128 = 0x87;
59 const unsigned char R_64 = 0x1B;
60 unsigned char R_n, mask;
Dave Rodgman7f86d352024-03-05 15:35:59 +000061 uint32_t overflow = 0x00;
Simon Butcher327398a2016-10-05 14:09:11 +010062 int i;
Brian Murrayb0c3c432016-05-18 14:29:51 -070063
Gilles Peskine449bd832023-01-11 14:50:10 +010064 if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070065 R_n = R_128;
Gilles Peskine449bd832023-01-11 14:50:10 +010066 } else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
Brian Murrayb0c3c432016-05-18 14:29:51 -070067 R_n = R_64;
Gilles Peskine449bd832023-01-11 14:50:10 +010068 } else {
69 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Brian Murrayb0c3c432016-05-18 14:29:51 -070070 }
71
Dave Rodgman7f86d352024-03-05 15:35:59 +000072 for (i = (int) blocksize - 4; i >= 0; i -= 4) {
73 uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
74 uint32_t new_overflow = i32 >> 31;
75 i32 = (i32 << 1) | overflow;
76 MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
77 overflow = new_overflow;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000078 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +000079
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000080 /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
81 * using bit operations to avoid branches */
Simon Butcher327398a2016-10-05 14:09:11 +010082
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000083 /* MSVC has a warning about unary minus on unsigned, but this is
84 * well-defined and precisely what we want to do here */
85#if defined(_MSC_VER)
86#pragma warning( push )
87#pragma warning( disable : 4146 )
88#endif
Gilles Peskine449bd832023-01-11 14:50:10 +010089 mask = -(input[0] >> 7);
Manuel Pégourié-Gonnard475f06f2016-01-13 13:05:03 +000090#if defined(_MSC_VER)
91#pragma warning( pop )
92#endif
93
Gilles Peskine449bd832023-01-11 14:50:10 +010094 output[blocksize - 1] ^= R_n & mask;
Simon Butcher327398a2016-10-05 14:09:11 +010095
Gilles Peskine449bd832023-01-11 14:50:10 +010096 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +000097}
98
99/*
100 * Generate subkeys
Simon Butcher327398a2016-10-05 14:09:11 +0100101 *
102 * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000103 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100104static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
105 unsigned char *K1, unsigned char *K2)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000106{
Janos Follath24eed8d2019-11-22 13:21:35 +0000107 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200108 unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murrayb0c3c432016-05-18 14:29:51 -0700109 size_t olen, block_size;
110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 mbedtls_platform_zeroize(L, sizeof(L));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700112
Dave Rodgman85a88132023-06-24 11:41:50 +0100113 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100114
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000115 /* Calculate Ek(0) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700117 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000119
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000120 /*
Manuel Pégourié-Gonnarda610b4c2016-01-13 11:28:16 +0000121 * Generate K1 and K2
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000122 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700124 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 }
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100128 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 }
Simon Butcher327398a2016-10-05 14:09:11 +0100130
131exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 mbedtls_platform_zeroize(L, sizeof(L));
Simon Butcher327398a2016-10-05 14:09:11 +0100133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000135}
Ron Eldor621080d2017-12-21 10:57:43 +0200136#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000137
Ron Eldor621080d2017-12-21 10:57:43 +0200138#if !defined(MBEDTLS_CMAC_ALT)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000139
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000140/*
141 * Create padded last block from (partial) last block.
142 *
143 * We can't use the padding option from the cipher layer, as it only works for
144 * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
145 */
Gilles Peskine9e930e22023-06-14 17:52:54 +0200146static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE],
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 size_t padded_block_len,
148 const unsigned char *last_block,
149 size_t last_block_len)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000150{
151 size_t j;
152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 for (j = 0; j < padded_block_len; j++) {
154 if (j < last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000155 padded_block[j] = last_block[j];
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 } else if (j == last_block_len) {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000157 padded_block[j] = 0x80;
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 } else {
Manuel Pégourié-Gonnardd2c3d3e2016-01-13 13:14:04 +0000159 padded_block[j] = 0x00;
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000161 }
162}
163
Gilles Peskine449bd832023-01-11 14:50:10 +0100164int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
165 const unsigned char *key, size_t keybits)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000166{
Simon Butcher327398a2016-10-05 14:09:11 +0100167 mbedtls_cipher_type_t type;
168 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher327398a2016-10-05 14:09:11 +0100169 int retval;
170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) {
172 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
173 }
Simon Butcher327398a2016-10-05 14:09:11 +0100174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175 if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits,
176 MBEDTLS_ENCRYPT)) != 0) {
177 return retval;
178 }
Simon Butcher327398a2016-10-05 14:09:11 +0100179
Dave Rodgman2e8f6aa2023-06-24 17:32:18 +0100180 type = mbedtls_cipher_info_get_type(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 switch (type) {
Simon Butcher327398a2016-10-05 14:09:11 +0100183 case MBEDTLS_CIPHER_AES_128_ECB:
184 case MBEDTLS_CIPHER_AES_192_ECB:
185 case MBEDTLS_CIPHER_AES_256_ECB:
186 case MBEDTLS_CIPHER_DES_EDE3_ECB:
187 break;
188 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
Simon Butcher327398a2016-10-05 14:09:11 +0100190 }
191
192 /* Allocated and initialise in the cipher context memory for the CMAC
193 * context */
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t));
195 if (cmac_ctx == NULL) {
196 return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
197 }
Simon Butcher327398a2016-10-05 14:09:11 +0100198
199 ctx->cmac_ctx = cmac_ctx;
200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state));
Simon Butcher327398a2016-10-05 14:09:11 +0100202
203 return 0;
204}
205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
207 const unsigned char *input, size_t ilen)
Simon Butcher327398a2016-10-05 14:09:11 +0100208{
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 mbedtls_cmac_context_t *cmac_ctx;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700210 unsigned char *state;
Simon B3249cb72016-11-03 01:11:37 +0000211 int ret = 0;
212 size_t n, j, olen, block_size;
Brian Murrayb0c3c432016-05-18 14:29:51 -0700213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 if (ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
215 ctx->cmac_ctx == NULL) {
216 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
217 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700218
Simon Butcher327398a2016-10-05 14:09:11 +0100219 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100220 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100221 state = ctx->cmac_ctx->state;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000222
Simon Butcher6b0774a2016-10-10 21:37:42 +0100223 /* Is there data still to process from the last call, that's greater in
224 * size than a block? */
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 if (cmac_ctx->unprocessed_len > 0 &&
226 ilen > block_size - cmac_ctx->unprocessed_len) {
227 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
228 input,
229 block_size - cmac_ctx->unprocessed_len);
Simon Butcher327398a2016-10-05 14:09:11 +0100230
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100231 mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100232
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
234 &olen)) != 0) {
235 goto exit;
Simon Butcher327398a2016-10-05 14:09:11 +0100236 }
237
Simon Butcher6b0774a2016-10-10 21:37:42 +0100238 input += block_size - cmac_ctx->unprocessed_len;
239 ilen -= block_size - cmac_ctx->unprocessed_len;
Simon Butcher327398a2016-10-05 14:09:11 +0100240 cmac_ctx->unprocessed_len = 0;
Brian Murray57863ad2016-05-19 16:38:36 -0700241 }
242
Simon Butcher327398a2016-10-05 14:09:11 +0100243 /* n is the number of blocks including any final partial block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 n = (ilen + block_size - 1) / block_size;
Simon Butcher327398a2016-10-05 14:09:11 +0100245
Simon B3249cb72016-11-03 01:11:37 +0000246 /* Iterate across the input data in block sized chunks, excluding any
247 * final partial or complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 for (j = 1; j < n; j++) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +0100249 mbedtls_xor_no_simd(state, input, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
252 &olen)) != 0) {
253 goto exit;
254 }
Simon Butcher327398a2016-10-05 14:09:11 +0100255
256 ilen -= block_size;
257 input += block_size;
Brian Murray57863ad2016-05-19 16:38:36 -0700258 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000259
Simon Butcher327398a2016-10-05 14:09:11 +0100260 /* If there is data left over that wasn't aligned to a block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 if (ilen > 0) {
262 memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
263 input,
264 ilen);
Simon Butcher6b0774a2016-10-10 21:37:42 +0100265 cmac_ctx->unprocessed_len += ilen;
Simon Butcher327398a2016-10-05 14:09:11 +0100266 }
267
268exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100270}
271
Gilles Peskine449bd832023-01-11 14:50:10 +0100272int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
273 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100274{
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 mbedtls_cmac_context_t *cmac_ctx;
Simon Butcher69283e52016-10-06 12:49:58 +0100276 unsigned char *state, *last_block;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200277 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
278 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
279 unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Janos Follath24eed8d2019-11-22 13:21:35 +0000280 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100281 size_t olen, block_size;
282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
284 output == NULL) {
285 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
286 }
Simon Butcher327398a2016-10-05 14:09:11 +0100287
288 cmac_ctx = ctx->cmac_ctx;
Dave Rodgman85a88132023-06-24 11:41:50 +0100289 block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Simon Butcher327398a2016-10-05 14:09:11 +0100290 state = cmac_ctx->state;
291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 mbedtls_platform_zeroize(K1, sizeof(K1));
293 mbedtls_platform_zeroize(K2, sizeof(K2));
294 cmac_generate_subkeys(ctx, K1, K2);
Simon Butcher327398a2016-10-05 14:09:11 +0100295
Simon Butcher69283e52016-10-06 12:49:58 +0100296 last_block = cmac_ctx->unprocessed_block;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000297
298 /* Calculate last block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 if (cmac_ctx->unprocessed_len < block_size) {
300 cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len);
301 mbedtls_xor(M_last, M_last, K2, block_size);
302 } else {
Manuel Pégourié-Gonnard2c063062016-01-13 14:27:55 +0000303 /* Last block is complete block */
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 mbedtls_xor(M_last, last_block, K1, block_size);
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000305 }
306
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 mbedtls_xor(state, M_last, state, block_size);
309 if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
310 &olen)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100311 goto exit;
312 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 memcpy(output, state, block_size);
Simon Butcher327398a2016-10-05 14:09:11 +0100315
316exit:
317 /* Wipe the generated keys on the stack, and any other transients to avoid
318 * side channel leakage */
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 mbedtls_platform_zeroize(K1, sizeof(K1));
320 mbedtls_platform_zeroize(K2, sizeof(K2));
Simon Butcher327398a2016-10-05 14:09:11 +0100321
322 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
324 sizeof(cmac_ctx->unprocessed_block));
Simon Butcher327398a2016-10-05 14:09:11 +0100325
Gilles Peskine9e930e22023-06-14 17:52:54 +0200326 mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000328}
329
Gilles Peskine449bd832023-01-11 14:50:10 +0100330int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000331{
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 mbedtls_cmac_context_t *cmac_ctx;
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000333
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) {
335 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
336 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700337
Simon Butcher327398a2016-10-05 14:09:11 +0100338 cmac_ctx = ctx->cmac_ctx;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000339
Simon Butcher327398a2016-10-05 14:09:11 +0100340 /* Reset the internal state */
341 cmac_ctx->unprocessed_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 mbedtls_platform_zeroize(cmac_ctx->unprocessed_block,
343 sizeof(cmac_ctx->unprocessed_block));
344 mbedtls_platform_zeroize(cmac_ctx->state,
345 sizeof(cmac_ctx->state));
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000348}
349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
351 const unsigned char *key, size_t keylen,
352 const unsigned char *input, size_t ilen,
353 unsigned char *output)
Simon Butcher327398a2016-10-05 14:09:11 +0100354{
355 mbedtls_cipher_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000356 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100357
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) {
359 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
360 }
Simon Butcher327398a2016-10-05 14:09:11 +0100361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 mbedtls_cipher_init(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100365 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 }
Simon Butcher327398a2016-10-05 14:09:11 +0100367
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen);
369 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100370 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 }
Simon Butcher327398a2016-10-05 14:09:11 +0100372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 ret = mbedtls_cipher_cmac_update(&ctx, input, ilen);
374 if (ret != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100375 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 }
Simon Butcher327398a2016-10-05 14:09:11 +0100377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 ret = mbedtls_cipher_cmac_finish(&ctx, output);
Simon Butcher327398a2016-10-05 14:09:11 +0100379
380exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100382
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100384}
Simon Butcher327398a2016-10-05 14:09:11 +0100385
Simon Butcher69283e52016-10-06 12:49:58 +0100386#if defined(MBEDTLS_AES_C)
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000387/*
Simon Butcher69283e52016-10-06 12:49:58 +0100388 * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000389 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100390int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
391 const unsigned char *input, size_t in_len,
392 unsigned char output[16])
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000393{
Janos Follath24eed8d2019-11-22 13:21:35 +0000394 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100395 const mbedtls_cipher_info_t *cipher_info;
Simon Butcher69283e52016-10-06 12:49:58 +0100396 unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
397 unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 if (key == NULL || input == NULL || output == NULL) {
400 return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
401 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
404 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100405 /* Failing at this point must be due to a build issue */
406 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
407 goto exit;
408 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700409
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 if (key_length == MBEDTLS_AES_BLOCK_SIZE) {
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000411 /* Use key as is */
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
413 } else {
414 memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
Manuel Pégourié-Gonnard7b555f22016-01-13 15:09:09 +0000415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key,
417 key_length, int_key);
418 if (ret != 0) {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700419 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 }
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000421 }
422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len,
424 output);
Manuel Pégourié-Gonnardd6cf7542016-01-13 11:30:00 +0000425
Simon Butcher327398a2016-10-05 14:09:11 +0100426exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 mbedtls_platform_zeroize(int_key, sizeof(int_key));
Brian Murrayb0c3c432016-05-18 14:29:51 -0700428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 return ret;
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000430}
Brian Murrayb439d452016-05-19 16:02:42 -0700431#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000432
Steven Cooreman63342772017-04-04 11:47:16 +0200433#endif /* !MBEDTLS_CMAC_ALT */
434
Simon Butcher69283e52016-10-06 12:49:58 +0100435#if defined(MBEDTLS_SELF_TEST)
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000436/*
Janos Follathcd13bd22016-12-13 11:51:04 +0000437 * CMAC test data for SP800-38B
438 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
439 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
Brian Murray0f6af732016-05-19 15:59:23 -0700440 *
441 * AES-CMAC-PRF-128 test data from RFC 4615
442 * https://tools.ietf.org/html/rfc4615#page-4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000443 */
444
Brian Murray0f6af732016-05-19 15:59:23 -0700445#define NB_CMAC_TESTS_PER_KEY 4
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000446#define NB_PRF_TESTS 3
Simon Butcher327398a2016-10-05 14:09:11 +0100447
Brian Murray0f6af732016-05-19 15:59:23 -0700448#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
449/* All CMAC test inputs are truncated from the same 64 byte buffer. */
450static const unsigned char test_message[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000451 /* PT */
452 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
453 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
454 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
455 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
456 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
457 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
458 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
459 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000460};
Simon Butcher69283e52016-10-06 12:49:58 +0100461#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
Brian Murray0cf14c12016-05-23 12:49:50 -0700462
Simon Butcher69283e52016-10-06 12:49:58 +0100463#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700464/* Truncation point of message for AES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700465static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000466 /* Mlen */
Brian Murray0f6af732016-05-19 15:59:23 -0700467 0,
468 16,
Janos Follathcd13bd22016-12-13 11:51:04 +0000469 20,
Brian Murray0f6af732016-05-19 15:59:23 -0700470 64
471};
472
Janos Follathcd13bd22016-12-13 11:51:04 +0000473/* CMAC-AES128 Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700474static const unsigned char aes_128_key[16] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000475 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
476 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Brian Murray0f6af732016-05-19 15:59:23 -0700477};
Simon Butcher69283e52016-10-06 12:49:58 +0100478static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700479 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000480 /* K1 */
481 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66,
482 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde
Brian Murray0f6af732016-05-19 15:59:23 -0700483 },
484 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000485 /* K2 */
486 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc,
487 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b
Brian Murray0f6af732016-05-19 15:59:23 -0700488 }
489};
Gilles Peskine449bd832023-01-11 14:50:10 +0100490static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
491{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000492 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000493 /* Example #1 */
494 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
495 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000496 },
497 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000498 /* Example #2 */
499 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
500 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000501 },
502 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000503 /* Example #3 */
504 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8,
505 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000506 },
507 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000508 /* Example #4 */
509 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
510 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000511 }
512};
513
Janos Follathcd13bd22016-12-13 11:51:04 +0000514/* CMAC-AES192 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800515#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700516static const unsigned char aes_192_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000517 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
518 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
519 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000520};
Simon Butcher69283e52016-10-06 12:49:58 +0100521static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700522 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000523 /* K1 */
524 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27,
525 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96
Brian Murrayb0c3c432016-05-18 14:29:51 -0700526 },
527 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000528 /* K2 */
529 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e,
530 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c
Brian Murrayb0c3c432016-05-18 14:29:51 -0700531 }
532};
Gilles Peskine449bd832023-01-11 14:50:10 +0100533static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
534{
Brian Murrayb0c3c432016-05-18 14:29:51 -0700535 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000536 /* Example #1 */
537 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5,
538 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67
Brian Murrayb0c3c432016-05-18 14:29:51 -0700539 },
540 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000541 /* Example #2 */
542 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90,
543 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84
Brian Murrayb0c3c432016-05-18 14:29:51 -0700544 },
545 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000546 /* Example #3 */
547 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04,
548 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8
Brian Murrayb0c3c432016-05-18 14:29:51 -0700549 },
550 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000551 /* Example #4 */
552 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79,
553 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11
Brian Murrayb0c3c432016-05-18 14:29:51 -0700554 }
555};
Yanray Wangdd56add2023-05-11 13:53:46 +0800556#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700557
Janos Follathcd13bd22016-12-13 11:51:04 +0000558/* CMAC-AES256 Test Data */
Yanray Wangdd56add2023-05-11 13:53:46 +0800559#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Brian Murray57863ad2016-05-19 16:38:36 -0700560static const unsigned char aes_256_key[32] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000561 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
562 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
563 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
564 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
Brian Murray0f6af732016-05-19 15:59:23 -0700565};
Simon Butcher69283e52016-10-06 12:49:58 +0100566static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700567 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000568 /* K1 */
569 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac,
570 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f
Brian Murray0f6af732016-05-19 15:59:23 -0700571 },
572 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000573 /* K2 */
574 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58,
575 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700576 }
577};
Gilles Peskine449bd832023-01-11 14:50:10 +0100578static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] =
579{
Brian Murray0f6af732016-05-19 15:59:23 -0700580 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000581 /* Example #1 */
582 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
583 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83
Brian Murray0f6af732016-05-19 15:59:23 -0700584 },
585 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000586 /* Example #2 */
587 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
588 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c
Brian Murray0f6af732016-05-19 15:59:23 -0700589 },
590 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000591 /* Example #3 */
592 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a,
593 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93
Brian Murray0f6af732016-05-19 15:59:23 -0700594 },
595 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000596 /* Example #4 */
597 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
598 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10
Brian Murray0f6af732016-05-19 15:59:23 -0700599 }
600};
Yanray Wangdd56add2023-05-11 13:53:46 +0800601#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -0700602#endif /* MBEDTLS_AES_C */
603
Simon Butcher69283e52016-10-06 12:49:58 +0100604#if defined(MBEDTLS_DES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700605/* Truncation point of message for 3DES CMAC tests */
Brian Murray57863ad2016-05-19 16:38:36 -0700606static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
Brian Murray0f6af732016-05-19 15:59:23 -0700607 0,
Janos Follathcd13bd22016-12-13 11:51:04 +0000608 16,
Brian Murray0f6af732016-05-19 15:59:23 -0700609 20,
610 32
611};
612
Janos Follathcd13bd22016-12-13 11:51:04 +0000613/* CMAC-TDES (Generation) - 2 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700614static const unsigned char des3_2key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000615 /* Key1 */
616 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
617 /* Key2 */
618 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01,
619 /* Key3 */
620 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Brian Murray0f6af732016-05-19 15:59:23 -0700621};
622static const unsigned char des3_2key_subkeys[2][8] = {
623 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000624 /* K1 */
625 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9
Brian Murray0f6af732016-05-19 15:59:23 -0700626 },
627 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000628 /* K2 */
629 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2
Brian Murray0f6af732016-05-19 15:59:23 -0700630 }
631};
Gilles Peskine449bd832023-01-11 14:50:10 +0100632static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
633 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700634 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000635 /* Sample #1 */
636 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60
Brian Murrayb0c3c432016-05-18 14:29:51 -0700637 },
638 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000639 /* Sample #2 */
640 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b
Brian Murrayb0c3c432016-05-18 14:29:51 -0700641 },
642 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000643 /* Sample #3 */
644 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69
Brian Murrayb0c3c432016-05-18 14:29:51 -0700645 },
646 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000647 /* Sample #4 */
648 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb
Brian Murrayb0c3c432016-05-18 14:29:51 -0700649 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700651
Janos Follathcd13bd22016-12-13 11:51:04 +0000652/* CMAC-TDES (Generation) - 3 Key Test Data */
Brian Murray57863ad2016-05-19 16:38:36 -0700653static const unsigned char des3_3key_key[24] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000654 /* Key1 */
655 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef,
656 /* Key2 */
657 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
658 /* Key3 */
659 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
Brian Murray0f6af732016-05-19 15:59:23 -0700660};
661static const unsigned char des3_3key_subkeys[2][8] = {
662 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000663 /* K1 */
664 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0
Brian Murray0f6af732016-05-19 15:59:23 -0700665 },
666 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000667 /* K2 */
668 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b
Brian Murray0f6af732016-05-19 15:59:23 -0700669 }
670};
Gilles Peskine449bd832023-01-11 14:50:10 +0100671static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE]
672 = {
Brian Murrayb0c3c432016-05-18 14:29:51 -0700673 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000674 /* Sample #1 */
675 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50
Brian Murrayb0c3c432016-05-18 14:29:51 -0700676 },
677 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000678 /* Sample #2 */
679 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09
Brian Murrayb0c3c432016-05-18 14:29:51 -0700680 },
681 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000682 /* Sample #3 */
683 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2
Brian Murrayb0c3c432016-05-18 14:29:51 -0700684 },
685 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000686 /* Sample #4 */
687 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5
Brian Murrayb0c3c432016-05-18 14:29:51 -0700688 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 };
Brian Murrayb0c3c432016-05-18 14:29:51 -0700690
Brian Murray0f6af732016-05-19 15:59:23 -0700691#endif /* MBEDTLS_DES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -0700692
Simon Butcher69283e52016-10-06 12:49:58 +0100693#if defined(MBEDTLS_AES_C)
Brian Murray0f6af732016-05-19 15:59:23 -0700694/* AES AES-CMAC-PRF-128 Test Data */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000695static const unsigned char PRFK[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000696 /* Key */
697 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
698 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000699 0xed, 0xcb
700};
701
702/* Sizes in bytes */
703static const size_t PRFKlen[NB_PRF_TESTS] = {
704 18,
705 16,
706 10
707};
708
Janos Follathcd13bd22016-12-13 11:51:04 +0000709/* Message */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000710static const unsigned char PRFM[] = {
Janos Follathcd13bd22016-12-13 11:51:04 +0000711 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
712 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
Manuel Pégourié-Gonnard3da54022016-01-13 11:00:47 +0000713 0x10, 0x11, 0x12, 0x13
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000714};
715
716static const unsigned char PRFT[NB_PRF_TESTS][16] = {
717 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000718 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b,
719 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000720 },
721 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000722 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52,
723 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000724 },
725 {
Janos Follathcd13bd22016-12-13 11:51:04 +0000726 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee,
727 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000728 }
729};
Brian Murray0f6af732016-05-19 15:59:23 -0700730#endif /* MBEDTLS_AES_C */
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732static int cmac_test_subkeys(int verbose,
733 const char *testname,
734 const unsigned char *key,
735 int keybits,
736 const unsigned char *subkeys,
737 mbedtls_cipher_type_t cipher_type,
738 int block_size,
739 int num_tests)
Simon Butcher327398a2016-10-05 14:09:11 +0100740{
Brian Murray2fab5c92016-12-15 18:51:13 -0800741 int i, ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100742 mbedtls_cipher_context_t ctx;
743 const mbedtls_cipher_info_t *cipher_info;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200744 unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
745 unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
748 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100749 /* Failing at this point must be due to a build issue */
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Simon Butcher327398a2016-10-05 14:09:11 +0100751 }
752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 for (i = 0; i < num_tests; i++) {
754 if (verbose != 0) {
755 mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1);
756 }
Simon Butcher327398a2016-10-05 14:09:11 +0100757
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 mbedtls_cipher_init(&ctx);
Janos Follathd4443582016-10-12 10:00:42 +0100759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) {
761 if (verbose != 0) {
762 mbedtls_printf("test execution failed\n");
763 }
Simon Butcher327398a2016-10-05 14:09:11 +0100764
Janos Follathd4443582016-10-12 10:00:42 +0100765 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100766 }
767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits,
769 MBEDTLS_ENCRYPT)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100770 /* When CMAC is implemented by an alternative implementation, or
771 * the underlying primitive itself is implemented alternatively,
Steven Cooremanc7da6a42021-01-29 11:09:50 +0100772 * AES-192 may be unavailable. This should not cause the selftest
773 * function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
775 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
776 cipher_type == MBEDTLS_CIPHER_AES_192_ECB) {
777 if (verbose != 0) {
778 mbedtls_printf("skipped\n");
779 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100780 goto next_test;
781 }
782
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 if (verbose != 0) {
784 mbedtls_printf("test execution failed\n");
785 }
Simon Butcher327398a2016-10-05 14:09:11 +0100786
Janos Follathd4443582016-10-12 10:00:42 +0100787 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100788 }
789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 ret = cmac_generate_subkeys(&ctx, K1, K2);
791 if (ret != 0) {
792 if (verbose != 0) {
793 mbedtls_printf("failed\n");
794 }
Janos Follathd4443582016-10-12 10:00:42 +0100795
796 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100797 }
798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 if ((ret = memcmp(K1, subkeys, block_size)) != 0 ||
800 (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) {
801 if (verbose != 0) {
802 mbedtls_printf("failed\n");
803 }
Janos Follathd4443582016-10-12 10:00:42 +0100804
805 goto cleanup;
Simon Butcher327398a2016-10-05 14:09:11 +0100806 }
807
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 if (verbose != 0) {
809 mbedtls_printf("passed\n");
810 }
Janos Follathd4443582016-10-12 10:00:42 +0100811
Steven Cooreman830d5af2021-01-08 18:01:46 +0100812next_test:
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 mbedtls_cipher_free(&ctx);
Simon Butcher327398a2016-10-05 14:09:11 +0100814 }
815
Gilles Peskinedf761d52018-03-01 22:18:14 +0100816 ret = 0;
Janos Follathd4443582016-10-12 10:00:42 +0100817 goto exit;
818
819cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 mbedtls_cipher_free(&ctx);
Simon Butcher69283e52016-10-06 12:49:58 +0100821
Janos Follathd4443582016-10-12 10:00:42 +0100822exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100824}
825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826static int cmac_test_wth_cipher(int verbose,
827 const char *testname,
828 const unsigned char *key,
829 int keybits,
830 const unsigned char *messages,
831 const unsigned int message_lengths[4],
832 const unsigned char *expected_result,
833 mbedtls_cipher_type_t cipher_type,
834 int block_size,
835 int num_tests)
Brian Murray00dc5f02016-05-19 14:23:50 -0700836{
Simon Butcher327398a2016-10-05 14:09:11 +0100837 const mbedtls_cipher_info_t *cipher_info;
Brian Murray2fab5c92016-12-15 18:51:13 -0800838 int i, ret = 0;
Gilles Peskine9e930e22023-06-14 17:52:54 +0200839 unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
Brian Murray57863ad2016-05-19 16:38:36 -0700840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
842 if (cipher_info == NULL) {
Simon Butcher327398a2016-10-05 14:09:11 +0100843 /* Failing at this point must be due to a build issue */
844 ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
Brian Murray00dc5f02016-05-19 14:23:50 -0700845 goto exit;
846 }
847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 for (i = 0; i < num_tests; i++) {
849 if (verbose != 0) {
850 mbedtls_printf(" %s CMAC #%d: ", testname, i + 1);
851 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages,
854 message_lengths[i], output)) != 0) {
Steven Cooreman830d5af2021-01-08 18:01:46 +0100855 /* When CMAC is implemented by an alternative implementation, or
856 * the underlying primitive itself is implemented alternatively,
Steven Cooremand3679902021-02-15 13:42:35 +0100857 * AES-192 and/or 3DES may be unavailable. This should not cause
858 * the selftest function to fail. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
860 ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) &&
861 (cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
862 cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) {
863 if (verbose != 0) {
864 mbedtls_printf("skipped\n");
865 }
Steven Cooreman830d5af2021-01-08 18:01:46 +0100866 continue;
867 }
868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 if (verbose != 0) {
870 mbedtls_printf("failed\n");
871 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700872 goto exit;
873 }
Brian Murray9ce2e092016-05-24 22:46:43 -0700874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) {
876 if (verbose != 0) {
877 mbedtls_printf("failed\n");
878 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700879 goto exit;
880 }
881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 if (verbose != 0) {
883 mbedtls_printf("passed\n");
884 }
Brian Murray00dc5f02016-05-19 14:23:50 -0700885 }
Gilles Peskinedf761d52018-03-01 22:18:14 +0100886 ret = 0;
Simon Butcher327398a2016-10-05 14:09:11 +0100887
Simon Butcher69283e52016-10-06 12:49:58 +0100888exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 return ret;
Brian Murray00dc5f02016-05-19 14:23:50 -0700890}
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000891
Simon Butcher69283e52016-10-06 12:49:58 +0100892#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100893static int test_aes128_cmac_prf(int verbose)
Brian Murray6a3c0d22016-05-20 18:25:43 -0700894{
Robert Cragie3d23b1d2015-12-15 07:38:11 +0000895 int i;
Janos Follath24eed8d2019-11-22 13:21:35 +0000896 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher69283e52016-10-06 12:49:58 +0100897 unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
Simon Butcher327398a2016-10-05 14:09:11 +0100898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 for (i = 0; i < NB_PRF_TESTS; i++) {
900 mbedtls_printf(" AES CMAC 128 PRF #%d: ", i);
901 ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output);
902 if (ret != 0 ||
903 memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) {
Simon Butcher327398a2016-10-05 14:09:11 +0100904
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 if (verbose != 0) {
906 mbedtls_printf("failed\n");
907 }
Brian Murrayb0c3c432016-05-18 14:29:51 -0700908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 return ret;
910 } else if (verbose != 0) {
911 mbedtls_printf("passed\n");
Brian Murrayb0c3c432016-05-18 14:29:51 -0700912 }
913 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 return ret;
Brian Murray0f6af732016-05-19 15:59:23 -0700915}
916#endif /* MBEDTLS_AES_C */
917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918int mbedtls_cmac_self_test(int verbose)
Brian Murray0f6af732016-05-19 15:59:23 -0700919{
Janos Follath24eed8d2019-11-22 13:21:35 +0000920 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher327398a2016-10-05 14:09:11 +0100921
Simon Butcher69283e52016-10-06 12:49:58 +0100922#if defined(MBEDTLS_AES_C)
Simon Butcher327398a2016-10-05 14:09:11 +0100923 /* AES-128 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 if ((ret = cmac_test_subkeys(verbose,
925 "AES 128",
926 aes_128_key,
927 128,
928 (const unsigned char *) aes_128_subkeys,
929 MBEDTLS_CIPHER_AES_128_ECB,
930 MBEDTLS_AES_BLOCK_SIZE,
931 NB_CMAC_TESTS_PER_KEY)) != 0) {
932 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100933 }
934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 if ((ret = cmac_test_wth_cipher(verbose,
936 "AES 128",
937 aes_128_key,
938 128,
939 test_message,
940 aes_message_lengths,
941 (const unsigned char *) aes_128_expected_result,
942 MBEDTLS_CIPHER_AES_128_ECB,
943 MBEDTLS_AES_BLOCK_SIZE,
944 NB_CMAC_TESTS_PER_KEY)) != 0) {
945 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100946 }
947
948 /* AES-192 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800949#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 if ((ret = cmac_test_subkeys(verbose,
951 "AES 192",
952 aes_192_key,
953 192,
954 (const unsigned char *) aes_192_subkeys,
955 MBEDTLS_CIPHER_AES_192_ECB,
956 MBEDTLS_AES_BLOCK_SIZE,
957 NB_CMAC_TESTS_PER_KEY)) != 0) {
958 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700959 }
Brian Murray0f6af732016-05-19 15:59:23 -0700960
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 if ((ret = cmac_test_wth_cipher(verbose,
962 "AES 192",
963 aes_192_key,
964 192,
965 test_message,
966 aes_message_lengths,
967 (const unsigned char *) aes_192_expected_result,
968 MBEDTLS_CIPHER_AES_192_ECB,
969 MBEDTLS_AES_BLOCK_SIZE,
970 NB_CMAC_TESTS_PER_KEY)) != 0) {
971 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +0100972 }
Yanray Wangdd56add2023-05-11 13:53:46 +0800973#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Simon Butcher327398a2016-10-05 14:09:11 +0100974
975 /* AES-256 */
Yanray Wangdd56add2023-05-11 13:53:46 +0800976#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 if ((ret = cmac_test_subkeys(verbose,
978 "AES 256",
979 aes_256_key,
980 256,
981 (const unsigned char *) aes_256_subkeys,
982 MBEDTLS_CIPHER_AES_256_ECB,
983 MBEDTLS_AES_BLOCK_SIZE,
984 NB_CMAC_TESTS_PER_KEY)) != 0) {
985 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700986 }
Brian Murray0f6af732016-05-19 15:59:23 -0700987
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 if ((ret = cmac_test_wth_cipher(verbose,
989 "AES 256",
990 aes_256_key,
991 256,
992 test_message,
993 aes_message_lengths,
994 (const unsigned char *) aes_256_expected_result,
995 MBEDTLS_CIPHER_AES_256_ECB,
996 MBEDTLS_AES_BLOCK_SIZE,
997 NB_CMAC_TESTS_PER_KEY)) != 0) {
998 return ret;
Brian Murray9044b022016-05-19 16:36:56 -0700999 }
Yanray Wangdd56add2023-05-11 13:53:46 +08001000#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Brian Murray0f6af732016-05-19 15:59:23 -07001001#endif /* MBEDTLS_AES_C */
1002
Simon Butcher69283e52016-10-06 12:49:58 +01001003#if defined(MBEDTLS_DES_C)
Simon Butcher327398a2016-10-05 14:09:11 +01001004 /* 3DES 2 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 if ((ret = cmac_test_subkeys(verbose,
1006 "3DES 2 key",
1007 des3_2key_key,
1008 192,
1009 (const unsigned char *) des3_2key_subkeys,
1010 MBEDTLS_CIPHER_DES_EDE3_ECB,
1011 MBEDTLS_DES3_BLOCK_SIZE,
1012 NB_CMAC_TESTS_PER_KEY)) != 0) {
1013 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001014 }
1015
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 if ((ret = cmac_test_wth_cipher(verbose,
1017 "3DES 2 key",
1018 des3_2key_key,
1019 192,
1020 test_message,
1021 des3_message_lengths,
1022 (const unsigned char *) des3_2key_expected_result,
1023 MBEDTLS_CIPHER_DES_EDE3_ECB,
1024 MBEDTLS_DES3_BLOCK_SIZE,
1025 NB_CMAC_TESTS_PER_KEY)) != 0) {
1026 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001027 }
Brian Murray0f6af732016-05-19 15:59:23 -07001028
Simon Butcher327398a2016-10-05 14:09:11 +01001029 /* 3DES 3 key */
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 if ((ret = cmac_test_subkeys(verbose,
1031 "3DES 3 key",
1032 des3_3key_key,
1033 192,
1034 (const unsigned char *) des3_3key_subkeys,
1035 MBEDTLS_CIPHER_DES_EDE3_ECB,
1036 MBEDTLS_DES3_BLOCK_SIZE,
1037 NB_CMAC_TESTS_PER_KEY)) != 0) {
1038 return ret;
Simon Butcher327398a2016-10-05 14:09:11 +01001039 }
1040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 if ((ret = cmac_test_wth_cipher(verbose,
1042 "3DES 3 key",
1043 des3_3key_key,
1044 192,
1045 test_message,
1046 des3_message_lengths,
1047 (const unsigned char *) des3_3key_expected_result,
1048 MBEDTLS_CIPHER_DES_EDE3_ECB,
1049 MBEDTLS_DES3_BLOCK_SIZE,
1050 NB_CMAC_TESTS_PER_KEY)) != 0) {
1051 return ret;
Brian Murray9044b022016-05-19 16:36:56 -07001052 }
Brian Murray0f6af732016-05-19 15:59:23 -07001053#endif /* MBEDTLS_DES_C */
1054
Simon Butcher69283e52016-10-06 12:49:58 +01001055#if defined(MBEDTLS_AES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 if ((ret = test_aes128_cmac_prf(verbose)) != 0) {
1057 return ret;
1058 }
Brian Murray0f6af732016-05-19 15:59:23 -07001059#endif /* MBEDTLS_AES_C */
Brian Murrayb0c3c432016-05-18 14:29:51 -07001060
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 if (verbose != 0) {
1062 mbedtls_printf("\n");
1063 }
Brian Murray0f6af732016-05-19 15:59:23 -07001064
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 return 0;
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001066}
1067
Brian Murray0f6af732016-05-19 15:59:23 -07001068#endif /* MBEDTLS_SELF_TEST */
Robert Cragie3d23b1d2015-12-15 07:38:11 +00001069
1070#endif /* MBEDTLS_CMAC_C */